Canonical pretty-printer with no user knobs
Platform spec ADR
Canonical pretty-printer with no user knobs
Spec standingStandard
0 revisions (git unavailable at build; counts may be empty)
No commits recorded for this path.
| Section id | Required | Found |
|---|---|---|
what-this-feature-specifies | yes | yes |
implementation-anchors | yes | yes |
Full tree: run pnpm verify:platform-spec-layout (writes src/generated/platform-spec-layout-report.json).
Context
Section titled “Context”Most modern languages that ship a first-party formatter (gofmt, rustfmt with default config, dotnet format, csharpier) converged on the same answer to the bikeshed question of formatter style: pick one and don’t expose knobs. Languages that allow per-project style files (older prettier configs, clang-format) routinely waste cycles in code review on layout disagreements and create friction for cross-project contributions.
The Beskid formatter starts from a clean slate. The reference implementation in compiler/crates/beskid_analysis/src/format/ is already opinionated (four-space indent, brace on same line, one blank line between members) and ships through a single CLI surface (beskid format / beskid fmt). The question this ADR resolves is whether to expose layout configuration to consumers.
Decision
Section titled “Decision”The Beskid formatter must be a canonical, knob-free pretty-printer. The platform ships exactly one layout style. The formatter:
- Must not expose user-configurable width, indent unit, brace style, member ordering, blank-line policy, or comment placement.
- Must not read project-level style files (no
.beskid-format.toml, no[format]section inProject.proj). - Must be a pure function of the parsed AST and the formatter version compiled into the CLI.
- May change formatter output between releases under the rules in the parent hub’s Compatibility and versioning section (release notes + idempotency preserved + ADR when the layout policy changes substantively).
The CLI must continue to support the operational flags --write, --check, and --output; these affect where the output goes, not what it looks like.
Consequences
Section titled “Consequences”Pros:
- Zero bikeshedding in code review: there is exactly one correct way for any given input.
- Deterministic CI:
beskid format --checkis a reliable PR gate; no per-repo style file ambiguity. - Simpler editor integrations: every plugin can shell out to the canonical CLI without re-implementing layout logic.
- Faster onboarding: new Beskid contributors don’t need to learn project-specific style files.
Cons / accepted trade-offs:
- Teams with strong existing house style (especially “tabs” or “2-space”) cannot satisfy that preference via the formatter; this is by design.
- Future syntactic features that might benefit from style-aware emission (for example, partial-application chains) must take a layout decision once and ship it as part of the formatter, not defer to user preference.
- Some downstream tools that wrap the formatter and want to expose style flags must either drop those flags or layer them outside the canonical formatter.
Verification anchors
Section titled “Verification anchors”beskid_analysis::format::policy— single file that owns layout policy; no other formatter file emits\nor indent runs directly.beskid_cli::commands::format::FormatArgs— the clap surface contains only--write,--check,--output; the absence of style flags is observable frombeskid format --help.- Parent hub Layout policy section — enumerates the fixed indent unit, blank-line rules, and brace style.