Skip to content

DECISION NEEDED: unify stdin label conventions across lint/fmt/build — three conventions in four contexts affect the --format json wire format #211

Description

@dean0x

Background

As of PR #196, stdin input carries three different label strings depending on which subcommand and output format is in use:

Subcommand Context Label emitted Where
mds build / mds check diagnostics, source maps <source> build.rs:900, resolver.rs:199
mds lint - diagnostics (human) input.mds lint.rs:652,661
mds lint - --format json JSON "file" key input.mds lint.rs:652
mds fmt - diagnostics, source maps <stdin> fmt.rs:148

Additionally, build.rs rewrites input.mds<stdin> when constructing source maps, so the library-level constant (STRING_SOURCE_MAP_LABEL = "input.mds") and the CLI-emitted label (<stdin>) diverge on the same codepath.

Ledger IDs: #37 (primary), #12 (formatter.rs source sentinel dual meaning), #13 (sourcemap.rs:104 hardcodes source label)
Files: mds-cli/src/lint.rs:652,661; mds-cli/src/fmt.rs:148; mds-cli/src/build.rs:900; mds-core/src/resolver.rs:199; mds-core/src/formatter.rs:119; mds-core/src/sourcemap.rs:104
Originating reviewer: Consistency
Triage verdict: FIX_SEPARATE — "no surface produces a wrong result today, but the lack of a written rule is the root cause"

The tension

Three legitimate design arguments pull in different directions:

  1. Library parity (input.mds): The library-level string-source path genuinely wants a label that looks like a filename — tools that accept MDS as a string and process it programmatically can identify the "virtual file" as input.mds. This is why STRING_SOURCE_MAP_LABEL was introduced in PR fix: v0.4.0 remediation — dogfooding blockers, bug batch, UX polish, docs sweep #196.

  2. CLI stdin convention (<stdin>): UNIX tools conventionally use <stdin> (angle-bracket form) for standard input in diagnostic output and source maps. mds fmt already uses this; mds build/mds check use <source> (similar convention). A user piping cat prompt.mds | mds lint - expects <stdin>, not input.mds.

  3. Wire format immutability ("file" key in mds lint --format json -): The JSON output contract commits to whatever label is emitted in the "file" field. Changing it after v0.4.0 is a machine-readable breaking change. Currently it would emit input.mds — a filename that does not exist on disk.

What must be decided before v0.5.0

Write a rule: what label does stdin carry, per context (diagnostics, source maps, JSON wire format), per subcommand (lint, fmt, build, check)?

Possible resolution:

  • Option A (input.mds everywhere, align all CLI surfaces to the library): consistent, but <source>/<stdin> users break.
  • Option B (<stdin> everywhere, align library label to CLI convention): consistent, but input.mds library consumers break.
  • Option C (library uses input.mds; CLI remaps to <stdin> at the render boundary): maximally compatible, but adds a rewrite in every CLI emit path. build.rs already does exactly this — extend to lint and fmt.
  • Option D (subcommand-specific): lint uses <stdin> for human output and input.mds for JSON (machine-readable consumers can tolerate a fixed virtual name); fmt/build/check use <stdin>. Documents the split explicitly.

Why deferred from PR #196

Three of the four conventions predate PR #196. The PR introduced input.mds on the lint path specifically because the library string-source path needs a stable virtual name. Writing a rule under release pressure risks churning the wire format with no time to validate cross-surface consequences.

The triage explicitly notes: changing the label in v0.5.0 is a breaking change to mds lint --format json - wire format. The cheapest time to settle this is now, before v0.5.0 ships. If the decision is Option C or D, the [Unreleased] CHANGELOG should note the current input.mds label on lint - as provisional.

Related

  • mds-core/src/formatter.rs:119: SOURCE_SENTINEL = "" serves as both "no source provided" and "stdin" — same dual-meaning issue, same resolution.
  • mds-core/src/sourcemap.rs:104: Hardcodes "input.mds" independently of STRING_SOURCE_MAP_LABEL — should reference the constant once the rule is written.
  • Expose basePath on CompileOptions to match LintOptions #180: basePath alignment — both issues affect how the library vs CLI surfaces present virtual/stdin sources.

Deferred from: PR #196
Must resolve before: v0.5.0 (changing the JSON wire format after that is a breaking change requiring a major bump)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    architectureArchitectural refactoringcliCLI commands and optionslanguageMDS language features and syntaxtech-debtTechnical debt

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions