Replace the contract-integer compatibility gate with minor-version coupling#468
Merged
Merged
Conversation
…upling Removes CONTRACT_VERSION, ParseRange, and the integer Compare math from internal/contract in favor of a minor-exact major.minor compare over the binary's own display version and the plugin manifest's version field — the existing release stamps already couple both sides, so the floor now moves on every release with zero hand-maintained integer to forget. - internal/contract: new ParseMajorMinor + Compare(host, pluginVersion, binaryVersion); PluginPredatesContract folds into TooOldPlugin; MalformedRange renames to MalformedVersion. - D3: the module root embeds .claude-plugin/plugin.json so an unstamped dev build reports <checkout-version>+dev instead of the bare `dev` sentinel, closing the always-pass carve-out. - D4: two frozen cross-era sentinels preserved for integer-era installs — the manifest tombstone requires-contract ">=3,<4" and the (contract 3) --version token — so an old binary/FO still gets the correct abort remedy. - D5: the FO shared-core Startup gate rewritten to parse the version line and carry a single release-stamped "required binary minor" literal. - D6: gateHost stops printing for too-old-plugin; both front doors now auto-heal it (install, re-gate once, refuse on a second miss) alongside the existing no-plugin-found heal. --skip-contract-check renames to --skip-compat-check throughout. - Fixture manifests and cli tests migrate off static contract-range fixtures to versions derived from the effective binary version, so gating tests stay self-consistent as the repo's own manifest version advances. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ixture Adds the D5 release-pipeline half of minor-version coupling: - internal/release: StampProseVersion/ProseMinor rewrite and read back the FO shared-core's single "required binary minor" literal, erroring on zero or multiple matches (atomic by construction) or an unparseable release version. - cmd/spacedock-release: stamp-version and manifest-tag-gate now dispatch by file extension — a .md argument takes the prose handler/minor-only tag compare, a .json argument keeps the existing full-version handling, in the same multi-file invocation. - EvaluateProseMinorTagGate compares a tag's major.minor against the prose-stamped minor (the prose carries no patch, unlike the JSON gate). - TestStampVersionFlipsCompatibilityFloor is AC-1's divergeable proof: restamping ONLY the release version (no hand-edited integer) moves the SAME fixed binary version from Compatible to TooOldBinary against both the manifest and the prose gate. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… sites The D5 prose gate needs the same release-stamp coverage the plugin manifests already get, or a branch's skills contradict their own manifest (next carries manifests at X.(Y+1).0-pre1 while un-restamped prose still says the prior minor). Adds skills/first-officer/references/first-officer-shared-core.md to the manifest-tag-gate arg list, the main-reconcile stamp-version call + its git diff/commit path lists, and the next edge-bump stamp-version call + its commit path list. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…fests Pins D5's cross-file invariant in the quarantine-sanctioned home for a check that reads an instruction file: the FO shared-core's release-stamped "required binary minor" literal must equal the major.minor each vendored plugin manifest parses to, and the D4 tombstone (requires-contract ">=3,<4") stays frozen on both manifests. skills/integration's manifest tests drop the now-duplicated tombstone assertion, keeping only the manifest-shape checks that don't need an instruction-file read. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…le docs docs/releasing.md's stamp-then-tag step now carries the FO prose file alongside the manifests, notes the go-install proxy build's cosmetic +dev suffix; docs/runtime-live-ci.md's --skip-contract-check example renames to --skip-compat-check; the proof-policy worked example (docs/site/contributing/ proof-policy.md and docs/dev/README.md) rewords "the plugin manifest's contract range bracketing the binary's contract version" to "the plugin manifest's version sharing a major.minor with the binary's version" — the old example named a mechanism this task deletes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…heck Mechanical follow-through of the front-door flag rename in the (build-tag live) runtime-live drive fixtures, so a live-tagged run of these tests still invokes a flag the binary recognizes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…t prose Grep-level sweep for CONTRACT_VERSION / ParseRange / MalformedRange / PluginPredatesContract / --skip-contract-check turned up three leftover prose spots the earlier passes missed: a subtest name, a doc comment citing the renamed MalformedVersion verdict, and pi's --help negative-assertion list. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tested resolveHealableGate's too-old-plugin arm (announce, install, re-gate once, refuse on a second miss) had no direct test — the tooOldPluginManifest fixture helper existed but nothing called it. Adds: gateHost stays silent for too-old-plugin (mirrors the NoPluginFound silence test); both front doors auto-refresh + re-gate + launch on success; --no-install refuses with the gate's own mismatch remedy; a persisted mismatch after refresh refuses without looping (exactly one Install call). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…fixture displayVersion()'s dev-fallback (D3) had implementation but no dedicated test: the unit half (embeddedManifestVersion reads this checkout's own manifest, displayVersion falls back only when unstamped) and the behavior fixture half (an actual `go build ./cmd/spacedock` + `--version` reports <checkout-version>+dev on line 1) were both missing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
clkao
pushed a commit
that referenced
this pull request
Jul 2, 2026
gcko
added a commit
that referenced
this pull request
Jul 8, 2026
Bring PR 435 up to date with main (65 commits), reconciling the bridge-seam work with two paradigm shifts main introduced: - Contract gate: main replaced the integer contract with minor-version coupling (#468). plugin.json now carries the frozen D4 tombstone requires-contract ">=3,<4" alongside the branch's "hooks" registration. - FO Startup collapse: main collapsed the FO Startup recipe to <=4 steps ("boot identifies, engage converges") and caps first-officer-shared-core.md at 26755 bytes. Rewove PR 435's boot additions onto that spine: * launch-branch pin -> a sub-bullet of the boot-identify step * before-greet Bridge liveness heartbeat -> step 2b (non-counting), an explicit carve-out from main's "boot writes nothing" rule * gate drain-before-present kept in «gate.assemble-verdict» To fit the byte cap while preserving the opt-in fleet feature, relocated the Fleet Mode section to a deferred references/fo-fleet.md (idiomatic to main's defer-non-common-prose philosophy), rewritten against the new boot-identify + engage paradigm, and repointed fo-dispatch-core + SKILL.md. .gitignore: kept the _bridge/ block, dropped main's duplicate /spacedock. All contractlint + bridge/fleet integration tests pass; full suite green except the pre-existing agentsview TestSurveyCodexPresenceThroughSync (fails identically on clean main — local binary quirk). Co-Authored-By: Claude Opus 4.8 (1M context) <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.
The skill↔binary compatibility floor now moves itself each release — the hand-maintained contract integer that silently stayed at 1 across three minors is gone.
What changed
too-old-pluginat both front doors, with a re-gate-once guard0.24.0-pre1+dev)Evidence
go test ./...16/16 packages green; AC-1 stamp-only floor-flip fixture passedReview guidance
Release-critical surface: the release.yml stamp-site wiring and the two frozen sentinels.
kr