Skip to content

Release 0.9.4 — the gate judges the sources on disk - #259

Merged
qwerfunch merged 40 commits into
mainfrom
develop
Aug 26, 2026
Merged

Release 0.9.4 — the gate judges the sources on disk#259
qwerfunch merged 40 commits into
mainfrom
develop

Conversation

@qwerfunch

Copy link
Copy Markdown
Owner

2026-08-26 · develop → main · release 0.9.4

The language check reads your sources instead of your build manifest — projects it wrongly blocked now pass honestly — the module-honesty scan works for any language the spec teaches it, the gate config survives a fresh clone, and cladding proves its own host hooks fired.

Heads-up: merge with "Create a merge commit" — never squash, never rebase (a squash makes the next release PR report phantom conflicts). After merging: tag v0.9.4 on the merge commit, npm publish, gh release, then back-merge main → develop.

What ships (folded 0.9.4 — full text in CHANGELOG.md)

Evidence-based language check — the old comparison wrongly blocked 12 of 32 realistic shapes (measured); the new one blocks none, loses no drift catch, and on the motivating C++-under-Gradle shape an honest green went from impossible to 3/3, ~21% cheaper (blinded A/B, n=3, control NULL — docs/ab-evaluation/case-version-ab-093-vs-next.md).

Self-describing module-honesty scan — no more vacuous pass on cpp/java/csharp; declared layer globs are honored; an empty scan discloses itself.

Committable gate config.cladding/config.yaml finally survives a fresh clone; legacy projects get a doctor report, never a rewrite.

Runner-less skips name their exit — one line pointing at gate.commands when checks skipped for lack of a runner.

Live host-hook health, stop/completion telemetry, pinned generated CI, attestation policy identity, MCP SDK security refresh (the original 0.9.4 prep).

Verification

