Skip to content

Tracker Phase 1 — MDS plumbing, provably byte-identical #323

Description

@dean0x

Initial Request

src/assets/agents/git.md is a 938-line, 59,376-character hand-maintained file [verified: wc -c -l src/assets/agents/git.md938 59376] that Phase 2 must split into a contract layer plus generated per-provider references. Splitting it requires the MDS compiler to own it, but the build script today:

  • only compiles src/assets/commands/*.mds;
  • has no notion of a generator host — an agent file whose real frontmatter must survive as body text so loadShippedDefaults() can still read model:;
  • validates its output directory with a raw string equality (scripts/build-mds.ts:166-173 [verified]: const expectedOutputDir = 'dist/commands'; if (host.outputDir !== expectedOutputDir) { … process.exit(1) });
  • does not validate the output filename at all (scripts/build-mds.ts:178 [verified]: const dest = path.join(outAbs, \${host.basename}.md`)`);
  • is unknown to the installer (src/targets/claude-code/installer.ts:498-524 [verified] reads agentsDir() only) and to the model pipeline (src/core/agent-models.ts:469-504 [verified] loadShippedDefaults reads agentsDir() only).

Phase 1 converts git.mdgit.mds, teaches build-mds.ts the generator-host convention through a typed, Result-returning src/core/mds-variants.ts, makes the installer and the model pipeline read the compiled agent with a loud failure rather than a silent skip, and converts every remaining count literal into a name manifest so three later phases stop colliding on the same integer.

AC-1.1 is the whole review: dist/agents/git.md byte-identical to the Phase-0 golden.

Honest user-visible-change statement

"Zero user-visible change. dist/agents/git.md is byte-identical to the file it replaces, the 13 compiled command outputs are byte-unchanged, and the frozen github-status-lines.txt is untouched. The only observable difference is that npm run build:cli alone no longer produces installable agents — npm run build:mds is now required."

This sentence is the CHANGELOG entry and the PR's first paragraph. It is not marketing: it is the claim the golden test mechanically proves.

Execution: SEQUENTIAL_CODE_AGENTS · context-risk: CRITICAL · Design artifact: .devflow/docs/design/tracker-phase-1.2026-09-05_1155.md (authoritative; local, gitignored — a 60k-truncated copy is posted as a collapsed comment).

Product Requirements

Depends on

Phase 0 (#322) merged to main. Tracking issue: #321.

Acceptance criteria

  • AC-1.1dist/agents/git.md byte-identical to the golden captured at the Phase-0 merge commit — this test is the review
  • AC-1.2 — no @if with a single reachable arm, no variant list, no (module, op) iteration [DR-16 amendment] grep over the union src/assets/agents/git.mds ∪ src/core/mds-variants.ts ∪ scripts/build-mds.tsnot a git.mds-only grep, which cannot see src/core/ and so cannot mechanically check clause (iii)
  • AC-1.3 (amended) — tarball install produces a working git agent; the src-fallback branch is exercised on an unconverted agent, and the loud-failure branch on git — because Phase 1's own negative guard deletes src/assets/agents/git.md, making "dist absent ⇒ falls back to src" unreachable for the converted agent — the AC text as originally written is self-contradictory for git; the reworded text above is the binding one
  • AC-1.4loadShippedDefaults() has an entry for every getAllAgentNames(), and ['git'] === 'haiku'
  • AC-1.5 — the 13 command outputs byte-unchanged
  • AC-1.6 — registry completeness holds with git resolved from dist/agents
  • AC-1.7 — build-mds exits 1 with the exact "typo?" message for dist/wrong-dir and rejects name-template: ../x, name-template: a/b, output-dir: dist/../.., output-dir: dist/commands/
  • AC-1.8 — count literals are name manifests; the build's printed host/partial numbers agree with the manifest (a spawnSync assertion — no test asserts them today) NEW test required — the highest-risk P1 gap. See §12 row P1-a and [C16]. Tracked as open item O-8 in the master artifact.
  • AC-1.9test:integration runs in CI and covers the dist-preferred agent path
  • AC-1.10@mdscript/mds devDep pin 0.2.0 + lock mirror + absent-from-dependencies; a repo-wide grep for src/assets/agents/git.md returns only intended src-fallback sites
  • AC-1.11 — the frozen status-line fixture unchanged
  • AC-1.12 (new) — the tarball's src/assets/mds/*.mds entry count is pinned deliberately (0 or N) — the value is Gate-2 decision D-A: (a) ship it, pin the count
  • Prefix-shippability — After phase N: (i) npm run build && npm test && npm run test:integration && npm pack --dry-run are green; (ii) a fresh install from the tarball drives /plan → /implement → /code-review → /resolve → /release on a GitHub project with no new prompt and no new file in git status; (iii) every artifact in the tree has at least one reachable consumer in this phase's end-state — no file, define, list element, frontmatter key or conditional arm exists solely for a later phase (ADR-003); (iv) the frozen github-status-lines.txt fixture is byte-identical to its Phase-0 capture.

Subtasks

# Domain Owned files (with anchors) Depends on Gate before next Handoff contents
S1 build script / TS core / installer scripts/build-mds.ts (:101-104 readOutputDir [verified], :114-124 stripOutputDirKey [verified], :159-173 escape guard + dest pin [verified], IGNORE_DIRS :40-48 [verified], DEVFLOW_MDS_ROOT escape hatch :34 [verified]) · new src/core/mds-variants.ts · src/core/assets.ts (compiledAgentsDir() after commandsDir() :41-43 [verified]; optional mdsDir()) · src/targets/claude-code/installer.ts:498-524 [verified] · src/core/agent-models.ts:469-504 [verified] · new tests/mds-variants.test.ts · new tests/build-mds-generator-hosts.test.ts Phase 0 merged to main G1.1 the exact generator-frontmatter block shape stripGeneratorFrontmatter accepts (reproduced verbatim in §7 P1-S4); the 13 dist/commands/*.md SHA-256s recorded before and after S1, confirming they are unchanged; the new allowlist's resolved-path semantics
S2 prompt assets src/assets/agents/git.mdsrc/assets/agents/git.mds (git mv + generator frontmatter + 142 brace escapes + 9 indented fences) S1 (G1.1 green) G1.2 — the hard gate cmp -s dist/agents/git.md tests/fixtures/golden/git-agent.md exit 0, recorded verbatim; the enumerated list of the 9 indented fences with their git.mds line numbers; grep -c '\\{' dist/agents/git.md == 0; the statement that src/assets/agents/git.md no longer exists, which is why AC-1.3's src-fallback arm must be tested on an unconverted agent
S3 tests + packaging + docs tests/build-mds.test.ts (:67-73, :85-89, :474-482 → name manifests [all verified]) · tests/packaging.test.ts (:42-95 Guard 3 [verified], :213-250 Guard 5 reason string, :324-337 [verified]) · tests/core-paths-assets.test.ts:64-79 · tests/build.test.ts · tests/git-agent.test.ts / registry-integrity.test.ts / skill-references.test.ts / agent-name-guards.test.ts / agent-frontmatter.test.ts (repoint audit — should be no-ops if Phase 0's resolver did its job) · new tests/guards/dist-agents.test.ts · package.json:9-17 [verified] · CLAUDE.md (:89, :91, :116, :257, :276) · five .devflow/features/*/KNOWLEDGE.md [drift: source §P1.3 says six; §0.7 and P1-S15 enumerate five] · docs/reference/platform-assumptions.md · CHANGELOG.md S2 (G1.2 green) G1.3 — (terminal)

