Skip to content

gzkit — Big-Picture Assessment

Date: 2026-09-20 · Report: second in the big-picture series Evidence cutoff: 2026-09-20, main at 0ea44b2ea, working tree clean Comparison point: the baseline report of 2026-09-19

Read this first. The baseline published 25 hours before this one. Almost no trend has moved in that window, and this report is not a trend update. It is a re-cut at substantially the same evidence position, covering what the baseline under-covered: what gzkit is, what it does, and which of its mechanisms actually engage. Where a figure is unchanged from the baseline, that is because a day passed, not because it was re-confirmed as stable. Condition material here is deliberately compact and defers to the baseline rather than re-arguing it.


The assessment

The baseline answered "how is this project faring" and left "what is this project" to a mechanism table and a release list. That was the wrong proportion for a report meant to show the forest, and this one corrects it.

What the correction reveals is that gzkit is a substantially larger and more coherent built system than the baseline conveyed — 61 CLI verbs, 97 registered validator scopes, a 240-file distribution contract enforced in both directions, and a two-vocabulary layer model that is genuinely load-bearing rather than decorative. The baseline said "the architecture is coherent." Having now read it rather than summarised it, the stronger claim holds: the design is unusually well-specified, and its documents are honest about their own gaps in ways most project documentation is not.

It also reveals a fault line the baseline caught one instance of and treated as an anecdote. The airlock's empty seam-map is not a one-off. It is one of at least four mechanisms that are built, tested, registered, and structurally unable to do their job because nothing populates their input. The recurring shape is precise enough to name: a declared-but-unwired parameter with a permissive default. A default of (), 0, None or lambda: [] keeps every signature valid, every type check green and every test passing, while making the mechanism vacuous. gzkit's witnesses ask whether a mechanism is present. None of them asks whether its input is ever non-empty.

That is the finding. It is narrower and more actionable than the baseline's "defect-absorption equilibrium," and it sits underneath it.


What gzkit is

gzkit is a governance meta-harness. The boundary is stated precisely in the README and it is the first thing to understand about the product:

"It does not run agents: a vendor harness turns a model into an agent, and gzkit operates one tier up, wrapping agent harnesses such as Codex, Claude Code, Copilot, and adjacent tools with deterministic governance surfaces, evidence capture, gate enforcement, and human attestation."

The problem it exists for is stated in the PRD, and it is a problem about the human rather than the agent:

"AI-assisted development creates a drift problem: humans approve work they didn't verify, attest to artifacts they didn't read, and gradually become rubber stamps for agent-generated output. Existing tools either ignore governance entirely or bury it in ceremony that agents route around."

"gzkit exists to keep the human at index zero — first in priority, final in authority."

The organising metaphor is constitutional: humans are the Legislature (intent, constraints, final judgment), agents the Executive (execution within bounds, evidence generation), tests and BDD the Judiciary (verification). Three concerns compose it, with a stated dependency: "Specification without governance drifts. Governance without methodology is theater. Methodology without specification is arbitrary."

The design record is candid about the cost, which is rarer than the claim itself. The rendering-substrate doctrine says of its own weight: "the substrate is heavier than direct hand-authoring; that weight is the product, not overhead." And it is honest about the limits of its reach: "The substrate's resilience is exactly that it does not depend on runtime control of the vendor harness. Composition happens between turns; rendering happens before the agent loads; loading is the vendor harness's call."


What it does

This is the section the baseline lacked. A reader should be able to finish it able to say what a user actually gets.

The command surface

61 top-level verbs, each with a uniform exit-code contract (0 success, 1 user/config error, 2 usage or IO, 3 policy breach). Grouped by what they are for — the grouping is mine; the CLI prints one flat list:

Family Verbs What the operator does with it
Adoption 2 init scaffolds governance into a project; upgrade refreshes surfaces from the wheel
Governance spine 13 Author and move artifacts along prd → constitute → plan → specify → obpi → task
Verification & evidence 17 check, test, validate, gates, covers, arb — run the gates and emit receipts
Derived views 10 status, state, report, ontology — read what happened without changing it
Content & control surfaces 6 content, agent, skill, personas — author canon and regenerate mirrors
Operations 13 mx, airlock, chores, git-sync, handoff, insights, issue

The verbs that carry the most weight for a working operator: gz check runs a 62-step quality sequence; gz obpi complete atomically validates, writes evidence, flips status and emits a receipt; gz arb wraps QA commands and emits schema-validated JSON receipts that are the canonical attestation evidence; gz content compose and gz content commit stage and land control-surface renditions under attestation; gz agent sync control-surfaces regenerates every vendor mirror from canon in one invocation.

What an adopter receives

pip install py-gzkit && gz init delivers a frozen 240-file distribution contract across five canonical surface kinds:

Surface Files delivered
Chores 125 (across 39 chore slugs)
Skills 70
Rules 26
Templates 12
Personas 7
Total 240

It is enforced in both directions — three declared drift classes (ON_DISK_NOT_INCLUDED, BASELINE_NOT_ON_DISK, ON_DISK_NOT_BASELINE) — and the trust doctrine explains why this sits upstream of everything else: "if a canonical surface only exists in this repo's .gzkit/ and never ships, then T1 (canon-as-truth) is silently project-specific instead of project-portable." The sharpest statement of the obligation: "a wheel that ships without a canonical surface is a T0 breach, regardless of whether downstream gz init reports success."

This repository's own working set is larger than what it ships: 72 skills, 25 rules, 40 registered chores, 7 personas, 12 templates. The two extra skills are declared project_local and are absent from the wheel deliberately.

The verification surface

10,541 unit tests pass in 91.5 seconds. gz check runs 62 steps and exits 0. There are 97 registered validator scopes, 65.8% REQ coverage (1,794 of 2,728), 467 BDD scenarios, and 16,973 ledger events across 67 event types. The chore registry carries 40 entries, each declaring a class and a rung — 26 conformance, 5 coherence, 4 mining, 3 curation, 2 currency; 18 authorised to repair, 16 to propose, 6 operator-only.


How the parts compose

gzkit uses two orthogonal layer vocabularies, and keeping them distinct is the single most important structural fact about the system.

Storage tiers (L1/L2/L3) answer which layer wins?

Authority Rule
L1 Canon "Defines what should exist" Git-versioned markdown and YAML
L2 Ledger "Defines what has happened — the runtime truth" Append-only JSONL; lines never edited or deleted
L3 Derived "Defines what is convenient … never the source of truth" Rebuildable; delete it all and it reconstructs

Precedence is explicit: L2 > L1 > L3. Frontmatter is "a lazy mirror" and is never read as source-of-truth for completion. L3 "cannot block gates."

Trust tiers (T0–T3) answer a different question the storage model does not cover — how does each layer verify that the layer below produced what it assumes? The trust doctrine names the failure class and is worth quoting because it is the intellectual core of the project:

"Trust-chain poisoning. When Layer A's output feeds Layer B's decision, and A is silently wrong, B's decision looks correct… Each layer is individually correct. The composition is wrong because no layer independently tests that its inputs are what it assumes."

"Trust-chain poisoning is not a bug. It is a class of bug."

T1/T2/T3 map onto L1/L2/L3; T0 (distribution) is the addition and sits upstream of all of them.

The control-surface substrate is a four-stage pipeline — corpus → setpoint-compression → committed rendition → deterministic playback — whose terminal guarantee is "no LLM, no template substitution, no network. Identical committed rendition → byte-identical surface on every call." The corpus behind this repository's own AGENTS.md holds 367 entries tiered 232 invariant / 135 compressible; invariant entries are emitted verbatim at every setpoint and are never dropped or rewritten. That 0-Kelvin floor is a populated data field, not an aspiration.

Code architecture is ports-and-adapters, stdlib-first, with Pydantic as the one ratified exception. The rule is unusually specific about what it does not mean: "Domain cohesion lives in the type system, not the folder tree… core/ stays; do NOT add domain/application/adapters/contexts folder partitions to 'do DDD.'" The one place this is testable holds: networkx is imported in exactly one module, behind a port returning set[str] rather than a library type.


The claim each mechanism makes

Design choices carry claims. These are the load-bearing ones, each stated as what it makes impossible or replaces:

Mechanism The claim Status
Append-only ledger Runtime truth is witnessed, not asserted; frontmatter cannot certify completion Engages — 16,973 events, correction is a forward netting operation, never an edit
ADR → OBPI → REQ Work decomposed until completion is provable; no untyped acceptance criterion Engages — every REQ declares BEHAVIOR / SUPPORT / STRUCTURAL-FENCE with one proof channel
Five gates Verification staged and non-skippable; "a file or marker being present shows only that something is armed" Partial — lane→gate mapping is data, not code; but no ADR has reached closeout since 2026-07-31
Human attestation Cannot be automated or bypassed, in any lane, kind or sensitivity Engages hardest — see below
Corpus → rendition A hand-edited control surface is the same failure class as a hand-written ledger row Engages — playback is byte-identical; drift fail-closes
Airlock An un-declared seam makes GO structurally unreachable Vacuous — see below
ARB receipts Replaces agent narrative with wrapped-command receipts Engages — 659 + 466 + 235 receipt events
Chore system A chore is authorised to find, analyse, solve and fix on a cadence Newly mechanised — 40 chores now carry declared class and rung

Which mechanisms engage

This is the question the baseline asked once, about the airlock, and did not generalise. Generalised, it sorts gzkit's mechanisms into three states.

Engages hardest: attestation, and the hooks

The universality of Gate 5 is not merely documented — the branch that could waive it was deleted, and the function that would have decided it is now a constant:

Python
def _requires_human_obpi_attestation(parent_adr, parent_lane, brief_frontmatter=None) -> bool:
    """...human attestation is UNIVERSAL... The foundation/lane/security branching
    logic has been collapsed. The signature is preserved for call-site
    compatibility; all three parameters are accepted but not evaluated."""
    return True

Three parameters kept so call sites compile, all three ignored. A runtime invariant check asserts it. This is the opposite of the vacuity pattern: the permissive branch was removed rather than defaulted.

The hooks engage with equal force, and I can testify to it directly: five times during the production of this report a project hook refused one of my own shell commands, named the binding rule, quoted it, and printed the corrected command. Four of the five were the verification exit-code integrity gate catching me piping a verifier into a filter, which would have reported the filter's exit status instead of the verifier's. That is enforcement observed rather than asserted.

Of 76 trust-audit modules, 63 can raise a blocking ValidationError; 9 carry an advisory arm. The majority genuinely fail closed.

Vacuous: built, tested, and structurally unable to fire

The airlock. Of 71 transits, all 53 proceed decisions computed an empty seam-map and all 18 holds a non-empty one. The correlation is total because the decision function returns proceed exactly when the seam-map is falsy — so the mechanism has never once evaluated a populated map and chosen to proceed. The cause is wiring: parent_invariants is declared with default () and is passed by no caller in src/ — only by tests. Two further parameters on the same function, blast_radius: int = 0 and override: CaptainOverride | None = None, are likewise passed by nothing, so one authority branch is dead in production. Two call sites compute reach as a literal lambda _node: []. And the airlock ships diagnostic-only by design — "surfaced drift prints findings but still exits 0 — it reports, it never blocks."

Rendition lineage. The grading gate for control-surface provenance reports 0 of 22 sections owned, 0 of 19,872 bytes (0.0%), with 20 sections ungraded because the lineage artifact does not exist — and exits 0. To the validator's enormous credit it refuses to launder this: it says outright that counting those sections as owned "would claim proof this gate does not have," and forbids lowering the declaration to clear the gate. The gate is well-built. Its input is empty.

Validator reach. Bare gz validate runs 15 of 97 scopes; 82 are flag-gated. The project's own reachability chore classifies 51 of 99 runnable scopes as ungated — 27 invoked only by tests, 23 only by documentation, 1 by nothing at all.

Declared vocabulary. The ledger declares 77 event types; 10 have never fired.

The correction this report had to make about itself

An evidence pass for this report concluded that Gate 5 had lapsed — no attested event since 2026-07-31 against subsequent OBPI completions. Checked directly, that is false. attested is an ADR-closeout event; OBPI attestation is recorded inside the completion receipt. All 7 completions since 2026-07-31 carry attestor: g0 and obpi_completion: attested_completed. Gate 5 held on every one.

The gap means only what the baseline already said: no ADR has reached closeout since 0.34.0. The near-miss is worth recording because it is the project's own named failure mode — a consumer reading a field without independently verifying what the producer means by it — arriving inside a report about that failure mode.


Condition, in proportion

The baseline's diagnosis stands and is not re-argued here. One day on, refreshed:

Baseline (09-19) Now (09-20)
Open issues 55 56 (52 labelled defect)
Closed issues 1,001 1,001 — median age 3.7 h; 71.2% within 24 h, 57.6% same calendar day
Commits since v0.34.7 453 460 — 198 fix, 188 chore, 52 docs, 9 feat
OBPI completions 659 659 — last 2026-09-12, 8 days ago; longest gap 21 days
Campaign boxes 7 of 25 7 of 25 — unchanged across all 20 commits to this edition since 2026-08-16
Insights entries 784 785

The one figure that moved materially is the issue queue, by one — this session filed none. The campaign measurement is worth stating precisely because it is stronger than the baseline's: the current edition was created on 2026-08-16 already carrying 7 checked boxes, and in the 35 days and 20 commits since, that count has never changed. The plan is being edited actively and completed not at all.


The central uncertainty

Unchanged: does this work for anyone not building it? Flight tests remain 0 of 6 sorties flown; rhea remains stopped at 0 completed OBPIs; all issues ever opened still have one author.

One thing the baseline left open can now be closed. It cited "574 downloads last month" alongside "9 stars, 0 forks" without reconciling them, leaving open whether the downloads were mirror traffic. They are not. The statistics API splits the two, and the figure the baseline quoted is the non-mirror one: over the 30 days to 2026-09-19, 560 non-mirror downloads against 3,896 with mirrors. So mirror traffic is roughly 7× and is reported separately.

This does not establish human adopters — non-mirror downloads include CI and container builds, and nothing here attributes a single install to a person. But the cheapest available explanation for the download figure is now ruled out, and any future month-over-month claim has to say which of the two series it is using.


What would move this assessment

Observations that would change the reading, in either direction. Not recommendations; work selection is the operator's.

Would strengthen it materially: one airlock transit computing a non-empty seam-map from a real parent_invariants set — converting the membrane from designed to operating. A committed lineage artifact moving rendition ownership off 0.0%. And, unchanged from the baseline and still outranking both: one completed governed unit of work in a repository that is not gzkit.

Would weaken it: a further quarter with ADR-0.36.0 and ADR-0.37.0 still at zero landed OBPIs; the ungated-validator count rising rather than falling; or a new mechanism shipping with the same unwired-default signature after this report names the pattern.

Untested either way: whether the covenant's central value claim — that this prevents an operator's slow slide into rubber-stamping — is true. No instrument in the repository measures it. That remains the hardest measurement in the project and the one nobody has solved.


In summary

Read as a built system rather than as a health chart, gzkit is more impressive than the baseline conveyed and its central weakness is more specific. The design is coherent, the documents are honest about their own gaps, the distribution contract is real, and the enforcement that does engage engages hard enough to refuse its own author five times in one session.

Against that, four mechanisms are built and unwired, and they share one signature: a declared parameter with a permissive default that nothing populates. The project's witnesses confirm that mechanisms exist. Nothing yet asks whether they ever fire on a non-empty input — which is why all four pass, and why the airlock could sit at 53-for-53 without any gate noticing.


Evidence appendix

All figures observed 2026-09-20 against main at 0ea44b2ea unless dated otherwise. Every figure this report's argument rests on was measured directly by the author before use; figures from delegated read-only passes were re-measured, and one was refuted (see § The correction).

Commands run