▸ Full suite 2981/2981 · conformance corpus 33/33 (Iron Law L4) · strict pre-push gate GREEN · CI green on every constituent PR (#253 #255 #256 #257 #258) · two external packed-tarball E2E campaigns · blinded version A/B with pre-registered claims boundaries.

🤖 Generated with Claude Code

qwerfunch and others added 30 commits August 10, 2026 00:33
Adds .refactor/ as the committed home for this program's plan and ledger:

- PLAN.md   — the loop-drivable work queue (§0-§7) plus the reasoning appendices
- REFACTOR.md — the 49-unit refactor program (verification commands, rollback,
  checkpoint record per unit)
- ledger.md — the durable state the loop reads to answer "what is done, what is
  next, am I mid-item". It lives here rather than under .cladding/ because that
  path is gitignored, and a ledger that does not survive a clone cannot be
  reviewed or recovered from.

Also completes queue item S1. The event log records 251 distinct commit heads
across stop_blocked and gate_run; 29 of 48 block heads and 129 of 247 gate heads
are not ancestors of develop (squash-merged feature branches), surviving only in
the reflog. The oldest events are 41 days old, past git's default 30-day
reflogExpireUnreachable, and loose objects sit at 4,824 against the 6,700 auto-gc
threshold. All 251 are now pinned under refs/replay/*, so a gc can no longer
make the replay evidence unauditable. Refs only — no history change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…SMATCH

Three divergent language tables meant clad init could seed a label the
detector layer then rejected under --strict — measured on realistic repo
shapes, the manifest-chain comparison blocked 12 of 19 normal projects
(Android C++ SDK under Gradle, Rust core shipped via npm, plain
JavaScript, C#, Scala). The vocabulary now lives once in
src/core/language-evidence.ts, and the detector judges the observed
source distribution instead of the build manifest: unknown language or
under 5 classified files → silence, declared absent → one warn naming
the evidence, minority under 10% → one non-blocking info.

A coverage-ratio rule is deliberately absent — red-teaming showed its
denominator list flipped failures between false-warn and missed-drift
depending on membership. detectToolchain is untouched: a build-host
label answers "what do we run", which stays the right question for
gate-command selection.

Verified: 22-test impl-blind oracle (authored from the contract only),
32-shape adversarial corpus vs an independent reference (0 mismatches,
0 blocked false positives, 0 missed drifts), strict blocking semantics
proven through the built CLI, full suite 2886/2886.

F-9e1279d4 · clad done under a GREEN strict pre-push gate

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The module-honesty check chose one extension from a six-language table;
declaring cpp, java, or csharp fell through to *.ts, scanned zero files,
and passed vacuously — verified by direct scanPatterns calls — on
exactly the projects the check exists for. The universe is now derived
from evidence: extensions observed in the tree that the shared
vocabulary knows, united with extensions of modules claimed under layer
roots, so an unknown language (.zig) enters the moment a feature claims
it, with no table growth. Scan roots are likewise inferred from claimed
module paths (src/main/kotlin comes out of inference), retiring both
EXT_BY_LANGUAGE and ROOT_BY_LANGUAGE; the detector no longer reads
spec.project.language at all.

Root inference alone would over-teach — layer names recur under tests/,
skills/, and plugins/, which measured 430 false findings on this
repository — so a root must carry at least 25% of layer-claimed modules.
The accepted trades (a sub-25% genuine root is not scanned; the share is
ratio-noisy at tiny claim counts) are recorded in the spec entry.

On this repo the new universe is 133 patterns / 201 files (was 19 / 190)
with zero new findings, and the A/B golden scenarios now catch their
injected rename drift through UNMAPPED_ARTIFACT as well — the .tsx
rename the old table could not see.

Verified: 9-test impl-blind oracle (contract-only), 22 unit tests,
adversarial root-filter attacks (collision drop at scale, 50/50
dual-root survival, documented 80/20 miss), full suite 2909/2909.

F-87bb7ed3 · clad done under a GREEN strict pre-push gate

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
clad init ignored .cladding/ with the directory form, and git never
re-includes under an excluded directory — so .cladding/config.yaml
(gate.scope, gate.commands, gate.coverage, gate.test_report) could not
be committed at all. Every documented gate override was local-only:
fresh clones and CI silently ran a different gate than the author
tuned, and --strict exists for CI. Found by a live host run during the
gate.language E2E, verified with git check-ignore.

Fresh projects now get the contents-exclusion pair (.cladding/* plus
!.cladding/config.yaml) rendered by a pure policy module. An existing
.gitignore carrying any recognized cladding entry — the legacy
directory form included — stays byte-identical; instead of rewriting
adopters' files, clad doctor reports a blocked gate config in text and
JSON, the same read-only posture as the unpinned-CI report. The dogfood
repo's own .gitignore moves to the pair form, and the onboarding
description no longer promises the directory form.

Verified: 23-test impl-blind oracle (contract-only, includes live
git check-ignore ground truth) passing on first contact with the
implementation, end-to-end harness through the built CLI (fresh init
committable, legacy adopter byte-identical + doctor blocked, new-form
quiet), full suite 2936/2936.

F-b0c2e724 · clad done under a GREEN strict pre-push gate — the gate
itself first refused this commit because the new policy module was
claimed by no feature: F-87bb7ed3's evidence universe caught its own
sibling's spec gap.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
gloryinka and others added 10 commits August 26, 2026 15:19
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…n says so

External E2E defect D1: the universe derivation matched layer NAMES as
path segments, so a layer named anything but a literal directory —
measured with 'native' declaring modules: ["core/src/main/cpp/**"] —
produced an empty universe and a silent pass, while the identical spec
named 'core' found 21 files. The schema has carried per-layer modules
globs all along; the detector ignored a declared surface.

A layer that declares globs now gets its universe from them (times the
evidenced extensions), bypassing name inference; bare layers keep the
existing derivation byte-for-byte, and root-dominance math is untouched.
When the active full scan matches nothing at all, one info finding names
the layers and roots it searched instead of reading as a clean pass —
causal control: HEAD's detector printed zero findings on both fixtures.

Also records the external E2E's remaining findings as backlog rows
B12-B15 (legacy fallback shape, init language seeding, per-detector
language resolution, post-init scaffold probe), and reconciles
F-a04cd9's "advisory, not consumed" prose with the new consumer.

Verified: oracle grown 9→14 blind cases (5 authored against the amended
contract before the implementation landed, then passing untouched),
34 unit tests, full suite 2953/2953, external E2E 7/7 PASS at c41ba2e.

F-87bb7ed3 (amended) · clad done under a GREEN strict pre-push gate

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…nce contract

The F-013 fixture encoded the manifest-chain comparison (one .ts file,
python declared, warn expected from the toolchain verdict). Under the
evidence model one classified file sits below the floor, so the fixture
went silent and CI's stage-contract corpus caught it — the corpus doing
its job on a semantics change. The fixture now clears the floor with
five observed sources, and F-013's criterion text plus the corpus
description state the current contract, with the evidence model owned
by the new spec entry.

Conformance corpus 33/33 matched, Iron Law L4, full suite 2953/2953.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The gate judges the sources on disk, not the build manifest
A project whose language cladding cannot drive passed the gate with six
of nine stages skipped and zero mention of the way out — measured across
every adopter-reachable surface, gate.commands appeared once, in a
CHANGELOG line, and the gate.language E2E already proved that exact
configuration strands a fully-capable agent. Skips were honest but mute.

Command-stage skips now carry a structured reason: 'no-runner' when no
runner is registered for the language, 'tool-missing' when the resolved
tool is absent — by-design skips (missing oracles, no declared
deliverable) stay untagged, because prescribing gate.commands there
would be a false cure. When at least one no-runner skip occurred, the
check prints one trailing line naming those stages and the inline
declaration that turns them on, noting the file is committable so CI
runs the same gate. The remedy was proven true before the line was
written: declaring gate.commands flips all four stages from skip to run
through the shipped binary. JSON carries skipReason additively; every
skip message, exit code, and skip semantic is byte-identical.

Verified: 16-test impl-blind oracle passing on first contact, 12 unit
tests, golden matrix untouched, four-environment guard on the built
binary (guidance 1/0/0/0: runner-less shows it, declared / self /
known-toolchain do not), JSON purity, full suite 2981/2981.

F-c17e1edc · clad done under a GREEN strict pre-push gate

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Version A/B: what the release may and may not claim
The prepared 0.9.4 section predated the language-agnostic core and the
skip guidance, so the changelog folds [Unreleased] into it, adds the
runner-less-skip entry, re-dates the release, and leads with what
changed for users. The measured claims follow the A/B case document's
boundaries verbatim: what the old check wrongly blocked and what an
honest green cost, with n stated — and nothing the experiment ruled out.
README status rows across all six variants move to 281 features
(277 done).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@qwerfunch
qwerfunch merged commit a20dc3d into main Aug 26, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants