Rule Version History (lifted)¶
Verbatim version-history chains lifted out of .gzkit/rules/** by the
instructions-files-diet chore on 2026-08-02, under the operator ruling
"rule on the surface-weight ceiling: do the diet pass".
Why these moved. .gzkit/rules/skill-surface-sync.md § Non-negotiable
rules specifies the marker shape as "a visible > **Rule version:**X.Y.Z``
block quote with a one-sentence rationale." Accumulated multi-version chains
had grown to 6–29 lines each on the per-turn surface, exceeding the contract
they were written against. Each rule now carries its current-version rationale
plus a pointer here; the chains below are the lifted text, unedited.
Nothing binding moved. Only narrative provenance is here. Every binding bullet, invariant, and table stayed in its rule — per the chore's own anti-pattern guard, "lighter ceremony is not a tradeoff axis."
governance-core.md¶
Retired 2026-09-17 at version 0.15.0 — folded into root AGENTS.md¶
Operator ruling (verbatim): "i am not sure why we have this as an additional file? why not just place this in AGENTS.md?" … "it all seems pretty ad hoc, do option A" (GHI #921, instructions-files-diet). The rule was global (paths: "**/*"): Claude loaded it at launch every session, and Codex never received it because global rules are excluded from the nested AGENTS.md fan-out. Operator Doctrine names root AGENTS.md the sole rendered AgentContract for every harness, so a universal rule belongs there. Landed as corpus entries under attestation (gz content remember → compose → commit, attestation text the ruling above): illustrative values, verb resolution and adr-status regeneration in § Governance doctrine surfaces; externally-authored output in § Behavior Rules; attested-REQ retirement in § OBPI Acceptance Protocol; withdraw/repudiate in § Gate Covenant. Duplicates of AGENTS.md left with the rule (read AGENTS.md first; uv run; Gate 5; sacrosanct attestation; manual ledger edits; defects tracked). The six-step OBPI workflow order stays in governance_runbook.md. Rationale remains at Governance Core — Rationale. The rule's own stray corpus row (.gzkit/corpus/.gzkit/rules/governance-core.md.jsonl) was retired the same day. Final version note, verbatim:
Rule version:
0.15.0— § Operator-doc verb resolution scope widened to the surfaces an agent executes from: chore docs (.gzkit/chores/**/*.md,proofs/excluded),.gzkit/rules/**/*.mdand rootAGENTS.md(GHI #1006). Version history lifted to Rule Version History; worked examples and measured instances lifted to Governance Core — Rationale. This rule is scoped**/*and loads on every edit, so narrative is the most expensive thing it can carry.
Lifted at version 0.8.0 (rule now at 0.8.1).
Rule version:
0.8.0— adds the instruction-source boundary to § Non-negotiable rules. gzkit's canon carried NO prompt-injection or untrusted-content doctrine at any surface: the only such rule in force came from the Claude Code harness, so adopters on the.agents//.github/mirrors ran governed agents with no boundary at all. Doctrine atdocs/governance/untrusted-content.md(Claude Opus 5 System Card § 5.2). Prior0.7.0— extended § Operator-doc verb resolution to binddocs/user/manpages/<verb>.mdfilename references, not onlygz <verb>strings (GHI #532). 174 references to a non-existentgz-<verb>.mdmanpage convention had accumulated across 60 briefs/skills/docs with no gate catching them;audit_manpage_alignment(under the same--cli-alignmentflag) now fail-closes on thegz-prefix, terminal briefs exempt. Prior0.6.0— repointed § Required workflow order step 5 offgz gates, which announces its own deprecation at runtime, ontogz closeout --dry-run(GHI #705). The rule prescribed a retired verb on the only rule scopedpaths: "**/*"— loaded on every edit in every session — so an agent following it literally was routed onto a deprecated surface with no signal that the correct move was a different verb. The inverse oftool-skill-runbook-alignment.mdInvariant 2 is now mechanical:gz validate --deprecated-verb-prescriptionfails closed on any governed surface that prescribes a deprecated verb. (Entries0.5.0–0.3.0condensed 2026-08-02 to seat0.8.0under the surface-weight ceiling; full text in git history.) Prior0.5.0— reconciled two bullets that contradicted AGENTS.md (Pass A rows 14/16): the defect-tracking bullet named the exactgh issue createand raw-jsonl invocations Always #13/#11 forbid, and the Gate-5 bullet carried a lane conditional collapsed at ADR-0.0.36. Prior0.4.0— withdraw-vs-repudiate disambiguation (ADR-0.0.71): repudiate reverses a completion, withdraw is permanent retirement. Prior0.3.0— enshrined the canon-owner human-attestation directive.
Lifted 2026-08-29 at version 0.13.0 (rule now at 0.14.0)¶
Second diet pass under GHI #921, operator ruling "we are compressing everything and anything that the agent can consume". The 0.9.0–0.13.0 chain below is the lifted text, unedited. Bullet narrative from the same pass lives in Governance Core — Rationale.
Prior 0.12.0 — the MD-values bullet's remaining carve-out is measured rather than assumed (operator ruling 2026-08-16). It had named the advisory scorecard's classification cells as an open defect awaiting the same treatment the campaign pointer got; measurement said otherwise, and the bullet now records the result instead of the assumption. That instance has ONE parser rather than two, written defensively against failures it already survived (rows 22/27/52 carry \| inside code spans, which a naive split once dropped — "a three-row undercount that looks exactly like a correct answer"), its Summary roll-up already fenced against its own rows, and zero silent dropouts across 118 rows. Migrating it would separate each verdict from its justifying rationale and leave JSON + prose + a fence where one parser suffices. The residual — a malformed Score cell leaving a row invisible to every count, which _summary_drift_errors cannot catch because correcting the Summary moves both numbers together — is closed by _silent_dropout_errors in the same validator as its siblings. The operative lesson is the asymmetry: unavoidable is a claim requiring evidence, and the two instances measured differently. Prior 0.11.0 — the campaign-Status: carve-out is discharged, not merely restated (operator ruling 2026-08-16, "move ACTIVE out of prose into JSON"). The bullet had named campaign Status: as a place where prose "is unavoidably the state" — and unavoidable was wrong: data/active_campaign.json now declares which plan governs, scripts/session_orientation.py and gzkit.knowledge.generate both read it, and the ^Status:\s*\*\*ACTIVE regex is gone from production. It had been maintained in two copies on opposite sides of the wheel boundary, over text one character from ambiguity — every superseded edition reads **SUPERSEDED — was ACTIVE** and missed only because ACTIVE is not adjacent to the asterisks, so **ACTIVE (superseded)** would have silently flipped the governing plan of the whole repository. The banner survives as a restatement, held in agreement by tests/governance/test_active_campaign_registry.py, which also fails closed on an edition the registry does not declare — the property neither prior shape had, since a hardcoded pointer and a prose scan both fail silently. Scorecard classification cells remain the open instance. Prior 0.10.0 — adds § Non-negotiable rules bullet: a value in a Markdown doc is illustrative, never authoritative (operator ruling 2026-08-16, verbatim: "we should never allow a hard-coded value in an md doc to be anything other than illustrated lest some rg/grep finds it and gets confused"). Grounded in a measured instance, not a principle: .gzkit/rules/pythonic.md carries Modules <=600 while the execution authority is .gzkit/rules/complexity-thresholds.json, read by chores/module-sloc-cap-radon/check_module_size.py:56 — whose own docstring calls the 600 "the drift". A 2026-08-16 census against the prose number counted 51 oversized modules that no gate rejects, and an agent proposed a census box against an authority the codebase does not enforce. The failure is rg-shaped: a number in prose is indistinguishable from a number that binds, so the next reader adopts whichever they find first. Prior 0.9.0 — scopes the instruction-source boundary to externally-authored content and carves out operator-authored repo canon. As written in 0.8.0 the bullet was unscoped, and it sat in a Non-negotiable section of the only rule scoped paths: "**/*" — loaded on every edit in every session — where it contradicted two operator-verbatim canon bullets: AGENTS.md:342 ("GHIs are AUTHORIZED for direct repair, always … the GHI is the work order and the receipt") and AGENTS.md:338 (the campaign plan "rules every session"). A GHI body is tool output; a campaign plan is file content. One rule mandated autonomous execution, the other suspension, for the two most common session decisions in the repo, and neither side had a mechanical arm (docs/governance/untrusted-content.md § Relationship to the hook layer: "A mechanical incoming-data probe … remains unbuilt"). Surfaced as blocking rows R18/R19 of the 2026-08-09 control-surface-rule-conflicts Pass A walk, whose own session was the worked example — it acted on GHI bodies, a CHORE.md workflow, and a checker's remediation instruction without an operator ruling on any. The threat model is external content, not canon the operator authors; scoping preserves every bit of the defense while restoring the direct-repair path. Prior 0.8.1 — adds the instruction-source boundary to § Non-negotiable rules (0.8.0); prior version history lifted to Rule Version History.
Lifted 2026-09-13 at version 0.14.0 (rule now at 0.15.0)¶
Rule version:
0.14.0— diet pass under GHI #921 (operator ruling 2026-08-29, "we are compressing everything and anything that the agent can consume"). Version history lifted to Rule Version History; worked examples and measured instances lifted to Governance Core — Rationale. Binding rules unchanged; this rule is scoped**/*and loads on every edit, so narrative is the most expensive thing it can carry.
0.15.0 widens § Operator-doc verb resolution to chore docs, rules and root AGENTS.md (GHI #1006). gz-chore-runner Step 5 has an agent follow a CHORE.md, and rules and the root contract load into every session, yet none was scanned: measured 2026-09-13, 8 unresolvable gz chains stood in 4 chores (complexity-reduction-xenon still named gz complexity-advise after the verb landed as gz complexity advise); rules and AGENTS.md carried 0. audit_manpage_alignment now reads the same enumeration rather than a copy of it.
cli.md¶
Lifted 2026-09-17 at version 0.8.1 (rule now at 0.9.0)¶
Diet pass under GHI #921 (operator: "A" on the full before/after, 11,949 B → 6,893 B). Binding rules unchanged. Lifted verbatim as dated records — the 0.8.1 note, the 2026-08-22 shape measurements, the lane-vs-route quotations and the 8d9e09a4 worked example:
Rule version:
0.8.1— the manpage-filename pointer now namesAGENTS.md§ Governance doctrine surfaces, where the verb-resolution rule lives sincegovernance-core.mdwas folded into the root contract (2026-09-17, GHI #921).0.8.0— § Flag Conventions realigned to the canonical specification's § Output Modes and § Verbosity Levels:--verboseenables INFO-level logging (this row said "Debug output", the drift the adapter's level map had copied) and--debugis listed, and errors reach stderr in every mode;0.7.0and prior are lifted to Rule Version History.
- The count of depth-1 leaf commands may not increase — the specification prescribes
<group> <command>; 35 of 136 leaves are bare root verbs, so the existing set is waived shrink-only and new commands take a noun. - No subcommand may share its verb with a bare root command — 13 shadow today (
gz adr statusvsgz status,gz cli auditvsgz audit). Repetition itself is correct:listrecurs 7× under different nouns and collides with nothing. - A noun may not be registered in both singular and plural form — exactly one pair today (
gz flaggroup vsgz flagsleaf). - New root commands may not hyphenate a noun-verb pair — 6 exist (
register-adrs,check-config-paths,permitted-entry,migrate-semver,test-shape,git-sync); subcommands are the mechanism the hyphen is standing in for. - Every leaf command declares --json or carries a waiver with rationale — 63 of 136 lack it, and nine groups disagree with themselves:
gz adr emit-receipthas none whilegz obpi auditdoes, though both emit structured governance evidence. - A parser node is a leaf or a group, never both — exactly one node violates this (
gz mxcarries a handler and subcommands), so the state is either a deliberate default-subcommand or an accident, and nothing records which. - Building the gz parser tree may not import handler-only dependencies — every
gz --helppays what the parser tree imports (GHI #180). Guarded bytests/cli/test_help_path_imports.py. - A new subcommand satisfies all seven coupled obligations in the authoring patch — the set is enumerated at § Adding CLI Features — New Subcommand, and the validators named there win any disagreement with the list. Measured 2026-08-22: three surfaces described the set as 3, 4 and 1 obligations against 7 that fail closed (GHI #854).
- User-facing output passes through the formatter, never console.print directly — 1,230 sites bypass it against one
OutputFormatter. This is the precondition for the--jsonrule above, not a sibling of it: a--jsonflag on a command whose body prints human text is green while blind.
Two further specification rules are scored Judgment and are deliberately absent from this list — mandatory-target-as-positional (no surface models "target"; the available proxy grades by shape) and one-verb noun groups (no surface models intent-to-extend). They live in the canonical specification; see the scorecard for why neither is mechanizable.
Lane is not route. A GHI-tracked defect repair routes DIRECT even when it adds a CLI surface — AGENTS.md § Operator Doctrine, verbatim: "GHIs are AUTHORIZED for direct repair, always… A GHI-tracked defect repair routes to direct fix (fix(<scope>): <summary> (GHI #N), close citing the commit SHA) regardless of the 'OBPI ceremony required when ANY hold' criteria below; those criteria gate planned ADR work, not defect repair. Never spin up an ADR or OBPI merely to discharge a GHI." Reaffirmed 2026-09-06: "'may add a CLI surface' alone does not require new ADR/OBPI ceremony: GHI-tracked corrections are authorized for direct repair." The IRON LAW makes this more than a preference — only the operator initiates OBPI work, so an agent that read the un-carved sentence literally could not proceed by either route. Heavy lane still binds the gates the repair must clear (§ New Subcommand's seven obligations, gz cli audit exit 0); it never converts the repair into OBPI ceremony.
gz cli auditdoes not adjudicate this. It audits a flag's documentation — that the flag is named in its manpage (GHI #350) and that the usage line's required/value-taking claims match the parser (GHI #693) — and exits 0 with full cross-coverage regardless of a new flag's lane. Its green is evidence about docs, never about lane assignment. Its green is not evidence of correct lane assignment.
What this list cannot cover. These seven are enumerable because they are fixed per verb. They are not the coupled surface of a change that also alters a format — a consumer reading a document body, a test asserting against prose, a fixture keyed on a schema shape. 8d9e09a4 is the worked example: relocating the settled-ruling corpus updated every per-verb surface in one commit and still left test_settled_ruling_integrity reading a section that had become a pointer, caught by the suite at push time. Front-loading this checklist collapses the reactive loop for verb registration; it does not make a format change safe, and treating it as though it does would build a false floor.
Lifted 2026-09-17 at version 0.8.0 (rule now at 0.8.1)¶
Patch: the pointer to governance-core.md § Operator-doc verb resolution now names AGENTS.md § Governance doctrine surfaces, the clause's home since the rule was folded into the root contract (GHI #921). No other change.
Lifted at version 0.7.0 (rule now at 0.8.0).
Rule version:
0.7.0— GHI #1001 (operator ruling 2026-09-13, "Keep 2; fix the labels"): code 2 in § Exit Codes is relabelled Usage or System/IO, because every parse error exits 2 by attested REQ-0.0.4-02-03 while this table and the shared epilog called 2 System/IO alone;0.6.0and prior are lifted to Rule Version History.
Lifted at version 0.6.0 (rule now at 0.7.0).
Rule version:
0.6.0— operator ruling 2026-09-06 carves the GHI direct-repair exception into § Adding CLI Features, which had read as though every contract-bearing CLI change requires OBPI ceremony and so contradictedAGENTS.md§ Operator Doctrine;0.5.1and the superseded0.5.0–0.3.1chain are lifted to Rule Version History. Scopedsrc/gzkit/commands/**, this rule loads on every CLI-command edit, so narrative is the most expensive thing it can carry.Prior
0.5.1: diet pass under GHI #921 (operator ruling 2026-08-30, "do 3, 4, and 5"): the superseded0.5.0–0.3.1version chain is lifted to Rule Version History, restoring the one-sentence shapeskill-surface-sync.md§ Non-negotiable rules #2 requires. Binding rules unchanged; scopedsrc/gzkit/commands/**, this rule loads on every CLI-command edit, so narrative is the most expensive thing it can carry.
Lifted at version 0.5.0 (rule now at 0.5.1).
Rule version:
0.5.0— § Adding CLI Features — New Subcommand now enumerates all seven mechanically-checked obligations, read out of the validators rather than transcribed from memory. The prior list named four surfaces and omitted three that fail closed: theconfig/doc-coverage.jsonmanifest entry, the handler docstring, and the wielding skill. Measured 2026-08-22 on thegz handoff rulingsregistration — the first full suite run returned 21 failures, every one a deterministic consequence of adding ONE verb, against a 136s unit tier invoked three times. None was a surprise to the gates; all three were a surprise to the checklist. The gap is not enforcement — every obligation here already fails closed — it is that the pre-flight list disagreed with the post-flight check, so the cheapest surfaces in the repo were discovered by its slowest gate. Scoped deliberately to per-verb obligations: § New Subcommand's closing paragraph names what a fixed list structurally cannot catch, so this is not read as a completeness claim. Prior0.4.0— GHI #810: links the canonical specification, and adds § Command shape so this file can be scored for real. This rule declared clig.dev as its baseline while the 1,037-line specification elaborating it —docs/design/cli-standards-v3.md, named canonical by ADR-0.0.4 (Validated, foundation, heavy) — was cited by that ADR and by no rule or governance surface, so the per-turn contract never reached it. Meanwhile this file sat indata/advisory_scorecard_grandfather.jsonpinned at0.3.1— pre-ledger debt, never scored. The two facts compound: measured 2026-08-16, every CLI rule with a mechanical arm holds at or near 100% (exit codes, epilogs, manpage coverage, skill alignment) and every rule that is prose only sits at or near 0% (--json73/136, formatter chokepoint 1,230 bypasses, structlog 1get_logger,--log-fileabsent). This edit drops the pin by construction, which perdocs/governance/advisory-rules-audit.mdcompels the scoring pass. Prior0.3.1— reconciled § Core Principles — Consistency to the mechanism it names, so the audit checks usage-line agreement (0.3.0, GHI #693); prior version history lifted to Rule Version History.Rule version:
0.3.0— reconciled § Core Principles — Consistency to the mechanism it names (GHI #693, operator ruling 2026-07-17: this is a correction, not an enhancement — the rule's promise WAS the audit's declared intent). "The audit is the mechanical check" read as a promise that the documented flag contract is verified; the audit mechanized presence only, so a manpage could contradict its parser and ship green — observed live ongz handoff authorize --session-id, which documented a required flag as optional under a fully greengz check. The audit now checks usage-line agreement (required-ness, value-taking) and the rule says so. The § Adding CLI Features caveat also claimed the audit "audits verbs, not flags", which stopped being true at GHI #350; scoped it to the lane claim it was actually making. Prior0.2.0— resolved a self-contradiction and a release-notes conflict (Pass A conflict-matrix rows 17 and 25, run 2026-07-16); adds the body-level version marker this file never carried. § Adding CLI Features declared "New Flag (Additive = Lite Lane)" while § Heavy Lane Trigger, 65 lines above, named flags explicitly as Heavy — andAGENTS.md§ Lane Rules agrees with the latter. Step 5 prescribed hand-authoring release notes, the one artifactchangelog-release-notes.mdforbids hand-editing. Prior: unversioned since authoring.
gate5-runbook-code-covenant.md¶
Lifted at version 0.3.0 (rule now at 0.3.1).
Rule version:
0.3.0— Movement C family closure, rules arm: the placeholder-output-examples prohibition now states its advisory posture in its own text, with the measurement behind it. Scored Promotable on a proposed regex scan; the probe that would have justified building it found zero placeholder tokens in scope and eight legitimate elision lines that a scan would have demanded be edited. Re-scoredJudgmentatdocs/governance/advisory-rules-audit.mdrow 49; re-scoring without this text edit would have been laundering (operator ruling 2026-08-08). Prior0.2.1— reconciled to ADR-0.0.24/ADR-0.0.36 — attestation is universal and the validation bundle must cite ARB-wrapped invocations (0.2.0); prior version history lifted to Rule Version History. Binding rules unchanged.Rule version:
0.2.0— reconciled to ADR-0.0.24 and ADR-0.0.36 (Pass A conflict-matrix rows 15 and 19, run 2026-07-16). § Do Not scoped attestation to "heavy/foundation scope", describing lane branching collapsed at ADR-0.0.36 — an agent on a Lite+feature OBPI read it as permission to self-close. § Validation bundle prescribed bare commands that emit no ARB receipt, making the sequence mechanically unrunnable on the foundation ADRs this rule governs (gz adr emit-receiptexits 3 on zero receipt citations). The same drift was caught and fixed on the skill side atgz-adr-closeout-ceremony/SKILL.md:317; the rule side was never reconciled. Prior0.1.0— initial shape conformance pass; renamed prohibited heading (OBPI-0.0.54-04).
chores.md¶
Lifted at version 0.3.2 (rule now at 0.3.3).
Rule version:
0.3.2— marks this version-history linedeprecated-verb-ok, matching the precedent already set at Rule Version History.0.3.1repointed § Correct Evidence offgz gates, and recording which verb it repointed away from made this line the file's only remaininggz gatesoccurrence — sogz validate --deprecated-verb-prescription, the checker shipped alongside that repoint under GHI #705, failed the file for describing the fix it shipped. The escape marker exists for exactly this: a line that documents a deprecation rather than prescribing one. Nothing caught it for the same reason--auditssat broken — the scope is not ingz check. Binding rules unchanged. Prior0.3.1— repointed § Correct Evidence ontogz check(0.3.0, GHI #705); prior version history lifted to Rule Version History.Rule version:
0.3.0— § Correct Evidence prescribedgz gates, which announces its own deprecation at runtime; repointed togz check(GHI #705). Evidence commands are the one place a retired verb is most costly — the operator runs them to produce attestation evidence. Enforced going forward bygz validate --deprecated-verb-prescription. Prior0.2.0— bumped under OBPI-0.0.21-06 to capture the two-surface layout, project-first → package-fallback resolution, and the--explain/doctor/--chores-layoutsurfaces. Prior unversioned content treated as0.1.0.
Lifted 2026-09-13 at version 0.3.3 (rule now at 0.4.0)¶
Rule version:
0.3.3— diet pass under GHI #921 (operator ruling 2026-08-30, "do 3, 4, and 5"): the superseded0.3.2–0.3.1version chain is lifted to Rule Version History, restoring the one-sentence shapeskill-surface-sync.md§ Non-negotiable rules #2 requires. Binding rules unchanged; scopedsrc/gzkit/chores/**, this rule loads on every chore-module edit, so narrative is the most expensive thing it can carry.
0.4.0 adds § Suppression is not a repair, GHI #999 step 6 (docs/governance/chore-class-system.md § Implementation order). It lands with its witness, per operator ruling 2026-09-13 (verbatim "Static chore check (Recommended)"): audit_chore_suppression reads each registered chore's criteria and CHORE.md command spans, with tests/governance/test_chore_suppression.py running it over the live tree in gz check and NC:chore-suppression proving it catches. The loader's SHELL_OPERATORS_RE already refused &&, ||, |, < and > in a criterion, so the audit holds the routes that refusal leaves open: a shell interpreter, whose script can end ; exit 0, and an exit-forcing flag. A marker hand-written during a run stays advisory, stated in the clause itself.
Lifted 2026-09-14 at version 0.4.0 (rule now at 0.5.0)¶
Rule version:
0.4.0— adds § Suppression is not a repair (GHI #999 step 6), landed with its witnessaudit_chore_suppressionso it never stood as unwitnessed doctrine; prior0.3.3lifted to Rule Version History.
Lifted 2026-09-19 at version 0.5.1 (rule now at 0.5.2)¶
Rule version:
0.5.1— the full-suite test invocation isuv run gz test, the parallel canonical runner; the serial-m unittestform is retired (operator ruling 2026-09-18, under GHI #921). Prior0.5.0: § Discover Chores addsgz chores status, the staleness board that reads every chore's band without running one (GHI #936), and § Plan & Advise drops a--replaceflaggz chores plannever had; prior0.4.0lifted to Rule Version History.
Lifted 2026-09-28 at version 0.5.3 (rule now at 0.6.0)¶
Rule version:
0.5.3— distinguish Lite chore verification from required full-repository checks and Heavy BDD evidence (GHI #1042).Rule version:
0.5.2— the Lite-lane typecheck line is the canonicaluv run ty check . --exclude features(GHI #921). Binding rules unchanged. (Recovered from7422e33ab; the0.5.3edit replaced it without lifting it.)
adr-audit.md¶
Lifted at version 0.2.0 (rule now at 0.2.1).
Rule version:
0.2.0— reconciled to ADR-0.0.24 and ADR-0.0.59 (Pass A conflict-matrix rows 18 and 19, run 2026-07-16); adds the body-level version marker this file never carried, which is how both drifts survived unnoticed. § Audit sequence step 2 prescribed bare commands that emit no ARB receipt, making step 4 fail closed at exit 3 on every foundation ADR this rule governs. § Rules offered only two diagnosis branches, the first of which (author a @covers test) is the anti-patterntests.md§ REQ Scope Discipline names for SUPPORT and STRUCTURAL-FENCE REQs. Prior: unversioned since authoring.
Lifted 2026-08-30 at version 0.2.1 (rule now at 0.3.0)¶
Rule version:
0.2.1— reconciled to ADR-0.0.24/ADR-0.0.59 — ARB-wrapped audit commands and per-REQ-kind diagnosis branches (0.2.0); prior version history lifted to Rule Version History. Binding rules unchanged.
Lifted 2026-09-19 at version 0.3.1 (rule now at 0.3.2)¶
Rule version:
0.3.1— theunittestARB step names the canonical parallel command (CANONICAL_STEP_COMMANDS["unittest"]); the serial form it carried is no longer the canonical one andgz arb validateflags it. Prior0.3.0: scored for real under GHI #921 (2026-08-30). This rule sat indata/advisory_scorecard_grandfather.json, pinned at0.2.1against a version nobody recorded; the pin is stripped by any edit, so its clauses were re-read and its Coverage Ledger rows added or corrected in the same commit. Prior version history lifted to Rule Version History. Binding rules unchanged.
gh-cli.md¶
Lifted at version 0.3.0 (rule now at 0.3.1).
Rule version:
0.3.0— reconciled to AGENTS.md § Always #13 (Pass A conflict-matrix row 13, run 2026-07-16). § Allowed commands listedgh issue create --label defectas its first entry, under an allowlist heading, in the rule an agent greps for on anyghquestion — affirmatively sanctioning the invocation Always #13 forbids, and shipping that instruction in the wheel. The0.2.0diet pass predates the/ghi-authormandate and never reconciled to it. The invocation is retained (annotated) rather than deleted: it is load-bearing inside/ghi-author. Prior0.2.0— diet pass under GHI #327; compressed cross-repo filing section.
Lifted 2026-08-30 at version 0.3.1 (rule now at 0.4.0)¶
Rule version:
0.3.1— reconciled § Allowed commands to AGENTS.md § Always #13, annotating the/ghi-author-only invocation (0.3.0); prior version history lifted to Rule Version History. Binding rules unchanged.
Lifted 2026-09-07 at version 0.4.0 (rule now at 0.5.0)¶
Rule version:
0.4.0— scored for real under GHI #921 (2026-08-30). This rule sat indata/advisory_scorecard_grandfather.json, pinned at0.3.1against a version nobody recorded; the pin is stripped by any edit, so its clauses were re-read and its Coverage Ledger rows added or corrected in the same commit. Prior version history lifted to Rule Version History. Binding rules unchanged.
Lifted 2026-09-23 at version 0.5.2 (rule now at 0.6.0)¶
Rule version:
0.5.2— the allowedgh issue closeandgh release createexamples no longer model a narrative close or a whole-file release body, and the/ghi-authormandate is cited where it lives (GHI #921). Prior0.5.1and earlier lifted to Rule Version History. Binding rules unchanged.
Lifted 2026-09-27 at version 0.6.0 (rule now at 0.7.0)¶
Rule version:
0.6.0— operator ruling 2026-09-23: § Allowed commands gainsgh issue comment./ghi-authorStep 0 mandates a cross-link comment on a sibling GHI "at authoring time, not as a follow-up", and this allowlist did not carry the verb — so a skill-mandated step was unreachable through the only rule an agent greps on aghquestion. Measured at GHI #1083, whose cross-link to sibling #1081 went unwritten for exactly this reason. Binding rules changed: the allowlist widens by one verb. Prior0.5.2and earlier lifted to Rule Version History.
Lifted 2026-09-07 at version 0.5.0 (rule now at 0.5.1)¶
Rule version:
0.5.0— GHI #972 (2026-09-07): adds § Census queries. § Allowed commands sanctionedgh issue listby verb while the hazard is scoped by result-set size — everygh <noun> listreturns a 30-row page with no truncation marker and exit 0, and the handoff chain's own "re-derive the count" step was that capped command, so a session that noticed a wrong count re-derived30with fresh confidence. Scored Judgment at row 51c. Prior version history lifted to Rule Version History.
Lifted 2026-09-19 at version 0.5.1 (rule now at 0.5.2)¶
Rule version:
0.5.1— GHI #972 reopened (2026-09-07): two statements in0.5.0corrected. The count form printed only.total_count, hiding theincomplete_resultsfield the same clause required checking — the command now refuses to print a number on an incomplete search. And "a result whose length equals its--limitis a truncated page" overstated: equality proves nothing either way (--limit 40returned 40 against a 40-issue queue, complete), so completeness is UNPROVEN until pagination or an authoritative total establishes it.0.5.0added § Census queries under the same GHI; scored Judgment at row 51c. Prior version history lifted to Rule Version History.
task-discovery.md¶
Lifted 2026-09-17 at version 0.9.0 (rule now at 0.10.0)¶
Diet pass under GHI #921 (operator: "A" on the full before/after, 13,949 B → 6,527 B). Binding rules unchanged. paths: narrowed from .gzkit/** and docs/design/adr/** to .gzkit/hooks/** and docs/design/adr/**/obpis/** — the surfaces the channels are written on — so the rule no longer fans into .gzkit/AGENTS.md or loads on ledger, corpus, handoff, chore and lock edits. Lifted verbatim as dated records — the 0.9.0 note and the rollout histories:
Rule version:
0.9.0— GHI #820 (reopened): § Layer-drift fail-close now STATES that drift is contradiction and never shortfall, and binds every consumer to the one predicate that implements it. The carve-out had lived only in a_crossing_channelsdocstring, so a second consumer kept the overturned reading for 19 days. Prior0.8.0–0.5.1lifted to Rule Version History. Scopedsrc/gzkit/**, this rule loads on every source edit, so narrative is the most expensive thing it can carry.Three channels are producer-fed;
@advancesis advisory (GHI #752).ledger,commit_trailer, andtasks:are each written by the runtime at the moment it knows the attribution — the ledger on the TASK event, the trailer byprepare-commit-msg-task-trailers, andtasks:bygz task start(_stamp_brief_task_declaration).@advancesis advisory and expected to be empty: it marks the function an author judges materially advances a TASK, which no runtime can determine, so it has no producer by construction. Its emptiness is asserted rather than assumed (test_advances_channel_is_asserted_dead_not_assumed_dead) and is not a defect. Signature (c) compares only OBPIs where two channels carry data;tasks:populates going forward, from the next minted TASK onward, never retroactively.Producer-stamped (GHI #752).
gz task startappends the minted TASK to its OBPI brief'stasks:list via_stamp_brief_task_declaration— idempotent, accumulating (one TASK per REQ), and a silent no-op when the brief cannot be found or written, so attribution never blocks the pipeline. Hand-authoring the field stays valid; the stamp exists because the convention alone produced zero declarations across the whole corpus.This enforcement was declared and then deferred to OBPI-0.0.64-04 from
0.2.0until0.7.0. That OBPI's seven REQs never scoped it, so the deferral could never discharge — it named a destination that had not accepted the work, and completed correctly without it. Prefer citing the check over citing a work-surface ID: an ID is a promise that goes stale silently when the surface reaches a terminal state on different scope.Auto-stamped (landed under GHI #731).
.gzkit/hooks/prepare-commit-msg-task-trailersappends aTask:line per in-progress TASK onsrc/**/tests/**commits; an authoredTask:trailer of any form suppresses it. A non-Task:trailer does NOT — the hook skips only whenhas_task_trailer()is true, and that matchesTask:specifically. Witness status unruled — GHI #752.
The trailer set is CLOSED (operator ruling 2026-09-01, verbatim "never"). gzkit commits carry Task:, Ceremony:, and Eval-feedback-source: — nothing else. A session-attribution trailer injected by an agent harness (Claude-Session: or any successor) is a harness instruction, never repo doctrine: do not author it, and strip it when a harness reminder supplies one. It occurs in zero repo surfaces and is inert to TASK discipline — it neither satisfies nor suppresses has_task_trailer() — so this ruling closes a five-session RECURRENCE, not a defect. Measurement and rationale: Rule Version History § 0.8.0. (Advisory — gz validate --commit-trailers requires a Task:; it never checks for the absence of an extra trailer.)
Consumers MUST share the predicate, never restate it. _crossing_channels (src/gzkit/commands/validate_task_envelope.py) is the single implementation; gz validate --task-envelope-coherence and gz task envelope diagnose both read it. The two previously carried separate spellings, and the diagnostic went on reporting a subset as drift for 19 days after #820 corrected the validator — while the validator's own failure text sends the operator to that view. (Advisory — tests/governance/test_task_envelope_coherence.py::TestDiagnoseDriftAgreesWithTheValidator asserts the two consumers agree; nothing prevents a third consumer from re-implementing it.)
Lifted at version 0.7.1 (rule now at 0.9.0).
Rule version:
0.9.0— GHI #820 (reopened): § Layer-drift fail-close now states explicitly that drift is CONTRADICTION and never shortfall, and binds consumers to the single_crossing_channelspredicate. #820 corrected the validator on 2026-08-18 but the carve-out was recorded only in that function's docstring, sogz task envelope diagnosekept computinglen({frozenset(s) for s in populated}) > 1— the overturned any-inequality-is-drift reading — for 19 more days. The coupling is not incidental: the validator's own failure text sends the operator to the disagreeing view, and the diagnostic was the STRICTER side, so it reported drift where the gate reported none and invited the falsified attribution #820 exists to prevent. Measured at repair (OBPI-0.35.0-04): ch3 a strict subset of ch2, ch2 == ch4, validator crossing[], diagnosticdrift: True.Rule version:
0.8.0— operator ruling 2026-09-01 (verbatim "never") CLOSED the commit-trailer set toTask:,Ceremony:, andEval-feedback-source:, and corrected the auto-stamp's suppression clause. Why the question kept recurring: it had been argued across five sessions from a 30-day average that straddles a step change, so each session sampled a different slice and reached a different answer — the last framing was "the repo is 21% consistent (149 of 705)". Measured per-day at the ruling, it is not a consistency rate at all:Claude-Session:appears in 0 of 26 commits on 2026-08-19, first appears 2026-08-20 (3ac1c7d0), reaches 7 of 7 on 2026-08-30, and is 0 of 19 across 2026-08-31 and 2026-09-01. That is an 11-day window tracking a per-session agent-harness reminder, not repo doctrine —Claude-Sessionoccurs nowhere insrc/,data/,docs/, or.gzkit/rules/, and is validated and read by nothing. The "always" option was costed and rejected: 196 of 700 commits in the window aregz git-syncceremony commits whose trailers come from the fixed_SYNC_COMMIT_TRAILERSconstant (src/gzkit/commands/sync.py), so adopting it would require changing that producer plus a new validator arm, or it re-drifts the instant the harness setting flips — which the window proves it does. Against that, the trailer's only asset is a session URL that resolves for one account and ships dead to wheel adopters. The counter-argument was recorded rather than suppressed: session forensics is genuinely valuable here, and Layer-2 session provenance is only ~17% populated (87 of 500 recent ledger rows carrysession_id), so the redundancy case is not airtight — the ruling rests on the harness provenance and the producer cost, not on redundancy. Suppression correction: the rule had claimed since0.5.0that "an authored trailer of ANY form suppresses" theprepare-commit-msg-task-trailersstamp. False — the hook returns early only whenhas_task_trailer()is true, and that matchesTask:specifically. Verified againstgzkit.tasks.has_task_trailer: aClaude-Session:-only message returnsFalse(stamp still fires);Task:in either order returnsTrue.Rule version:
0.7.1— diet pass under GHI #921 (operator ruling 2026-08-30, "do 1 and 2"): the superseded0.7.0–0.5.1version chain is lifted here, restoring the one-sentence shapeskill-surface-sync.md§ Non-negotiable rules #2 requires. Binding rules unchanged; scopedsrc/gzkit/**, this rule loads on every source edit, so narrative is the most expensive thing it can carry.Rule version:
0.7.0— GHI #753:tasks:schema enforcement is LIVE, and the deferral that promised it is retired. From0.2.0this rule declared the check "deferred to OBPI-0.0.64-04" in three places (the channel table, § Convention: Frontmattertasks:, and theBriefStructure.tasksfield docstring). That OBPI's seven REQs never scoped it — they cover signatures (a)/(b)/(c),req_atomic,gz task envelope diagnose, thegz checkjoin, and a structural fence — so it reachedattested_completedcorrectly on its own scope while the deferral became permanent, because nothing couples "X is deferred to Y" to "Y's REQ set contains X". Both arms now ship:BriefStructure._validate_taskson the model path and signature (e) on the corpus path, each delegating toTaskId.parserather than restating the grammar. Latent until #752 made the channel producer-populated; corpus-safe because zero briefs carried atasks:entry at landing. Prior0.6.0— GHI #752: thetasks:channel is now PRODUCER-STAMPED bygz task start, and@advancesis DEMOTED to advisory. Two of the four channels produced zero keys repo-wide, so Signature (c) compared 7 of 534 OBPIs. The two were not symmetric:task_startalready resolves the OBPI id when it mints the TASK, sotasks:is runtime-known and was merely being asked of an author (the convention that decayed to ~15% on the trailer channel and to 0% here);@advancesnames the function an author judges materially advances a TASK, which no runtime can determine. Narrowing the envelope toledgerxcommit_trailerwas rejected — since0.5.0the trailer is stamped from the ledger, so those two are partly one source and their agreement is partly tautological. A brief-authoredtasks:restores an independent witness. Prior0.5.2— repointed the unruled witness question from GHI #731 (closed) to #752. Prior0.5.1— commit-trailer channel is producer-stamped (0.5.0, GHI #731); prior version history lifted to Rule Version History.Rule version:
0.5.0— commit-trailer channel is now PRODUCER-STAMPED (GHI #731; ~15% authored adherence left Signature (c) skipping 96 of 102 OBPIs). See § Convention: Commit trailer. Prior0.4.0— reconciled totests.md: the channels are cumulative-with-a-floor (an@advancesdecorator never discharges theTask:obligation, GHI #552), and the slug form's-#<ghi>anchor is optional (operator moratorium 2026-06-01). Prior0.3.0— ADR-0.0.64 closeout reconciliation.
pythonic.md¶
Lifted at version 0.5.0 (rule now at 0.5.1).
Rule version:
0.5.0— § Type-check suppression syntax gains the two forms ty actually honors that this rule had never listed:# type: ignore[ty:<code>]and the interop# type: ignore[<foreign-code>, ty:<ty-code>]. The omission was not cosmetic — the rule's own enforcement regex matched any bracketedtype: ignore[, sogz validate --type-ignoresflagged two working suppressions as violations, and a reader following the two-row table would delete a live suppression to satisfy the gate. The prohibition is unchanged and now stated at its real cause: ty skips codes lacking aty:prefix, so an all-foreign directive suppresses nothing — which is also why a shared comment works, making deletion the wrong fix whenever another checker reads the line. Verified against ty 0.0.69 rather than inferred from this file (# type: ignore[misc]left aninvalid-assignmenterror standing; bothty:-bearing forms suppressed it). Scope widened with the corrected predicate:srcalone had let 512 inert markers accumulate acrosstestsandfeatures. Prior0.4.0— § Imports records the PLC0415 posture as accepted rather than deferred (operator ruling 2026-08-08, "record deferred postures as accepted"). "Deferred" named a queue nothing was advancing, and the clause had been carried as an open loop across five handoffs on that word alone; the honest state is a measured, disclosed advisory whose reclassifying evidence is now named. Re-measured at the acceptance: still 138 sites. No binding rule changed. Prior0.3.0— Movement C family closure, rules arm. Scoring this rule's clauses for real found four advisory-scorecard rows asserting enforcement that did not exist, which is a worse state than the Promotable rows the campaign box counts: a Promotable row honestly says "no witness yet", while a false Mechanical row reports green while blind and is invisible to the criterion. Row 18 claimed "ruff BLE001 enforces" withBLEabsent from[tool.ruff.lint] select(6 live violations, one behind a# noqa: BLE0001typo that suppressed nothing); row 23 claimed PLC0415 was "partially enforced" withPLequally absent (138 live violations); rows 19 and 20 claimed line-count enforcement that § Size Limits has said was unbacked since0.2.0.BLE001is now enabled and the six sites fixed with cited justifications (operator ruling 2026-08-08); PLC0415 is deferred because its 138 sites need per-site readings against this rule's own optional-dependency and cycle-avoidance carve-outs. Rows 19/20/23 re-scoredJudgmentwith the measurements recorded here. Prior0.2.1— names the unreconciled three-way threshold conflict in § Size Limits & Refactoring (0.2.0); prior version history lifted to Rule Version History.Rule version:
0.2.0— names the unreconciled three-way threshold conflict in § Size Limits & Refactoring (Pass A conflict-matrix row 11, run 2026-07-16); adds the body-level version marker this file never carried, which is how a competing threshold authority survivedcomplexity-thresholds.md§ Invariant's explicit prohibition on exactly that. No number changed — resolution needs a class-size corpus band that does not exist yet, and is routed for operator decision rather than guessed. Prior: unversioned since authoring.
Lifted 2026-09-19 at version 0.5.2 (rule now at 0.5.3)¶
Rule version:
0.5.2— the full-suite test invocation isuv run gz test, the parallel canonical runner; the serial-m unittestform is retired (operator ruling 2026-09-18, under GHI #921). Prior0.5.1: diet pass under GHI #921 (operator ruling 2026-08-30, "do 1 and 2"): the superseded0.5.0–0.2.1version chain is lifted to Rule Version History, restoring the one-sentence shapeskill-surface-sync.md§ Non-negotiable rules #2 requires. Binding rules unchanged; scoped**/*.py, this rule loads on every Python edit, so narrative is the most expensive thing it can carry.
hexagonal-architecture.md¶
Lifted at version 0.2.0 (rule now at 0.2.1).
Rule version:
0.2.0— seats HA inside the DDD → HA → BDD → TDD spine and adds the binding cohesion doctrine (domain modeled as the ontology, not a folder tree;core/stays; subsumption over parallel models; "why is this here?" is a required answer).0.1.0enshrined Cockburn Ports & Adapters as the primary code-architecture directive (deps behind adapters, stdlib + Pydantic core, parameterize every external dependency).
Lifted 2026-08-30 at version 0.2.1 (rule now at 0.3.0)¶
Rule version:
0.2.1— seats HA inside the DDD → HA → BDD → TDD spine and adds the binding cohesion doctrine (0.2.0); prior version history lifted to Rule Version History. Binding rules unchanged.
agent-failure-modes.md¶
Changed 2026-09-24 at version 0.8.2 (GHI #1019)¶
The OpenAI-tier source moved from the GPT-5.6 System Card (§§ 7.1–7.4, 9.1.3.6, 9.2.2) to the GPT-6 Astra System Card (§§ 8.3.1, 8.6, 8.7, 8.8, 9.1–9.2). GPT-6 § 8.7 splits verbalized metagaming (reasoning about the grader) from oversight gaming (acting on it so the result loses its intended meaning); pattern 9 is oversight gaming. The METR and GPT-5.6 § 9.2.2 summary-omission findings have no GPT-6 counterpart. Patterns unchanged (nine).
Changed 2026-09-24 at version 0.8.1 (GHI #1089)¶
The Opus-tier source moved from the Claude Opus 5 System Card (§§ 6.4.4, 6.6.1) to the Claude Opus 5.5 System Card (§§ 6.3.1, 6.4.1, 6.4.3–6.4.5, 6.5.1). Patterns unchanged (nine): the new card's authorization findings re-source Hallucinated authorization and Security shortcut for expedience, and its unverifiable-authorization regression is incoming-content doctrine, not a tenth pattern. The 0.8.0 note, verbatim:
Rule version:
0.8.0— re-sourced to the Claude Fable 5.1 & Claude Mythos 5.1 System Card (GHI #934) and the Backstop column repointed to where each rule lives since the 2026-09-17AGENTS.mdrewrite (GHI #921); theAlways/Never #Nnumbers andDO IT RIGHT 6ano longer resolve in the contract. Prior version history lifted to Rule Version History. Patterns unchanged (nine).
Lifted at version 0.6.0 (rule now at 0.6.1, re-sourced to current-card-only
citations under the 2026-08-02 operator ruling against retaining superseded-model
references in live rules). Origin provenance for the pattern set, preserved
verbatim:
Patterns 1–6 from the Opus 4.7 System Card (§ 2.3.6) and GPT-5.5 System Card (§ 9.2); patterns 7–8 from the Claude Opus 5 System Card (§§ 6.4.4, 6.6.1); pattern 9 from the GPT-5.6 System Card (§§ 7.4, 9.1.3.6, 9.2.2, 2026-07-09), whose §§ 7.1–7.2 also corroborate patterns 2, 3, 7, 8 from a second vendor's internal agentic-coding traffic.
Rule version:
0.6.0— extended 8 → 9 patterns (operator ruling 2026-08-02; GHI #750 lineage; ADR-0.0.23 § Consequences pre-authorizes extension). Adds Metagaming / gaming the gate from the GPT-5.6 System Card: § 7.4 defines metagaming as reasoning "about how it will be graded, rewarded, or monitored"; § 9.1.3.6 records METR discarding a capability measurement over the detected cheating rate; § 9.2.2 records UK AISI observing anticipation of monitors and user-facing summaries that omit what the reasoning admits. Prior0.5.1— citation refresh (GHI #750): GPT-5.6 §§ 7.1–7.2 supplies second-vendor observations for patterns 2, 3, 7, 8. Prior0.5.0— re-sourced to the Claude Opus 5 System Card (2026-07-24) and extended 6 → 8 patterns. Adds Hallucinated authorization (Opus 5 § 6.6.1 measured the model internally representing "user consent that was never given" before a destructive action) and Security shortcut for expedience (§ 6.4.4, one of two dimensions Anthropic newly introduced). The ADR that authored this rule pre-authorized the revision: ADR-0.0.23 § Consequences — "treating the rule as living: future system cards may rename or extend patterns." Prior0.4.0— repointed the Safeguard-circumvention and Fabrication backstops off the removed TTYATTESTauthenticity gate onto AGENTS.md § Never #1 (operator-verbatim attestation + audit), per the canon-owner attestation declaration.
Lifted 2026-09-17 at version 0.7.0 (rule now at 0.8.0)¶
Rule version:
0.7.0— scored for real under GHI #921 (2026-08-30). This rule sat indata/advisory_scorecard_grandfather.json, pinned at0.6.2against a version nobody recorded; the pin is stripped by any edit, so its clauses were re-read and its Coverage Ledger rows added or corrected in the same commit. Prior version history lifted to Rule Version History. Binding rules unchanged.
Card lineage at the 0.8.0 rotation (GHI #934): the Mythos-tier source moved
from the Claude Fable 5 / Mythos 5 System Card (2026-06-09; §§ 2.3.3 real-usage
failure tags with cluster counts, 6.1.2, 6.3.5 diligence evaluations, 6.4.1
white-box vignettes) to the Claude Fable 5.1 & Claude Mythos 5.1 System Card
(2026-09-01; §§ 2.3.3 qualitative shortcomings, 6.2.1 deployment monitoring,
6.4.2–6.4.5 audit dimensions, 6.6.1 white-box clusters). The 5.1 card carries no
cluster counts and no diligence-evaluation rates; those figures left live
doctrine with the card. Backstop citations repointed from Always/Never #N and
DO IT RIGHT 6a (the pre-2026-09-17 numbering) to the rule names in the
rewritten AGENTS.md; 6a resolves to DO IT RIGHT #1 ("Fix the class of
failure, not the instance"), per the 2026-04-30 text that first cited it.
Lifted 2026-08-30 at version 0.6.2 (rule now at 0.7.0)¶
Rule version:
0.6.2— Fable/Mythos 5 card consumed (GHI #751): patterns 1–6 now carry direct current-generation observations — the card's own § 2.3.3 failure tags use this taxonomy's vocabulary (Safeguard circumvention/Fabrication/Skipped cheap verification/Reckless action/Correction fails) with real-usage cluster frequencies — and pattern 9 gains Anthropic-side corroboration (§§ 6.1.2, 6.4.1.2: grader-satisfying reasoning, almost never verbalized). Prior0.6.1— re-sourced to current-card-only citations; origin lineage lifted to Rule Version History. Patterns and backstops unchanged since0.6.0(nine patterns).
agents-md-map-doctrine.md¶
0.13.0 — 2026-09-17¶
Diet pass under GHI #921 (operator: "A" on the full before/after, 11,982 B → 7,083 B). Binding rules unchanged. Lifted verbatim as dated records — the 0.12.0 note, § Five prohibited shapes (a restatement of § Invariant), the § Budget pointer history, the GHI #822 naming paragraph and the attestation-granularity measurement:
Rule version:
0.12.0— adds § Writing levers, the authoring tests for every per-turn surface, distilled from Matt Pocock'swriting-for-agentsskill and Anthropic's current prompting guidance (operator direction 2026-09-17). Prior versions lifted to Rule Version History. Binding rules unchanged.
Five prohibited shapes¶
- Multi-paragraph rationale prose — paragraph longer than 5 lines without a binding-bullet anchor. The rationale belongs in
docs/governance/; the bullet states the rule. - Worked examples or anti-pattern catalogs — subsections titled "Worked example", "Anti-patterns", "Example", or equivalent. These belong in the canonical doctrine doc at a stable URL.
- "Why this is canon" / "Why X" coda blockquotes — blockquote paragraphs that explain why a rule was chosen. These are encyclopedic; the bullet is the rule.
- Narrative pedagogical sections — multi-paragraph explanations of how a rule works, its history, or its relationship to other rules. Route to
docs/governance/agent-contract-rationale.md. - Operative-claims expansions — prose blocks restating operative claims whose binding-bullet form already states the rule fully. The binding bullet is sufficient; the expansion is accretion.
The destination this doctrine sets for AGENTS.md is a tightened 15000-char ceiling (the map, not the encyclopedia). That weight-halving is not yet in force: AGENTS.md currently sits above 15000 under a relaxed interim budget, and reaching the target is deferred to ADR-0.35.0-canon-entry-corpus-landing § Decision 3 — sections declare corpus-owned or unowned, the generator materializes owned sections from the corpus, and the unowned byte total is held in a decrease-only ratchet. The predecessor pointer to ADR-0.0.37 is retired: that ADR is terminal (§ Terminal Disposition, 2026-07-18) and its registry-spine OBPIs were permanently withdrawn, so no weight-halving work can land under it. The intermediate hop through GHI #533 is also retired: that issue closed 2026-09-01 superseded into this ADR, having tracked a dependency (the registry-projection migration) that was itself withdrawn. Cite the ADR directly — a pointer through a closed tracker is the same dead-pointer shape this paragraph already records once.
The transitional window is open. The delivered-surface witness (GHI #712, src/gzkit/governance/trust_audits/surface_delivery_witness.py) is wired into the default gz check scope and reports the byte distance to the Codex delivery cap; run gz validate --instructions-files-budget for the live figure. That witness is advisory and never fail-closed (operator ruling 2026-07-06, recorded in the budget file's _doc) — do not read it as a gate that will stop an overrun. The cap itself is project_doc_max_bytes, a Codex setting gzkit writes into the .codex/config.toml it generates — Codex loads that file in any directory the operator has trusted (its own trust prompt: "Trusting the directory allows project-local config, hooks, and exec policies to load"), and it wins over $CODEX_HOME/config.toml. So the cap recorded in data/vendor-manifest.json is a limit gzkit established, not a vendor fact — and it is checked by observation, not by two authored numbers agreeing: gz validate --instructions-files-budget carries a codex-delivery witness that reads what Codex actually assembled (GHI #962). Raising the cap is legitimate and is how the contract reaches a Codex session whole; raising it without re-observing delivery is what GHI #962 names. This paragraph names no byte figures, per the § Budget instruction four lines above that a duplicated number drifts from what is enforced — the earlier text asserted a 560 B margin and a fail-close, and by 2026-09-02 both were false while AGENTS.md sat past the cap with Codex silently truncating from § Architectural Boundaries down (GHI #815). Shape enforcement (gz validate --agents-md-map-conformance) ships and binds now; the weight target lands with the deferred work. (ADR-0.0.54 closed Completed-Partial on exactly this split.)
- Do not call a build step "Gate 5." The content surface's attestation is named CORPUS ATTESTATION. Gate 5 is OBPI/ADR completion attestation (ADR-0.0.36) and nothing else; a second subject wearing one name is the collision the transit/exchange/handoff fence forbids.
gz content commit --helpclaimed the name until 2026-08-18 and no longer does (GHI #822). The replacement noun iscorpus, notrendition, because this same ruling puts the attestable subject on the corpus — the table above attests adding and removing entries and exempts a re-render — and holds a rendition to be a Layer-3 derived view, never the thing attested. Naming a rendition promotion after the artifact it writes would re-assert the very inversion this section records.
(Advisory — the implementation is inverted and no witness holds it.) Measured 2026-08-17: gz content remember and gz content retire accept no --attestor; gz content commit requires one and fail-closes on empty. So the two acts this rule makes attested are ungated, and the one it exempts is gated. Reclassify when the verbs carry the granularity.
0.12.0 — 2026-09-17¶
Adds § Writing levers. Operator direction, verbatim: "use the advise from pocock and read the whole thing, onboard some or all if useful." The source is Matt Pocock's writing-for-agents skill (github.com/mattpocock/skills, MIT), read in full on 2026-09-17: SKILL.md, SKILL-MECHANICS.md and agents/openai.yaml. The section is a restatement in gzkit's terms, not a copy, and it keeps only the levers that bear on surfaces gzkit renders: the two loads, the branch test for inline versus disclosed material, pointer wording, positive phrasing, the no-op hunt, single source of truth including the environment, co-location, leading words, and the context cost of a model-invoked skill description. Its guidance on steps, completion criteria and splitting by sequence is skill-authoring procedure and was not onboarded here.
It agrees with the Anthropic pages read the same day: Prompting best practices (§ Tool usage, § Add context to improve performance, § Migration considerations), Prompting Claude Opus 5 (§ Task scope and over-verification) and the Claude Code memory page (§ Write effective instructions). The clause is advisory and says so: the source itself holds that whether a sentence is a no-op is settled by running the document, and gzkit has no behavioral witness for instruction text (GHI #943).
The rule's paths: scope is unchanged. Widening it to the canonical authoring surfaces (.gzkit/rules/*.md, .gzkit/skills/**) would fan the whole rule into the generated nested AGENTS.md for those subtrees; measured with _extract_subtree_prefix, both patterns resolve to a subtree prefix.
0.11.0 — 2026-09-05¶
Withdraws 0.10.0 entirely. Its finding was false and the commit it justified was a regression.
0.10.0 asserted that gzkit has no route to deliver project_doc_max_bytes, inferring it from codex doctor naming a single config source, $CODEX_HOME/config.toml. Doctor does not enumerate the project-local overlay, so its silence was read as absence — the failure AGENTS.md names verbatim: "A search is not a read — never report that something is absent, undocumented, or unruled on the strength of keyword queries."
Codex loads a project's .codex/config.toml in any directory the operator has trusted, and that file wins over the global one. Its own trust prompt states the mechanism: "Trusting the directory allows project-local config, hooks, and exec policies to load." Measured 2026-09-05 via codex debug prompt-input, holding trust constant and varying only the repo-local value: 32768 → 32768 B delivered, 65536 → 46876 B (the whole surface), 12000 → 12000 B.
The cost of the false finding: 344f7189 (GHI #815) had set the cap to 65536 and it was working. e43c55c9 lowered it to Codex's 32768 default on 0.10.0's reasoning, re-introducing the truncation #815 had fixed, and b90d0484 propagated the claim into three more live surfaces. For roughly a day the tail of AGENTS.md — 14108 B, the IRON LAW included — reached no Codex session.
The structural lesson, and why this is more than a value correction: every check on this surface compared one authored number to another. CodexDocCapCoherenceTest pinned the generated config to the manifest; the surface-delivery witness measured rendered bytes against the manifest's declared cap. All of them stayed green while delivery was capped 14108 B short, because none of them ever asked the vendor. gz validate --instructions-files-budget now carries a codex-delivery witness (src/gzkit/governance/trust_audits/codex_delivery_witness.py) that reads what Codex actually assembled, reports unobserved rather than passing when it cannot run, and is advisory on the standing 2026-07-06 ruling that an adapter limit must not gate the core.
0.10.0 — 2026-09-05 (WITHDRAWN by 0.11.0 — recorded as authored; its finding does not hold)¶
§ Budget's transitional-window paragraph asserted that project_doc_max_bytes is "a Codex setting gzkit writes into the .codex/config.toml it generates". Measured 2026-09-04 under GHI #962: Codex reads $CODEX_HOME/config.toml and never the project-local file gzkit generates, so gzkit has never written that setting anywhere Codex looks. Both remedies are closed — writing to ~/.codex/ is an adopter's global surface the operator ruled out 2026-09-04 ("such locations are global to an adopter's project, i think the right answer is no"), and repointing CODEX_HOME moves auth.json with it, leaving the tier-1 adversary unauthenticated. The paragraph now records the cap as Codex's own default, in force and unraisable from here.
This is the doctrine arm of e43c55c9, which corrected the same false claim in render_codex_config's docstring and CodexDocCapCoherenceTest and set both numeric surfaces to 32768. The claim survived in two further live surfaces — this rule (with its wheel mirror) and src/gzkit/schemas/vendor_manifest.json's content_type_delivery_caps description — which is why the witness could still be read as reporting headroom gzkit controlled. Binding budget values unchanged; the correction is to what the cap is.
0.9.0 — 2026-09-01¶
Dead-pointer sweep under GHI #533. The § Budget destination pointed at GHI #533 → ADR-0.35.0 § Decision 3; #533 closed superseded into that ADR the same day, so the rule now cites the ADR directly. This is the second dead-pointer repair on the same sentence — 0.3.0 repointed it off terminal ADR-0.0.37 under the same GHI (fcff7b49, 9c1c1230). Binding rules unchanged; only the destination pointer moved.
Lifted 2026-08-29 at version 0.7.0 (rule now at 0.8.0).
Rule version:
0.7.0— § Attestation granularity's build-step bullet now NAMES the replacement (CORPUS ATTESTATION) instead of only prohibiting the collision, and records the prohibition as discharged rather than pending.0.6.0stated the rule as an open defect — "gz content commit --helpcurrently claims the name" — which is the shape that decays: a rule whose only content is "X is wrong" leaves the next author to invent a replacement, and the locally obvious invention isrendition attestation, which re-asserts the inversion the same section exists to record. Operator ruling 2026-08-18 (GHI #822) fixed the noun ascorpus, on the ground this section already carries: the attestable subject is the corpus, and the rendition is the Layer-3 projection that is "never the thing attested." Swept the same day acrosscontent/commit.py,content/__init__.py,docs/user/manpages/content.md,ADR-0.35.0and seven of its OBPI briefs, andinstructions-files-dietv3.2.0 — leaving every genuine "cite at Gate 5" reference and every### Gate 5 (Human)gate-covenant section untouched. Prior0.6.0— adds § Attestation granularity, which the0.5.0division of labour needed and did not have.0.5.0ruled that the chore is the only phase that trims and that ordinary sessions never resize a render surface — but it said nothing about who authorizes the resulting rendition, so the undifferentiated reading held: every recompose routes to Gate 5.instructions-files-dietv3.0.0 § 5a encodes that reading verbatim ("STOP THERE … It stops at the candidate to attest. It never lands canon itself"), which made the chore structurally unable to finish the job0.5.0assigned it. Operator ruling 2026-08-17, verbatim: "a rerender of unhanged canon doesn't require my attestation. adding to cms entries would. removing items would. trims and compressions to render within budget might invite a review" (spelling preserved), preceded by "I only attest to completed obpi/adr work". The discriminator is the corpus fingerprint, not the fact of a write. The current implementation is measurably backwards and this rule now says so:gz content rememberandgz content retireaccept no attestor, whilegz content commitfail-closes without one — gating the Layer-3 derived view and leaving the Layer-1 canon changes ungated. Prior0.5.0— theEXIT CONDITION: restore fail-closed at 1.0is RETIRED, not deferred (operator ruling 2026-08-17, ratified in design dialogue).0.4.0read the stay as a waiting room: budgets advisory until a mechanism arrived, then re-armed at 1.0. The mechanism arrived and turned out to be a cadence, not a gate, which dissolves the condition rather than satisfying it. Operator verbatim: "permit exceedances of accumulated render sources, then, let the chore handle overages"; "let the chore manage the limits. let normal discovery and operations add to or suggest modifications to sources. then, the chore is what gets render surfaces back into shape. otherwise, we churn"; "I can't be stopping to trim them at every turn." The division of labour is now binding: ordinary sessions add to sources and never resize a render surface;instructions-files-diet(v3.0.0) is the only phase that trims, and it recommends rather than decides; operator-on-demand is a first-class trigger. A hard gate has nothing to bite on here, and that is structural rather than a concession. The per-turn surface is not live-rendered — it is played back verbatim from a Gate-5-attested rendition (sync_agents_md,.gzkit/renditions/AGENTS.md/<consumer>.md+ a<consumer>.corpus.jsonmanifest carryingcorpus_fingerprint,corpus_entry_count,committed_ts,attestor).gz content rememberappends to the corpus and moves nothing; onlygz content commitchanges the rendered build, under human attestation. So the rendered surface cannot drift on its own, and a gate on it can only fire repeatedly about a build the operator already approved — measured 2026-08-17 as exactly that: approvedcorpus_entry_count59, corpus on disk 59, zero pending drift, and the witness nonetheless reporting the frozen 34354 B build against the codex cap on everygz check. That is alarming about the release instead of about unreleased accumulation. The tracked signal moves accordingly: drift between the corpus and the last approved build, which isgz validate --rendition-lineage(OBPI-0.35.0-06-validate-rendition-lineage, Draft) — the campaign's own item #6, so this is a sequencing note, not new scope. Reminder channels are the handoff at session boundaries and one quiet line ingz check; the remedy catalogue belongs to the chore. Budget VALUES remain unchanged and every file is still measured. Prior0.4.0— the per-file char budgets are ADVISORY until 1.0 (operator ruling 2026-08-17, verbatim: "temporary stay of all control surface budget limits until version 1.0. I want to be warned, and we may lift the limits as needed, but no blockers."). Budget VALUES are unchanged and every file is still measured, with each overrun reported to stderr carrying its distance and the/gz-context-dietpointer — the stay suspends the consequence, never the observation, which is what keeps "we may lift the limits as needed" a per-file decision rather than a blanket amnesty. Two arms were fail-closed, not one:audit_instructions_files_budgetandagents_md_map_conformancecriterion (d), the second discoverable only through this rule's § Shape enforcement list. Criteria (a)/(b)/(c) — paragraph shape, prohibited titles, link resolution — are untouched and remain fail-closed; the stay is scoped to budget limits, never to shape. The flip also made the scope internally consistent: its siblingsurface_delivery_witnesshas been observe-only on the vendor cap since the 2026-07-06 decoupling, sogz validate --instructions-files-budgethad been strict about the project's own soft budget while merely warning about the harder cap that can actually TRUNCATE the surface. Theinstructions-files-budgetnegative control was repointed at the scope's surviving fail-closed property (survival-declaration drift) the same day — a control asserting enforcement that no longer happens is worse than no control. Supersedes the original assertion ofREQ-0.0.54-03-01d("must be rejected");ADR-0.0.54is Validated and stays SEALED as the record of what was decided on its date, with the live posture held by the LAST dated entry indata/instructions_files_budget.jsonper that file's own reading convention. EXIT CONDITION: restore fail-closed at 1.0, on the standing 2026-07-28 ground that strictness is earned by the mechanism that discharges it —ADR-0.35.0§ Decision 3 is where that mechanism lands. Prior0.3.0— repointed § Budget's deferral target offADR-0.0.37, which went terminal 2026-07-18 (§ Terminal Disposition, "Split-and-Supersede") with its registry-spine OBPIs permanently withdrawn, onto the live successorADR-0.35.0-canon-entry-corpus-landing§ Decision 3 (section ownership + decrease-only ratchet). The dead pointer sat in a rule scoped toAGENTS.md/CLAUDE.md/.claude/rules/*.md, so every agent editing those surfaces was aimed at a destination that can no longer accept work (GHI #533). Also records that the transitional window is no longer slack: the GHI #712 delivered-surface witness is now in the defaultgz checkscope and AGENTS.md sits 560 B under the Codexproject_doc_max_bytesdefault. Prior0.2.0— corrected the § Budget section to read the livedata/instructions_files_budget.jsonsource of truth instead of duplicating stale enforced numbers, and marked the 15000-char AGENTS.md weight target as deferred to GHI #533 / ADR-0.0.37 (ADR-0.0.54 closed Completed-Partial: shape enforcement delivered; weight-halving deferred). Prior0.1.0— authored under OBPI-0.0.54-01; establishes the shape invariant and budget contract. OBPI-0.0.54-02 lifts AGENTS.md sections. OBPI-0.0.54-03 shipsgz validate --agents-md-map-conformance.
cross-platform.md¶
Lifted 2026-08-29 at version 0.6.0 (rule now at 0.7.0).
Rule version:
0.6.0— added § Delivered path literals (GHI #900), and widenedpaths:tosrc/gzkit/**/*.mdso the rule loads where that defect is authored. The platform-co-equality posture below was already contradicted by a path rooted at one machine, but no clause enforced the posture against a literal, so four wheel-shipped files told adopters to open a path that existed on one laptop whilegz validate --distributionread green -- byte-equivalent delivery of an instruction that cannot resolve. Prior0.5.0— added § Subprocess reads (GHI #582): text-mode subprocess captures MUST passerrors="replace", sinceencoding="utf-8"alone still raisesUnicodeDecodeError(aValueErrorthatexcept OSErrormisses) on non-UTF-8 tool/git output. Prior0.4.0— corrected the platform framing: removed the inaccurate "Windows (primary)" label and the miscitedDoctrine: ADR-0.0.1reference (ADR-0.0.1 is canonical-govzero-parity; no cross-platform ADR exists). gzkit targets all platforms co-equally (operator directive 2026-06-28). Prior0.3.0— diet pass under GHI #327; lifted helper patterns and scope-boundary details todocs/governance/cross-platform-rationale.md.
guardrail-feedback-prose.md¶
Lifted 2026-08-29 at version 0.2.0 (rule now at 0.3.0).
Rule version:
0.2.0— Movement C family closure, rules arm: § Mechanical promotion path is replaced by § Enforcement posture, which states the advisory disposition in the rule's own text and names what would reclassify it. The section had declared "This rule is Promotable" while describing, in the same paragraph, why the mechanism it promised was deliberately not built — a discipline declared with no witness and no statement that none is coming, which is the third state the family-closure criterion forbids. Nothing is being weakened: the per-surface covering-test channel that actually enforces this bar is now named as the enforcement rather than as an interim measure. Re-scoredJudgmentatdocs/governance/advisory-rules-audit.mdrow 61; re-scoring without this text edit would have been laundering (operator ruling 2026-08-08). Prior0.1.0— initial authoring under ADR-0.0.70 (Buetow adoption): the feedback text IS the prompt a human would otherwise have typed; engineer it as one.
Lifted 2026-09-19 at version 0.3.0 (rule now at 0.3.1)¶
Rule version:
0.3.0— diet pass under GHI #921 (operator ruling 2026-08-29, "we are compressing everything and anything that the agent can consume"). Version history lifted to Rule Version History. Binding rules unchanged.
model-selection.md¶
Changed 2026-09-25 at version 0.6.3 (GHI #1097)¶
The effort: max row read "Opus + extended thinking". Opus 5.5 always
thinks and effort sets how much (docs/governance/opus-tuning.md § Adaptive
regulation), so the row now names max effort. Routing policy is unchanged.
Prior marker, verbatim:
Rule version:
0.6.2— the Claude model mapping follows the current catalog:opus→claude-opus-5-5,fable→claude-fable-5-1(GHI #1089); routing policy is unchanged.
Changed 2026-09-24 at version 0.6.2 (GHI #1089)¶
The Claude mapping moved to the current catalog: opus → claude-opus-5-5
(Opus 5.5 card consumed, GHI #1089) and fable → claude-fable-5-1, which
the 2026-09-17 Fable 5.1 consumption (GHI #934) had left at claude-fable-5.
Routing policy is unchanged.
Lifted 2026-08-29 at version 0.5.1 (rule now at 0.6.0).
Rule version:
0.5.1— discharges the fable-calibration pending note via the card consumption (GHI #751); routing unchanged. Prior0.5.0— adds thefabletier (operator ruling 2026-08-02: "It seems like we should incorporate fable for the cases and times"): Mythos-class judgment work — doctrine evaluation, design dialogues, adversarial review, system-card evaluation — under operator supervision. Fable is NOT the pipeline or mechanical default; initial effort calibration landed with the card consumption (GHI #751) — seedocs/governance/opus-tuning.md§ Fable (Mythos-class) calibration: starthighnotmax, expect prompt-steerable overeagerness, and treat cyber-classifier fallback to a prior Opus tier as silent degradation.skill_modelLiteral and router test extended in the same commit. Prior0.4.0— adds operative claim 5 (subagent claims are relayed only with independent evidence), closing the relay gap the Claude Opus 5 System Card § 6.1.3 named: "the model can relay claims from subagents to users without verifying them", with multi-agent coverage acknowledged as an unmeasured limitation of that card's whole audit. gzkit dispatchesnarrator/implementer/quality-reviewer/spec-reviewerand relays their output into ceremony evidence, so the gap was live here. Also retires the two-generations-stale model mapping (opus→claude-opus-4-7) and compresses it to one line. Prior0.3.0— renamed prohibited headings; lifted Rationale to expansion doc (OBPI-0.0.54-04 shape conformance pass).
mx-mode.md¶
Lifted 2026-08-29 at version 1.3.0 (rule now at 1.4.0).
Rule version:
1.3.0— adds § Opting a guard into the floor, which names the two opt-in mechanisms and the choice between them.1.2.0said only that "a new guard inherits demotion by default and must opt into the floor explicitly" and never said HOW — whilecheckpoint.resolveoffers two routes that differ in reversibility: NAME (GATE5_INVARIANTSmembership, a Boundary Invariant #3 one-way door, forbidden for a narrower proxy per § Consequences/Negative #7) and LEVEL (emit CRITICAL, reversible). Measured 2026-08-22 against_GUARD_META: four of six pre-commit guards survive an open hangar and they do it BOTH ways —ledgerandgate5-attestationby name,post-authoring-src-commitsandenforcement-floorby level — so the roster could not be read without tracing the resolver. The reasoning existed and was correct; it lived in a commit body.84519da5(GHI #852) derived it at fix time and recorded it there, which is the settled-twice-recorded-nowhere shapegovernance-core.md0.13.0names: both wrong answers are locally plausible, so re-deriving it is a coin flip rather than a delay. Also records the operator ruling of 2026-08-22 that the Stage-2 production-code fence's pin is permanent (GHI #855), and that an unregistered guard name resolves CRITICAL rather than advisory. Prior1.2.0— § Honor the marker now names BOTH enforcement surfaces, andpaths:reaches the second one. The clause said "most guards drop to advisory" without qualification while the demotion reached onlygz validatescopes and thegz checkstep layer; the pre-commit guards insrc/gzkit/hooks/guards.pyeach self-decided fatality with a barereturn 1, which is verbatim the "named coverage defect" of ADR-0.0.74 BI#2. Measured 2026-08-22: zero checkpoint consumers anywhere undersrc/gzkit/hooks/, so an open hangar had no authority over one of the two surfaces governance is enforced on — whilegz mx --helpadvertised the hangar so "the operator can repair governance itself" and offeredgz mx enter --reason "repair ledger"as its worked example. Third recurrence of one class: GHI #638 (thegz checkstep layer), GHI #651 (the enforcement floor demoting inside the hangar), now GHI #843. The root is an inventory gap ADR-0.0.74 Negative #6 predicted in its own words — "a funnel that forgets it silently stays hard" — because the funnel inventory OBPI-0.0.74-02 shipped enumeratesvalidate_cmdand nothing else. Closed by GHI #843: one seam over one registered inventory inguards.py, fenced bytests/test_hooks_guards.py::TestMxCheckpointSeam, which fails when aforbid_*guard is added without a checkpoint entry. Prior1.1.0— Movement C family closure, rules arm: § Honor the marker now names the mechanical witness it has had since OBPI-0.0.74-17/-20. The scorecard scored this clause Promotable on the premise that "the marker-check is structural (file exists/not)" and liveness was advisory — a description of the rule's state beforecheckpoint.resolve,disposition, and 45 covering tests across five modules landed. Nothing was built to close this row; the score had simply not been revisited when its own mechanism arrived, which is how a Promotable row outlives the reason it was Promotable. Re-scored Mechanical atdocs/governance/advisory-rules-audit.mdrow 62. Prior1.0.1— marker path aligned to.gzkit/mx.json;e2d38c3c0bumped the HTML marker only (GHI #650). Prior1.0.0— initial authoring under ADR-0.0.74 (OBPI-0.0.74-08).
security-sensitivity.md¶
Lifted 2026-08-29 at version 0.5.1 (rule now at 0.6.0).
Rule version:
0.5.1— aligned the MX-marker path in § 3 to code truth: the hangar marker file is.gzkit/mx.json(src/gzkit/mx/marker.py:29), not.gzkit/mx-active(GHI #650). Prior0.5.0— named two unenforced surfaces the rule had been asserting as binding (Pass A conflict-matrix rows 22 and 23, run 2026-07-16). The auto-detect floor's "escape is fail-closed" language silently does not hold inside the MX hangar —sensitivityis not inGATE5_INVARIANTS, so the scope resolves ADVISORY and its exit-3 errors are dropped; the demotion is deliberate (a fail-closed sensitivity scope would lock the hangar against the briefs an operator enters it to repair — GHI #682) but was unannounced. The § Registry contract's self-bootstrapping clause presupposes an editing brief, which the operator-canon direct-fix path never has, leaving the floor unenforced on the path canon mandates. Both are now stated rather than implied. Prior0.4.0— GHI #625: the auto-detect floor now fails closed (sensitivity-floor-violation, exit 3) on an omitted declaration over a registered overlap, not only on a wrong one; pre-cutover briefs are grandfathered viadata/sensitivity_floor_grandfather.json. Prior0.3.2— renamed prohibited## Anti-patternsheading →## Do Not(OBPI-0.0.54-04 shape conformance pass).
skill-surface-sync.md¶
Lifted 2026-09-17 at version 0.12.0 (rule now at 0.13.0)¶
Diet pass under GHI #921 (operator: "A" on the full before/after, 11,719 B → 5,785 B). Binding rules unchanged. Lifted verbatim as dated records — the 0.12.0 note, rule 2's GHI #307/2026-07-21 history, § Procedure, § Version discipline, § Conflict resolution, § Do Not, and the class-classifier declaration narrative:
Rule version:
0.12.0— diet pass under GHI #921 (operator ruling 2026-08-29, "we are compressing everything and anything that the agent can consume"). Version history lifted to Rule Version History. Binding rules unchanged.
- Bump the version on every edit. Increment the version marker before saving. The marker differs by surface:
-
Skills carry the marker nested under
- Rules carry a body-levelmetadata:asmetadata.skill-version, a quotedX.Y.Zstring. That exact key is whatskills_audit.pyandsync_skill_validation.pyread; a top-levelskill-version:sibling ofname:/owner:is invisible to both and was silently unvalidated on 11 skills until GHI-less direct fix 2026-07-21. Presence is enforced (SKA-METADATA-SKILL-VERSION-MISSING, blocking) alongside the pre-existing format check.<!-- rule-version: X.Y.Z -->HTML comment immediately after the frontmatter, plus a visible> **Rule version:** \X.Y.Z`block quote with a one-sentence rationale. The rule frontmatter schema (RuleFrontmatterinsrc/gzkit/rules/init.py) isextra="forbid"and rejects askill-version:` key on rule files — that is intentional. The "skill-version" name on a non-skill artifact was a doctrine smell; the body-level marker resolves it.
Procedure¶
- Edit the canonical file under
.gzkit/skills/or.gzkit/rules/ - Bump the version marker for the surface:
- Skill: increment
skill-version:in frontmatter - Rule: increment both the
<!-- rule-version: X.Y.Z -->HTML comment and the visible> **Rule version:** \X.Y.Z`` block quote - Skills only: update
last_reviewed:to today's date (YYYY-MM-DD) in the same edit as theskill-versionbump (non-negotiable rule #6) - Run
uv run gz agent sync control-surfaces - Verify sync output shows no stale or divergent mirrors
- If sync reports stale mirror-only paths, follow the recovery in
/gz-agent-syncskill documentation
Version discipline¶
| Change type | Bump | Example |
|---|---|---|
| GovZero framework major release | Major | 6.0.0 -> 7.0.0 |
| Governance rule or procedure change | Minor | 6.0.0 -> 6.1.0 |
| Tooling, template, or wording fix | Patch | 6.0.0 -> 6.0.1 |
The same bump table applies to both skills (frontmatter version) and rules (body-level version). The marker location differs; the semver semantics do not.
Conflict resolution¶
When sync detects a version mismatch between canonical and a mirror, resolve via:
| Signal | What it tells you | How to check |
|---|---|---|
| Version marker (semver) | Intentional edit sequence | Skill: parse frontmatter skill-version. Rule: parse body <!-- rule-version: ... --> |
| Git commit hash / timestamp | Physical edit recency | git log -1 --format=%H -- <path> |
Resolution rules:
- Mirror version > canonical version: An agent edited the mirror directly. Promote the mirror content to canonical, then sync. The higher version wins.
- Mirror version == canonical version, content differs: An agent edited the mirror without bumping the version. Use git commit timestamp to determine recency; flag for human review.
- Canonical version > mirror version: Normal state — sync propagates canonical to mirrors.
Version is the primary signal (intentional semantic ordering). Commit hash is the tiebreaker (physical recency when versions match but content diverges).
Do Not¶
- Do not edit a skill without bumping its
skill-versionfrontmatter - Do not edit a rule without bumping its body-level
<!-- rule-version: ... -->marker (and the visible block quote) - Do not add
skill-version:to rule frontmatter — the schema rejects it (GHI #307); use the body-level marker instead - Do not edit
.claude/rules/directly — sync overwrites it from.gzkit/rules/ - Do not edit
.claude/skills/directly — edit.gzkit/skills/and sync - Do not manually copy skill files between surfaces — use the sync command
- Do not skip sync because "both files look the same" — sync also updates manifests, registrations, and vendor-specific rendering
Do Not¶
- Do not edit a skill without bumping its
skill-versionfrontmatter - Do not edit a rule without bumping its body-level
<!-- rule-version: ... -->marker (and the visible block quote) - Do not add
skill-version:to rule frontmatter — the schema rejects it (GHI #307); use the body-level marker instead - Do not edit
.claude/rules/directly — sync overwrites it from.gzkit/rules/ - Do not edit
.claude/skills/directly — edit.gzkit/skills/and sync - Do not manually copy skill files between surfaces — use the sync command
- Do not skip sync because "both files look the same" — sync also updates manifests, registrations, and vendor-specific rendering
Declaring a chore project-local (GHI #728). Add "projectLocal": true to its
entry in .gzkit/chores/registry.json. All three consumers read the one
declaration through _classify_chore_file, and the shipped registry.json is
filtered on export — the wheel must never advertise a chore whose files it
does not carry, or gz init registers a slug an adopter cannot resolve and
gz chores doctor reports it MISSING. The property must be DECLARED, not
inferred: _classify_doctor_slug derives its PROJECT-LOCAL label from absence
from the wheel, which is the state sync itself overwrites.
The gz validate --distribution validator consults the per-surface
classifiers (_classify_<surface>_file helpers) to exempt package_only
files from ON_DISK_NOT_INCLUDED errors; sync_pkg_surfaces consults them
to skip non-canonical files when propagating .gzkit/ → src/gzkit/.
Lifted 2026-08-29 at version 0.11.0 (rule now at 0.12.0).
Rule version:
0.11.0— GHI #728: adds the chores-onlyproject_localcontent class and the declaration protocol..gzkit/chores/AGENTS.mddeclared project-local-only slugs as a real category (REQ-0.0.21-09-06) but nothing implemented it, so a chore authored only under.gzkit/chores/was copied into the wheel by sync and scaffolded into every adopter bygz init. The property is now DECLARED inregistry.jsonrather than inferred from absence — the inferencegz chores doctorused is the exact state sync overwrites. Prior0.10.1— diet pass (operator ruling 2026-08-02): lifted bootstrap-semantics narrative, retirement-policy rationale, and the class-classifier reference tables todocs/governance/skill-surface-sync-rationale.md; every non-negotiable rule and binding core retained verbatim. Prior0.10.0— namesmetadata.skill-versionas the canonical spelling and records that presence is now enforced. Rule #2 said only "skill-version:in YAML frontmatter (validated by the skill schema)", which was true of neither half: no skill schema exists, the audit checked format when present and never presence, and the unstated nesting let two spellings coexist — 57 skills nested undermetadata:, 11 at top level, where both validators were blind to them. The rule's own conflict-resolution procedure names the version as "the primary signal", so the drift disarmed the procedure the same rule prescribes. Prior0.9.0— renamed prohibited headings; lifted Rationale to expansion doc (OBPI-0.0.54-04 shape conformance pass).
tests.md¶
Changed 2026-09-25 at version 0.26.6¶
The operator's Magna Carta hierarchy amendment separates durable catalog requirements from bounded work assignments. § TASK-Driven Workflow now distinguishes that authority from the current brief-local REQ/TASK identifier and proof lineage. Task trailers, REQ kinds, proof channels, TDD, BDD, coverage and human acceptance obligations remain in force. Catalog runtime and identifier migration are not implemented by this wording change.
Changed 2026-09-23 at version 0.26.5 (GHI #1088)¶
Plain gz check became the per-change gate (the change scope, without
Behave or Preflight) and records the reuse fingerprint; gz check --full is
the full sweep, and CI runs it. § Two runners states the new scopes. 0.26.4,
the same day, had described the old ones: a full default sweep and a prepush
scope that dropped Behave but could not record.
Clarified 2026-09-23 at version 0.26.4¶
§ Two runners said "Both tiers must pass for gz check", which read as
binding behave to every change after the Gate Covenant bound it to the
heavy lane (commit 45e82992b). The sentence now names the scopes as
data/check_step_scopes.json declares them: the full sweep and CI run both
tiers, the pre-push and --fast scopes drop Behave. No runner, scope or
obligation changed.
Clarified 2026-09-19 at version 0.26.3 (GHI #1047)¶
The empty smoke-tier claim now states the opt-in boundary established by GHI
724 and ce234a0fb: absent/false smoke.required gives advisory success; true¶
gives a policy breach. No runtime policy or budget changed. Version 0.26.2
had clarified the default unit-only behavior and explicit BDD selector under
GHI #1042; those obligations remain unchanged.
Lifted 2026-09-17 at version 0.25.0 (rule now at 0.26.0)¶
Diet pass under GHI #921 (operator: "A" on the full before/after, 24,015 B → 10,551 B). Binding rules unchanged; measured instances, histories and the mutation-sweep example moved to Tests — Rationale. The 0.25.0 note, verbatim:
Rule version:
0.25.0— GHI #1008 reads a( … )or{ …; }group as ONE command in § Verification exit-code integrity: a grouped verifier is masked or escaped on the same terms as a bare one, with shell state and errexit scoped the way the shell scopes them. Prior versions lifted to Rule Version History. Binding rules unchanged except as stated.
Lifted 2026-08-29 at version 0.18.0 (rule now at 0.19.0).
Rule version:
0.18.0— GHI #856: refreshes § Full unit tier's measured figures and scopes the parallelism sentence to the budget it governs. The old figures (268.1s / 7497 tests serial, 71.4s across 32 processes) dated from0.13.0and were two generations stale on both halves — re-measured 2026-08-27 at2c81cb7don a 10-core host: 144.23s serial and 41.34s parallel over 8,912 tests. Worse than stale, the sentence "parallelism does not rescue it" was routinely read as a general ruling against parallel execution, which it never was: it justifies why the 60s smoke budget belongs to a subset, and says nothing about attestation. That misreading is now load-bearing in the other direction —CANONICAL_STEP_COMMANDS["unittest"]runsunittest-parallelas of the same GHI, so a rule read as forbidding parallelism would contradict the canonical "Tests pass" invocation. Figures are restated as a DATED RECORD per.claude/rules/governance-core.md§ Non-negotiable rules (a value in a Markdown doc is illustrative, never authoritative); the enforced budget staysuv run gz smoke. No binding rule changed. Prior0.17.0— operator ruling 2026-08-11: settles the repo-wide[kind]tag case. Both readers have always beenre.IGNORECASE, so the split was never a correctness defect — but three documenting surfaces disagreed and one contradicted itself:docs/governance/req-scope-discipline.mdgave lowercase at § The invariant and UPPERCASE at § Tag syntax, so an agent consulting the canonical expansion got both answers from one document and the question recurred per brief. Case-insensitivity is now stated where it binds, UPPERCASE is named as the authored form (597 of 967 tags, thegz-obpi-specifyauthoring skill, and AGENTS.md prose all already use it), and the 370 lowercase tags across 55 briefs are declared correct and explicitly out of scope for rewriting — a ~970-tag sweep for zero mechanical gain is what DO IT RIGHT #11 forbids. No binding rule changed; a question that had no authority now has one. Prior0.16.0— GHI #567 Move 2(b): adds the horizontal-slicing prohibition to § Red-Green-Refactor. The section already prescribed the vertical rhythm ("One test → one observed RED → …") but never named the shape that violates it, so the most common real-world deviation — author every test for a brief, then every implementation — had no name in the rule an agent could be held to. Articulates WHY the batch shape fails rather than only that it does: assertions written against an implementation you are about to write record intent rather than REQ semantics, and a RED arriving with ten other REDs is not evidence about any one of them. Framed as § The discriminator applied at authoring time, so the two clauses reinforce rather than restate. Advisory, and no mechanical witness is planned — authoring order leaves no artifact to inspect, and the RED witness that could prove it (gz arb red) is per-REQ by construction. Adopted from Matt Pocock'stddskill via the external-catalog alignment scan. Prior0.15.0— Movement C family closure, rules arm: § Eval-awareness corollary and § Output-form fixture carve-out now state their advisory posture in their own text, and are re-scoredJudgmentatdocs/governance/advisory-rules-audit.mdrows 71 and 69. Both had sat in the forbidden third state — a discipline declared with no mechanical witness and no statement that none is coming — which is the family GHI #537 named. Neither is being demoted for convenience: the corollary's promotion path (a name-shape scan overtests/**) was scored tractable for months and never built because nothing has been observed for it to catch, and the carve-out's path ("flip thegz test-shapearm closed once the declared-marker backlog drains") would fail-close the whole legacy corpus at once, which is why the arm was left open. Under the scorecard's § Recommended promotion order freeze (2026-06-08, opt-in-with-justification) a backlog draining is not the observed-drift evidence a new fail-closed check requires. Re-scoring without this text edit would have been laundering (operator ruling 2026-08-08). Prior0.14.0— GHI #589: § Verification exit-code integrity is now MECHANICAL, not prose. It had been binding since0.8.0and enforced by nothing — scored Promotable, unenforced atdocs/governance/advisory-rules-audit.mdrow 66, and the highest-frequency observed violation class in agent sessions, whose failure mode is a confident false green that then gets relayed as attestation evidence. Theverifier-pipe-gate.pyPreToolUse hook overBashnow refuses a verifier in any non-final pipeline stage;set -o pipefailand${PIPESTATUS[0]}opt out. Scoped by predicate rather than by the clause's named filters: the shell reports the last stage's exit whatever that stage is, so atail|head|grepallowlist would have wavedgz check | catthrough — the enumerate-the-examples miss this codebase has now made three times on the resume gate's own allowlist. Prior0.13.0— GHI #724: the 60s ceiling now names the suite it governs, and that suite exists. It bound a "Smoke/BVT" tier — subset language for a subset that was never built — so it was read against the full unit tier and breached 4.5x (268.1s / 7497 tests) with no consumer reading the number. Adds § Smoke tier membership, declares the full tier explicitly unbounded (its runtime ratchets with the REQ set by design, so a constant ceiling over it can only be breached), and points the budget atuv run gz smoke, which fails closed on breach AND on an empty tier — an empty subset satisfies any budget trivially. Parallelism is ruled out by measurement, not preference: 71.4s across 32 processes is still over. Prior0.12.0— GHI #538: pins the STRUCTURAL-FENCE proof-channel matrix row to the explicit OBPI-combination anchor token(OBPI-NN[, OBPI-MM, …]), making the parent-ADR## Boundary Invariantsbinding mechanical rather than heading-presence-only. The row previously said only "Parent-ADR## Boundary Invariantsentry", which the resolver read as heading presence — a fence REQ passed while no invariant named its OBPI, so the proof could not say which invariant proved which fence. Syntax detail lives indocs/governance/req-scope-discipline.md§ STRUCTURAL-FENCE; enforced byresolve_fence_proof. Prior0.11.0— GHI #571: lifts the operational discriminator into the hot-path rule rather than adding more prose. § 6f ("tests assert semantics, not strings") was slogan-shaped: memorable, with no test an agent could apply — the discriminating question lived only indocs/governance/req-scope-discipline.md. Adds § Unit-test purpose, § The discriminator (if behavior changed but text did not, would this test fail?), § Prefer structured assertion targets, the enumerated no-pytest forms, and the# output-contract:marker convention thatgz test-shapereads. Extends the non-BEHAVIOR@coversprohibition to STRUCTURAL-FENCE (it previously named SUPPORT alone). Reconciles § RED evidence with thearb-red-*witness schema (GHI #642). Prior0.10.0— GHI #647: the SUPPORT proof channel's ledger arm is now path-specific. A bare event of the cited type no longer proves; an event must cite the path, or forartifact_edited(content authorship, never emitted for source.pyfiles) the cited artifact must exist on disk. Closes the hollow gate where 4295 unrelatedartifact_editedevents satisfied any SUPPORT proof. 81 pre-cutover REQs snapshotted indata/support_proof_grandfather.json(shrink-only, waiver-ratchet-registered); 62 drained by the artifact-existence proof, 19 tolerated asgrandfathered-support. Prior0.9.0— § Behave scenario tagging is now REQ-kind-aware (GHI #636): only BEHAVIOR REQs can require behave, and a BEHAVIOR REQ is satisfied by a scenario tag OR an@coversunit test; SUPPORT / STRUCTURAL-FENCE REQs are exempt by proof channel. This drains the deadlock where the gate demanded abehave_coverage_waivers.jsonentry that ADR-0.0.73's shrink-only waiver-ratchet forbids growing. Prior0.8.0— added § Verification exit-code integrity (GHI #589): never pipe a verifier throughtail/head/grep; the shell reports the filter's exit, not the verifier's — read the ARB receiptexit_status. Prior0.7.0— producer reconciled to GHI #552:gz git-syncnow stampsTask: TASK-gz-git-sync(previously onlyCeremony:, which #552 stopped accepting on src/tests scope — leaving every sync commit silently non-compliant), and the direct-fix slug's-#<ghi>anchor is now OPTIONAL (operator moratorium on reflexive GHI-filing, 2026-06-01). Prior0.6.0: GHI #552 strict-mode — src/tests commits MUST carryTask:;Ceremony:/Eval-feedback-source:no longer substitute. Surfaces TASK as the leaf vertebra of the PRD → Constitution → ADR → OBPI → REQ → TASK → Attestation governance spine (per AGENTS.md § Workflow).
Lifted 2026-09-14 at version 0.23.0 (rule now at 0.24.0).
Rule version:
0.23.0— GHI #977 adds § Isolation Git fixture isolation: everygita test spawns passesenv=_isolated_git_env(), git's own repo-local variable set (local_repo_env) scrubbed at the fixture boundary. Measured 2026-09-07: a push from a linked worktree ran the pre-pushgz check, the fixtures inherited the hook's absoluteGIT_DIR, andgit initin a temp dir re-initialised the hosting repository as bare whilegit configwrote the fixture identity into its shared config. MECHANICAL from the first landing —tests/commands/test_common_fixtures.py::TestEveryGitSpawnIsInsideTheBoundaryfences every literalgitargv undertests/**. Prior0.22.0— GHI #970 extends § Verification exit-code integrity to the||BRANCH: the branch announces a failure in output and replaces it in status, and the gate had honoured the announcement as if it were the report. Names the branch-local remedy (set -eis suppressed left of||), and tracks the two limits it declares rather than closes — the aggregate status (GHI #969) and the caught&&chain (GHI #971). Prior0.21.0— GHI #940 extends § Verification exit-code integrity to the SEQUENCE form: the clause was scoped to the pipe character while the shell reports the last statement just as it reports the last stage, soverifier > log; tail logread as compliant. Names the two non-interchangeable remedies (pipefailfor a pipe,set -efor a sequence), the immediacy requirement on a$?read, and — declared rather than hidden — that the aggregate status is a floor a shell-level rule cannot lift. Prior0.20.0— adds § Mutation-sweep integrity (GHI #963): a failing mutant run is not a kill, sweeps report four outcomes, and every mutant runs with its own bytecode cache. Prior0.19.0diet pass under GHI #921 (operator ruling 2026-08-29, "we are compressing everything and anything that the agent can consume"). Version history lifted to Rule Version History. Binding rules unchanged.
Lifted 2026-09-15 at version 0.24.0 (rule now at 0.25.0).
Rule version:
0.24.0— GHI #971 closes the caught&&chain in § Verification exit-code integrity: what reports the status is the separator ENDING the verifier's AND-OR list, never its own terminator, and the gate now reads it — and a$?read after&(the background launch's status) no longer counts as an escape. Prior versions lifted to Rule Version History. Binding rules unchanged except as stated.
token-block-discipline.md¶
Lifted 2026-09-24 at version 0.8.0 (rule now at 0.9.0)¶
The three-subjects ruling was carried into the rule (GHI #1091). Lifted verbatim as a dated record:
Rule version:
0.8.0— diet pass under GHI #921: the landed-staging notes (OBPI-0.0.41-02/-03/-04), the blocklist-to-default-DENY history and the pre-GHI #764 section-misfiling record lifted to Rule Version History; the staleGenerated by OBPI-0.0.41-01 — do not editmarker removed (the rule has been edited seven times since). Binding rules unchanged.
Lifted 2026-09-17 at version 0.7.0 (rule now at 0.8.0)¶
Diet pass under GHI #921 (operator: "A" on the full before/after, 14,118 B → 7,049 B). Binding rules unchanged. Lifted verbatim as dated records — the 0.7.0 note, the landed staging notes and the two histories:
Rule version:
0.7.0— diet pass under GHI #921 (operator ruling 2026-08-29, "we are compressing everything and anything that the agent can consume"). Version history lifted to Rule Version History. Binding rules unchanged.
Staging: OBPI-0.0.41-02 implements this as a warning-only precondition ("you're releasing without a register entry; this will become fail-closed in 0.0.41-03"). OBPI-0.0.41-03 flips to fail-closed enforcement.
Attestation Language: When OBPI-0.0.41-03 implements this rule, the reaping agent's ledger entry MUST include: "Reaped lock for OBPI-<id> (agent: <A>, TTL exceeded at <timestamp>); created abandoned_by_reaper register entry at <path> before release." The register entry path is proof the handoff was created; the ledger entry is the agent's attestation that it was created before the reap.
The predicate is default-DENY (GHI #763). is_exchange_register_entry admits a document only when it carries the shape an exchange writer actually emits — mode: CREATE and not abandoned — so CHECKPOINT, RESUME, and any mode invented later are refused without being enumerated. This inverts the earlier blocklist, which admitted by default and subtracted known-bad shapes one reactive commit at a time (abandoned, then CHECKPOINT under GHI #756); each exclusion could only be written after the harm it prevented. Location is the first fence — session documents no longer enter .gzkit/locks/exchange/ at all — and this predicate is the second. gz validate --lock-exchange-coupling remains the ledger-replay backstop for a release whose handoff_path was resolved by any other route, and for historical events still citing .gzkit/handoffs/.
Anti-pattern: placing content in the section it fits rather than the section it belongs to. The implementation summary is retrospective and filing it under ## Pending Work / Open Loops — as the writer did for all 33 records before GHI #764 — describes finished work as pending. A section that emits byte-identical text across every record is not a low-value section; it is a section with no channel.
Lifted 2026-08-29 at version 0.6.0 (rule now at 0.7.0).
Rule version:
0.6.0— GHI #764: adds § Binding Sub-Invariant 7 (the exchange record carries an observation report). The record is two things by operator canon — the fact of block vacation AND an observation report of what happened during possession — and only the first half was implemented: the completion writer had three content inlets for seven sections, so four sections emitted boilerplate byte-identical across all 33 records on disk, and those four are the observation report's own subject matter. The implementation summary was also filed under## Pending Work / Open Loops, a prospective heading for retrospective content. Inlets are OPTIONAL and sourced from the brief, so GHI #619's input-free floor is unchanged. Prior0.5.0— GHI #763: the token block's register entry is an exchange record, named and stored as one. It lived in.gzkit/handoffs/under session-handoff identifiers, so system membership had to be inferred from a shared word, path, and directory rather than read from a discriminator — and was inferred wrongly twice in one session. Records now live in.gzkit/locks/exchange/(location types membership), the writers/finder areexchange-named ingzkit.exchange_records, and--lock-handoff-couplingsurvives as a deprecated alias of--lock-exchange-coupling. § Sub-Invariant 5's predicate is now default-deny: it admits only the shape an exchange writer emits, so a document kind nobody admitted is refused without having to be enumerated first. The ledger payload keyhandoff_pathis FROZEN on the wire — 204 append-only events carry it. Prior0.4.0— GHI #756: § Binding Sub-Invariant 5 now namesmode: CHECKPOINTas a third disqualifier alongsideabandoned: true.modewasLiteral["CREATE", "RESUME"]andfind_exchange_for_releasenever read it, so once the mid-flight bookmark mode existed, a bookmark postdating the claim would have satisfied the release precondition — a token surrendered on the evidence of a session that never departed. The predicate now skips checkpoints at the live gate andgz validate --lock-exchange-couplingbackstops it on ledger replay. Prior0.3.1— diet pass (operator ruling 2026-08-02): lifted § Vocabulary, § Cross-Links, and § Audit Path todocs/governance/token-block-doctrine.md(correcting the retired "5:1 governance ratio" citation in transit); binding sub-invariants unchanged. Prior0.3.0— added § Binding Sub-Invariant 6 (completion surrender is mechanical):gz obpi complete(and thegz obpi pipelinesync stage that invokes it) writes the register-entry handoff and releases any held lock automatically (GHI #619), so the token's exit edge no longer requires an operator-authored handoff or a manualgz obpi lock release. This does NOT relax Sub-Invariant 5 — completion produces the register entry mechanically rather than demanding the operator author one; the fail-closed manual release path is unchanged for mid-traversal surrender. Prior0.2.0— Sub-Invariant 2 minimum-information channels are now named per-field: items 1/2/4 are frontmatter keys, item 3 is the## Decisions Madebody section. Resolves the rule↔validator↔producer drift where the prose said "frontmatter or body" but bothgz validate --lock-exchange-couplingand the machine-generated reaping handoff already use frontmatter. Prior0.1.1— trimmed railway-history pedagogy while preserving all lock-release and handoff invariants.
tool-skill-runbook-alignment.md¶
Lifted 2026-09-17 at version 0.5.0 (rule now at 0.5.1)¶
Patch: the pointer to governance-core.md § Operator-doc verb resolution now names AGENTS.md § Governance doctrine surfaces, the clause's home since the rule was folded into the root contract (GHI #921). No other change.
Lifted 2026-08-29 at version 0.4.0 (rule now at 0.5.0).
Rule version:
0.4.0— § When to apply — Authoring a new CLI verb now names the wielding skill as one of seven obligations and points at.gzkit/rules/cli.md§ Adding CLI Features — New Subcommand as the authority, instead of reading as the whole requirement. Measured 2026-08-22: the new-verb obligation set was described in three places and no two agreed — this row named 1 obligation,cli.md§ Consistency named 3, andcli.md§ New Subcommand named 4, against 7 that fail closed. An author who found this row first shipped a skill and nothing else. This is GHI #787's class recurring on a second surface: a point-of-use coupling checklist that undercounts its own obligations, discovered by the slowest gate rather than the cheapest. One authority, others point at it. Prior0.3.0— Movement C family closure, rules arm: adds § Enforcement posture, which states in the rule's own text that Invariant 1 is mechanical while Invariants 2 and 3 are advisory by design. The scorecard carried rows 29 and 30 as Promotable for months on the premise that the skill→runbook cross-reference and output-form fixtures were merely unbuilt. They are not merely unbuilt: both invariants turn on "the same operator moment", and no repository surface represents an operator moment as a comparable object — the runbook prescribes verbs in prose, so a checker would have to score the agreement of two prose surfaces, which is grading by shape. The section also names the mechanical witness that DOES exist nearby (gz validate --cli-alignment, which catches the renamed-verb half of Invariant 2) so the advisory scope is the residue, not the whole. Re-scoredJudgmentatdocs/governance/advisory-rules-audit.mdrows 29 and 30; re-scoring without this text edit would have been laundering (operator ruling 2026-08-08). Prior0.2.0— lifted pedagogy, canonical violations, and enforcement details to rationale doc under GHI #327.
brief-heading-conventions.md¶
Lifted 2026-08-30 at version 0.1.0 (rule now at 0.2.0).
Rule version:
0.1.0— adds the body-level version marker required byskill-surface-sync.md§ Non-negotiable rules #2, which this file never carried (Pass A run 2026-07-16 marker sweep). Content unchanged; no conflict row was raised against this rule.
changelog-release-notes.md¶
Lifted 2026-08-30 at version 1.1.0 (rule now at 1.2.0).
Rule version:
1.1.0— the hermeticgz validate --changelogstructural scope landed; corrected the release-notes enforcement wording (no mechanical release-notes validator exists) (GHI #685).
complexity-doctrine.md¶
Lifted 2026-08-30 at version 0.3.1 (rule now at 0.4.0).
Rule version:
0.3.1— renamed prohibited## Corpus Anti-Patternsheading →## Corpus Disqualifiers(OBPI-0.0.54-04 shape conformance pass).
complexity-thresholds.md¶
Lifted 2026-08-30 at version 0.4.0 (rule now at 0.5.0).
Rule version:
0.4.0— GHI #469: corrected> See [...]pointer paths from file-relative../../docs/...to repo-root-relativedocs/...sogz validate --pointer-anchorsresolves them correctly (ADR-0.0.33 Invariant 3).
models.md¶
Lifted 2026-08-30 at version 0.1.0 (rule now at 0.2.0).
Rule version:
0.1.0— initial shape conformance pass; renamed prohibited heading (OBPI-0.0.54-04).