Observation Source
10,541 tests pass, 4 skipped, 91.5 s uv run gz test
62 checks, exit 0 uv run gz check
REQ coverage 1,794 / 2,728 = 65.8% uv run gz covers
61 top-level verbs uv run gz --help, subcommand list parsed
97 registered validator scopes; 15 default tier, 82 explicit VALIDATOR_REGISTRY in src/gzkit/commands/validate_cmd.py
51 of 99 runnable scopes ungated (27 test-only, 23 doc-only, 1 orphan) src/gzkit/chores/control-surface-validator-reachability/check_reachability.py --report
77 declared event types, 67 fired, 10 never src/gzkit/chores/ledger-vocabulary-inertness/check_ledger_inertness.py --report
240 distribution baseline files (125/70/26/12/7) data/distribution_baseline_manifest.json
72 skills, 25 rules, 40 chores, 7 personas, 12 templates on disk find/ls over .gzkit/<surface>
Rendition lineage 0/22 sections, 0.0% of 19,872 bytes uv run gz validate --rendition-lineage
Corpus 367 entries, 232 invariant / 135 compressible .gzkit/corpus/AGENTS.md.jsonl
Chore registry 40 entries; class and rung distributions .gzkit/chores/registry.json
560 non-mirror / 3,896 with-mirror downloads, 30 d to 2026-09-19 pypistats.org /overall

Ledger-derived (.gzkit/ledger.jsonl, 16,973 events, 67 types)

  • Airlock: 71 airlock_in, 29 airlock_out; 53 proceed / 18 hold. All 53 proceeds carry an empty unaccounted set; all 18 holds non-empty.
  • gate_checked 943 and attested 103 both last fired 2026-07-31, at ADR-0.34.0 closeout — 51 days.
  • OBPI completions (obpi_receipt_emitted, receipt_event: completed) 659. By month: Mar 306, Apr 109, May 134, Jun 74, Jul 28, Aug 3, Sep 4. Last 2026-09-12. Longest gap 21 days.
  • All 7 completions since 2026-07-31 carry attestor: g0 and obpi_completion: attested_completed.

Code read

src/gzkit/commands/adr_audit.py (attestation constant), src/gzkit/airlock/enter.py and exit.py (seam-map construction), src/gzkit/commands/permitted_entry.py and mx_cmd.py (reach defaults), src/gzkit/commands/validate_cmd.py (scope registry), src/gzkit/advisory.py, src/gzkit/reports.py.

Document sources

README.md; docs/design/prd/PRD-GZKIT-1.0.0.md (status Draft); docs/governance/state-doctrine.md; docs/governance/trust-doctrine.md; docs/governance/agent-control-surface-rendering-substrate.md; .gzkit/rules/hexagonal-architecture.md; docs/governance/chore-class-system.md; docs/governance/build-to-1.0-campaign-2026-08-16.md; docs/reports/big-picture/2026-09-19.md.

Material limitations

  1. This is not a trend report. It publishes 25 hours after the baseline. Every trend claim it makes is inherited from the baseline's measurement window, not established by the interval between them.
  2. The PRD is a Draft from 2026-01 and is superseded in at least three places — Gate 5 lane scoping (ADR-0.0.36 made it universal), the CLI framework, and command scope. It is cited here for its problem statement and origin only.
  3. The README's "all state lives in Markdown" is stale against the L2-authoritative ledger that the state doctrine defines. Noted, not repaired.
  4. "Vacuous" is a claim about input wiring, not about code quality. All four mechanisms named are well-constructed; three of them report their own gap honestly. The finding is that nothing detects the gap mechanically.
  5. The four-mechanism list is not exhaustive. It is what four evidence passes surfaced; the reachability and inertness chores suggest the population is larger.
  6. One delegated finding was refuted, not merely corrected. A claim that Gate 5 had lapsed was checked against the receipts and found false. Other delegated figures were re-measured and held, but the episode bounds how much weight any un-re-measured delegated figure should carry — so none is load-bearing here.
  7. Adopter evidence remains partly unobservable. Download counts cannot distinguish a person from a CI job, and no instrument here attributes an install to a human.