Gates

Gate Must be green before Assertion
G1.1 S2 starts npm run build exits 0; npm test green; the 13 dist/commands/*.md SHA-256s identical to the Phase-0 merge commit (AC-1.5); the five negative build cases (AC-1.7) exit 1 with the exact … is not the expected '…' — typo? message (AC-1.7).
G1.2 S3 starts — the hard gate npm run build:mds exits 0 and cmp -s dist/agents/git.md tests/fixtures/golden/git-agent.md and grep -c '\\{' dist/agents/git.md == 0. No test may be repointed before this holds.
G1.3 PR opens Full prefix-shippability (§2 standing AC); loadShippedDefaults() ⊇ getAllAgentNames() and ['git'] === 'haiku' (AC-1.4); registry completeness with git resolved from dist/agents (AC-1.6); the build's printed host/partial counts agree with the manifest via spawnSync (AC-1.8); github-status-lines.txt unchanged (AC-1.11).

/implement spawn notes

Subtask Spawn parameters
S1 CREATE_PR: false · HANDOFF_REQUIRED: true
S2 CREATE_PR: false · HANDOFF_REQUIRED: true
S3 CREATE_PR: true · HANDOFF_REQUIRED: false (terminal; S3 opens the PR per implement.mds:409)

Commits are pathspec-scoped (git commit -- <owned paths>) so per-subtask provenance survives the squash-merge (PF-020's validated cheap mitigation). No PR split for Phase 1 (Gate-2 decision D-G) — the phase is one issue, one branch, one PR.

Execution strategy

SEQUENTIAL_CODE_AGENTS — 3 subtasks (S1 → S2 → S3). Context risk: CRITICAL.

Rationale:

  • src/assets/agents/git.mds cannot compile until stripGeneratorFrontmatter and the resolved-path dest allowlist exist in scripts/build-mds.ts. The conversion's only verification is the build, so build changes must land first.
  • The conversion (S2) is a 59,376-character transformation whose acceptance test is byte-equality against a frozen golden. This is the single highest-risk edit in the whole feature and must be the only thing in its agent's context.
  • Test repointing (S3) must not begin until byte-equality holds, or a repointed test's red state is ambiguous between "the repoint is wrong" and "the conversion is wrong."

Why PARALLEL_CODE_AGENTS is rejected — the rejection holds and is phase-independent [DR-23]:

  1. npm run build is rm -rf dist && npm run build:cli && npm run build:mds ([verified package.json:20]);
  2. /implement has no worktree isolation — a grep for worktree in implement.mds returns zero hits;
  3. read closures overlap across every partition (PF-020's 2026-08-30 closure rule).

Because every Code agent's verification step deletes the shared dist/ while a sibling is mid-suite, and Phase 0 deliberately makes every dist-scanning guard fail loud on a missing directory (AC-0.16 / §0.1-R3), any concurrent pair manufactures nondeterministic red. That disqualifier is independent of write-set disjointness. [DR-23] additionally records that Phase 1's S-level dependencies are hard, not merely scheduled: S2 cannot compile without S1's build changes, and S3's red states are ambiguous without S2's byte-equality — this is not one of the two weak dependencies DR-23 flags elsewhere in the plan. If per-agent worktrees ever land, Phase 1 is still not a parallelism candidate. This is a tooling limitation, not a plan limitation.

PR title

refactor(build): compile the Git agent from an MDS generator host

Implementation Plan

Design artifact (authoritative): .devflow/docs/design/tracker-phase-1.2026-09-05_1155.md — local and gitignored. A copy truncated at the 60k comment cap is posted as a collapsed comment: #323 (comment). Run with /implement .devflow/docs/design/tracker-phase-1.2026-09-05_1155.md. Tracking issue: #321.

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

    featureFeature request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions