Repository navigation
Load plan schemas through the registry and close #6 - #168
Merged
Merged
Conversation
Every version in schema/versions.json is now compiled from its retained snapshots, and plans and edit replies are checked by the version they declare. The loader refuses a registry that disagrees with the snapshots or validators, and treats a version with no validator as unsupported. Pin the released v1 files by SHA-256, keep them LF on checkout, and add the remaining #6 tests: path identity and Git mode mapping, hostile text in every authoring prompt, and output limits at the exact byte. Runtime gaps move to #162-#166. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Resolves the test/review.test.ts import conflict by keeping both imports. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟢 Approval recommended
No blocking issues remain; the changes preserve v1 behavior, add focused regressions, and explicitly document future-version limitations.
No open issues 🎉
What changed in this PR
Completes the remaining library work for #6 by loading plan schemas through the version registry, expanding regression coverage, and documenting separate runtime follow-ups.
Changes:
- Adds registry-selected schema validation and version compatibility guards.
- Pins released schema files and tests path identity, hostile prompts, and output boundaries.
- Maps #6 obligations to implementation evidence or follow-up issues.
| File | Description |
|---|---|
test/schema-versions.test.ts |
Tests registry loading, version dispatch, and released-file digests. |
test/review.test.ts |
Tests checkout identity and Git entry mapping. |
test/planning-provider.test.ts |
Tests bounded failure-output quotes. |
test/planning-author.test.ts |
Expands hostile prompt-text coverage. |
test/agent-supervisor.test.ts |
Tests decoded output boundaries in Docker. |
test/agent-adapter.test.ts |
Tests envelope decoding and parser size limits. |
docs/implementation/planning-audit.md |
Links the historical audit to completed schema loading. |
docs/implementation/plan-library-alignment.md |
Records obligation coverage, limitations, and follow-ups. |
docs/implementation/build-step-1.md |
Links the original implementation record to #6 closure. |
core/planning-author.ts |
Selects provider schemas by the appropriate version. |
core/plan.ts |
Adds registry-driven validation and version guards. |
.gitattributes |
Preserves LF endings for pinned schemas and CLI copies. |
Review effort: Balanced
mchwang
marked this pull request as ready for review
October 19, 2026 07:47
mchwang
added a commit
that referenced
this pull request
Oct 19, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #6.
Summary
#6 was an umbrella issue. PR #4 delivered its library part, and later lanes delivered most of the runner part. This PR closes the remaining library and test gaps and moves the remaining runtime gaps to their own issues.
docs/implementation/plan-library-alignment.mdmaps every obligation in #6 to its code and tests, or to the issue it moved to.Schema loading (
core/plan.ts,core/planning-author.ts)loadPlanSchemascompiles every version inschema/versions.jsonfrom its retained snapshots into one validator. Each plan or edit reply is checked by the version it declares; a value with no registered version is checked by the current schema, so v1 callers see the same/schema_versionerror as before.$iddiffers from its path, that does not requireschema_versionwith a one-valueenum, or whose plan/edit role differs; a validator key or implementation reused, or paired with another semantics document; a missing current version.validate,assertPlanandassertEditReply(docs/plan-format.md: "Treat a missing validator implementation as unsupported"). Before, any v1 registry change other than the exact v1 entry failed module load;test/registry.test.tsstill pins the key tov<version>.importPlanrequires the current version (no migrations exist).applySuggestionrequires the reply's version to equal the plan's. Drafts get the current plan schema; suggestions get the previous plan's edit schema.Released files pinned
test/schema-versions.test.tspins the SHA-256 of every file a registry entry names..gitattributeskeepsschema/versions/**and the CLI copies LF on checkout.New tests for the remaining #6 gaps
test/review.test.ts): the refusal without a known identity, case and NFC keys, the non-ASCII refusal on case-insensitive checkouts, and Git mode mapping (symlink targets verbatim, gitlinks, executable and odd-named files).test/planning-author.test.ts): repository, issue, lesson, feedback, previous-plan and continuation-context text, in initial drafts, revised drafts and suggestions.test/agent-supervisor.test.ts); the 1 MiB parser limit on a decoded Claude answer in draft validation and the envelope fixtures (test/agent-adapter.test.ts); the 300-unit quote of a failed planning run (test/planning-provider.test.ts).Not testable while v1 is the only version
Listed in the implementation note: module-level selection in
assertPlan/assertEditReply, the current-version import check, the reply/plan version check, which schema each provider gets, and the unsupported refusal on shape-only paths. The loader behaviour behind them is tested through an injected two-version loader.Follow-up issues
parseClaudeOutputre-serializesstructured_output, so duplicate keys and lossy numbers are normalized beforeparseV1sees them.Validation
Base
main7fd4dfe52d02de62a516e4d880b4564e83c78513(merged in at94b8611, 2026-10-19), head6b42931284a016e145d27b1d9d7547e5fc1beed2(current head).npm run typecheck)vitest --project parallel)94b8611;6b42931changes one doc lineagent-supervisor, "decoded output at the … limit")f9c2e6b; CIreal-dockerruns it on this headtest,real-docker(both required onmainsince 2026-10-19)6b42931(19m49s, 19m57s;real-dockerran the new Docker test)Since F6c (#177),
test/agent-adapter.test.tsruns in thetestjob; this PR's new cases there only parse envelopes and read repository files, so they still need neither Docker nor a vendor CLI.Earlier validated head
f9c2e6bon base22e76a8: typecheck pass; 2025/2025 without Docker.Load-related failures, separate from product results: at load average ~140 (other agents on the machine), three full runs each had one timing failure in files this PR does not touch:
pre-merge.test.ts"aborts remote work early enough…",review.test.ts"keeps review load available…",planning-worker.test.ts"never deletes Ask's folders…". Each passed 3/3 alone and in later full runs.Each new test was checked against a deliberate break of its behaviour; the breaks are listed in the implementation note.
Review record
requiredcheck; evidence overstated; unsupported version passing shape-only paths documented as untested; error-code consistencyassertPlan/assertEditReplynow refuse unsupported versions; table rows for mounts, termination, schema/output channels, prompt bytestypeofguard inselect(needed for TypeScript narrowing); a mutableMapbehind a shallow freeze (production loader not exported); pinningexamples/(not conformance fixtures; no test reads them)mainmain(async review loads #170, merge jobs F6a/F6b, F6c CI) with no conflicts6b42931; body updated hereSelf-review ran between rounds; every independent round reviewed the full diff against the base.
Review-lesson audit
Findings were classified against existing rules:
No new AGENTS.md rule is needed.
🤖 Generated with Claude Code