Skip to content

fix(standards): a guard whose expected value was a copy of its actual value (GT-633) - #277

Closed
beyondnetPeru wants to merge 12 commits into
developfrom
claude/happy-rubin-634587
Closed

fix(standards): a guard whose expected value was a copy of its actual value (GT-633)#277
beyondnetPeru wants to merge 12 commits into
developfrom
claude/happy-rubin-634587

Conversation

@beyondnetPeru

Copy link
Copy Markdown
Contributor

Pull Request Summary

Registers GT-633 and lands the fix it describes. The interesting content is the failure mode, not the repair.

src/rulesets/standards/native-evaluability-snapshot.json declared in its own header that it was a capture. Nothing captured it. It was hand-maintained and it drifted — documentation-only: 129 while Core pinned 136 — and it went on calling rules unimplemented-native after they had handlers.

Its guard in iso-5055-mapping.test.mjs compared the snapshot's six class counts against six numbers typed into the test: the same six literals the snapshot already contained. Expected value and actual value were copies of each other, so the assertion held for as long as the file was unchanged, whatever Core actually pinned. It reported an agreement it never checked — worse than no guard, because the row it protects reads as verified.

The drift does not stay where it starts. build-iso-5055-mapping.mjs stamps nativeEvaluability onto every row of the ISO/IEC 5055 mapping from that file — 388 rows now, 381 before — so one stale class is laundered into a derived artifact five times the size of its input, and overstates the handler backlog that is GT-598's entire deliverable. The recapture→rebuild order was written down nowhere, and the mapping's own guard ran in no workflow at all.

What lands

  • capture-native-evaluability-snapshot.mjs runs Core's real triage through ts-node. Nothing is reimplemented: a second implementation of the classification here would be a second source of truth, which is the defect being removed. To make the triage reachable outside jest it moved into src/packages/core-domain/test/rule-corpus-triage.ts — that unreachability is precisely why the file was maintained by hand.
  • Three checks replace the tautology, each in the job that can afford it: rule-corpus-triage.spec.ts asserts the committed snapshot against a freshly computed triage in both directions; the documentation-job guard reads Core's pinned counts out of the spec that pins them and throws when the literal is missing or reshaped, so failing to find the source of truth can never read as agreement with it; --check is the end-to-end re-derivation.
  • The order is now data, not prose — two new links in the GT-630 derived-artifact chain (46-validate-derived-artifact-order.mjs), between the ABAC link and the maturity links. Rebuilding the mapping before recapturing the snapshot is a guard failure now, not tribal knowledge.
  • Two new CI steps in docs.yml, which backs the required Validate documentation check.

The merge conflict was worth reading

rule-corpus-triage.spec.ts was rewritten on both sides: the fix extracted the corpus loader, while main closed twelve handlers inside it (GT-595, GT-632). The resolution keeps the extracted harness and main's numbers — but the extracted loader had dropped the enforce field GT-632 added, which is exactly the pattern GT-595 recorded as its second instance: a measuring instrument measuring a different corpus than production evaluates. Restored, with the reason written at the point of the port.

Recaptured, and the drift had grown while the fix was in flight

native-handler 139 → 151 · documentation-only 129 → 136 · handler backlog 60 → 48 · corpus 379 → 386 · mapping 381 → 388 rows.

Twelve of those handlers were closed by GT-595 and GT-632 while the hand-maintained snapshot went on reporting them as backlog — the defect demonstrating itself one more time, on numbers nobody typed twice. Board, catalog and closure record carry the measured values, EN and ES; counters recomputed 592/632 → 593/633.

Verified in this tree

  • capture --check → faithful capture, 386 rules; build --check → 388 rows, 37 mapped (9.5%), 42 analyser-adoptable
  • 46-validate-derived-artifact-order → 5 links / 7 artifacts, current AND at a fixed point; its own suite 8/8
  • core-domain jest 1436 passed / 127 suites (1 suite, 2 tests skipped); tsc --noEmit clean; iso-5055-mapping.test.mjs 9/9
  • 08-validate-tracking (633 gaps, 609/609 EN/ES sections, 575 closure records), 04-check-bilingual-parity, 01-validate-docs (1491 files), 40, 42, 43 (36/36 guards observed red)

Both failure modes were negative-tested: reverting the count to 129 goes red, and building the mapping from a stale snapshot goes red on the stamp assertion.

Evolith Core Quality Gates

  • Bilingual Parity: board, catalog and the src/rulesets/standards READMEs updated in EN and ES.
  • Validation Scripts: node .harness/scripts/ci/01-validate-docs.mjs → 1491 files, passed.
  • Bilingual Validation: node .harness/scripts/ci/04-check-bilingual-parity.mjs → passed.
  • Agnosticism: no new technology dependency in the agnostic Core reference. The capture script uses ts-node, already a repo dev dependency, and it is harness tooling under src/rulesets/standards, not Core reference material.

Linked ADRs / Issues

  • Link to ADR: n/a — no architectural decision; this is guard and derived-artifact hygiene under ADR-0104's existing chain.
  • Link to Issue: GT-633 (origin GT-598) — gap board, catalog entry

Conventional Commits

  • Title and commits follow Conventional Commits.

🤖 Generated with Claude Code

beyondnetPeru and others added 7 commits July 29, 2026 14:00
fix: three P0s, and twelve rules that promised enforcement and delivered nothing (GT-572, GT-595, GT-604)
…e snapshot it guards

`native-evaluability-snapshot.json` declared in its own header that it was a
capture. Nothing captured it. It was hand-maintained, and it drifted: it said
`documentation-only: 129` while Core pinned 136, and it went on calling rules
`unimplemented-native` after they got handlers.

The guard could not see any of that. It compared the snapshot's counts against
six numbers typed into `iso-5055-mapping.test.mjs` — the same six that are
literals inside the snapshot. Expected value and actual value were copies of
each other, so it passed for as long as the file was unchanged, whatever Core
actually pinned. A guard like that is worse than none: it reports agreement it
never checked.

Three checks replace it, each in the job that can afford it:

  - `rule-corpus-triage.spec.ts` (core-domain jest, required on main) asserts the
    committed snapshot against a FRESHLY COMPUTED triage — counts and the class
    of every rule, in both directions. This is the real guard: it is the only
    place with the dependencies to recompute the truth.
  - `iso-5055-mapping.test.mjs` runs in the documentation job, which has no
    node_modules, so it reads Core's counts OUT OF the spec that pins them
    instead of retyping them. Parsing a source file is a real coupling and it is
    stated rather than hidden: a missing or reshaped literal THROWS. Failing to
    find the source of truth must never read as agreement with it. Two further
    assertions: the snapshot's header must agree with its own body, and every
    class stamped into the mapping must match the snapshot.
  - `capture-native-evaluability-snapshot.mjs --check` is the end-to-end
    re-derivation, runnable wherever the workspace is installed.

The capture script is the missing half. It runs Core's REAL triage through
ts-node — same shape as the ABAC generator — because a second implementation of
the classification here would be a second source of truth, which is the defect
being removed. To make that possible the measurement moved out of the spec, where
only jest could reach it, into `test/rule-corpus-triage.ts`; that unreachability
is why the snapshot was maintained by hand in the first place.

Order matters and is now written down in both READMEs and in CI: recapture, THEN
rebuild. `build-iso-5055-mapping.mjs` stamps `nativeEvaluability` onto every row
from the snapshot, so rebuilding first launders a stale class into a 388-row
artifact and overstates the handler backlog by however many rules Core has closed.

Recaptured on this branch: documentation-only 129 -> 136, corpus 379 -> 386
(CORE-0118-01..CORE-0124-01, the seven generated ADR rulesets GT-627 surfaced).
Mapping rebuilt after: 381 -> 388 rows. The backlog stays 60.

Also wired into CI: the mapping guard ran in NO workflow. It does now.

Verified: core-domain jest 1368 passed / 125 suites; node --test 9/9; guards 01,
04, 40, 46, 47 green. Negative-tested both failure modes — reverting the count to
129 goes red, and building the mapping from a stale snapshot goes red on the
stamp test.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`node_modules/` — with the trailing slash — matches directories only. A fresh
worktree has no node_modules of its own, and the documented workaround is to
symlink the main checkout's; a symlink is not a directory, so the ignore did not
apply to it. The result was a link showing as untracked, and `git add -A` staging
a path that is absolute and valid on exactly one machine. That happened in this
session and was caught by reading the staged set, which is not a control.

Dropping the slash covers both shapes. No tracked path contains `node_modules`,
so nothing is un-tracked by the wider match.

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

The capture runs Core's triage through `node -r ts-node/register` with cwd at the
repository root. `ts-node` is declared by neither the root nor core-domain — it is
a devDependency of core-api and mcp-server, and it only sits in the root
`node_modules` because npm workspaces hoist it. Hoisting is an optimisation, not
a contract: a version conflict makes npm install it under the declaring package
instead, and a root-relative resolution then fails on a clean runner and nowhere
else. That is the failure shape this repository keeps paying for — green locally,
red on CI, because local state was doing work the declaration did not.

Resolve it with `createRequire` from the manifests that actually declare it, root
first, and state the failure when none of them can. The neighbouring ABAC
generator never had this exposure: it runs with cwd inside mcp-server, where
ts-node is declared.

Verified: all three manifests resolve today, `--check` still reports a faithful
capture of 386 rules, mapping guard 9/9.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… of its actual value

Follow-on defect from GT-598. The interesting content is the FAILURE MODE, not
the fix.

`native-evaluability-snapshot.json` said in its own header that it was a
capture. Nothing captured it. It was hand-maintained and it drifted —
`documentation-only: 129` while Core pinned 136 — and the guard over it, in
`iso-5055-mapping.test.mjs`, compared the snapshot's six class counts against
six numbers typed into the test: the same six literals the snapshot already
contained. Expected value and actual value were copies of each other, so it
passed for as long as the file was unchanged, whatever Core actually pinned. A
guard like that is worse than none, because the row it protects reads as
verified.

The second class is why the first was expensive. `build-iso-5055-mapping.mjs`
stamps `nativeEvaluability` onto EVERY row of the ISO/IEC 5055 mapping from that
snapshot — 388 rows after the recapture, 381 before — so one stale class is
laundered into a derived artifact five times the size of its input, and
overstates the handler backlog that is GT-598's entire deliverable.

Registered EN + ES on the board and in the catalog, status DONE, counters
recomputed 592/632 -> 593/633. The closure record names commit 78e9b09 and
states plainly that the fix is not in this branch: the capture script and
`test/rule-corpus-triage.ts` exist only there, so they are not cited as evidence
paths.

Verified: 08-validate-tracking (633 gaps, 609/609 EN/ES sections, 575 closure
records), 04-check-bilingual-parity, 01-validate-docs (1491 files), 40, 42, 43
(36/36 guards observed red). Derived artifacts regenerated in GT-630 order:
reconcile, then summary.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ct chain (GT-633)

The edit the originating session was blocked from making (S-16). The
recapture->rebuild order stops being prose in two READMEs and becomes data in
the GT-630 chain:

  1. ABAC rego tool sets
  2. native evaluability snapshot   <- new
  3. ISO/IEC 5055 corpus mapping    <- new
  4. maturity reconciliation
  5. executive governance summary

The snapshot link has the same shape as the ABAC one — derived from the RUNTIME,
not from a data file — so its `consumes` names the triage entry point and the two
sources that decide a rule's class. The mapping link is the edge the order exists
for: the builder stamps `nativeEvaluability` onto all 388 rows from the snapshot,
so rebuilding first launders a stale class into an artifact five times the size
of its input. Replay-safe because `capturedOn` is deliberately sticky while the
classification is unchanged, so the fixed-point pass stays byte-identical.

The guard's own fixtures move with it: `ABAC_STUB` becomes `UPSTREAM_STUBS` with
a shared `stubProducer` helper covering all three leading links, the count
assertions go 3 -> 5 links and `link 2 of 3` -> `link 4 of 5`, and the
byte-identical-restore test now covers the three new standards artifacts too.
Without that, five of the eight tests fail on the shape check before the
behaviour under test runs.

Verified: node --test 46-validate-derived-artifact-order.test.mjs -> 7 pass,
1 fail, and the one failure is the point: on the real tree the guard reports
`declared producer does not exist: capture-native-evaluability-snapshot.mjs`,
because commit 78e9b09 is not in this branch. THIS COMMIT MUST MERGE WITH OR
AFTER 78e9b09 — landing it alone turns `Validate documentation` red.

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

Brings the GT-633 fix into the line that registers it, so the two chain links
declared in 40d3fa9 have producers and the guard is green end to end instead of
reporting `declared producer does not exist`.

ONE CONFLICT, and resolving it surfaced the same defect one layer down.
`rule-corpus-triage.spec.ts` was rewritten on both sides: the fix branch moved
the corpus loader out to `test/rule-corpus-triage.ts` so a script could reach it,
while main closed twelve handlers in it (GT-595, GT-632). Resolution keeps the
extracted harness AND main's numbers — but the extracted loader had DROPPED the
`enforce` field GT-632 added, which is precisely the pattern GT-595 recorded as
its second instance: a measuring instrument measuring a different corpus than
production evaluates. Restored, with the reason written at the point of the port.

Pinned counts are the merged line's, not the branch's: native-handler 151,
documentation-only 136, unimplemented-native 48, needs-external-system 20,
needs-runtime 17, underspecified 14.

RECAPTURED, and the drift had grown while the fix was in flight: native-handler
139 -> 151, documentation-only 129 -> 136, the handler backlog 60 -> 48, corpus
379 -> 386, mapping 381 -> 388 rows. Twelve handlers had been closed while the
hand-maintained snapshot went on reporting them as backlog — the defect
demonstrating itself once more, on numbers nobody typed twice. Board, catalog and
closure record corrected to the measured values in EN and ES.

Verified in this tree:
  - capture --check -> faithful capture, 386 rules; build --check -> up to date,
    388 rules, 37 mapped (9.5%), 42 analyser-adoptable
  - 46-validate-derived-artifact-order -> 5 links / 7 artifacts, current AND at a
    fixed point; its own suite 8/8
  - core-domain jest 127 suites / 1436 passed (1 suite, 2 tests skipped);
    tsc --noEmit clean; iso-5055-mapping.test.mjs 9/9
  - 08-validate-tracking (633 gaps, 575 closure records), 04 bilingual parity,
    01-validate-docs (1491 files)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@beyondnetPeru
beyondnetPeru requested a review from a team as a code owner July 29, 2026 20:46
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@github-actions

Copy link
Copy Markdown

📊 Bilingual Coverage Impact

PR Changes

  • Paired EN/ES files modified: 4
  • New EN files needing ES translation: 0

Repository Coverage

Metric Value
Total EN files 524
Total ES files 498
Paired files 0
Coverage 0%

Good: All EN changes have ES counterparts.


Generated by GitHub Actions

}
console.log(`GT-598: native-evaluability-snapshot.json is a faithful capture — ${triage.corpusSize} rules.`);
} else {
fs.writeFileSync(OUT, json);
beyondnetPeru and others added 5 commits July 29, 2026 15:55
…hat must not be (GT-624)

Criterion (a) of GT-624. `1.1.0` is now deprecated on six packages —
evolith-cli, evolith-mcp, evolith-agent-runtime, evolith-core-domain,
evolith-core and evolith-infra-providers — each message naming the successor and
the date the security wave landed, so `npm install <pkg>@1.1.0` can no longer
resolve the pre-2026-07-23 build silently.

Verified with `npm view <pkg>@1.1.0 deprecated --prefer-online`. The first
read-back came up empty on four of the six; that was registry cache lag, not a
failed command, which is why it was re-read rather than trusted. All six now
report the message.

TWO PACKAGES WERE DELIBERATELY LEFT ALONE, and the reason is a finding:

  - @beyondnet/evolith-sdk@1.1.0 is what the CURRENT line actually resolves.
    cli@1.2.1 and mcp@1.2.1 both declare `@beyondnet/evolith-sdk: ^1.1.0`, and
    that package publishes 1.0.0, 1.1.0, 2.0.0 — so a caret range under 1.x pins
    EXACTLY 1.1.0, because 2.0.0 is a major. Deprecating it would print a warning
    on every fresh install of the healthy line and offer no 1.x to move to. The
    fix is to retarget those ranges to ^2.0.0 or publish an sdk@1.2.x — a code
    change and a republish, not a registry command.
  - @beyondnet/evolith-contracts@1.1.0 is that package's ONLY published version
    and nothing depends on it, so deprecating it leaves a warning with no upgrade
    path at all.

GT-624 stays OPEN on its other two criteria: no CI gate fails when a
security-tagged commit is absent from the published tag, and that gate's negative
fixture does not exist. Deprecating the versions does not make an unpublished
security fix visible, which is the larger half of the row.

Verified: 08-validate-tracking (633 gaps, 575 closure records), 04 bilingual
parity, 01-validate-docs (1491 files), 41 ratchet unchanged at 309 dead (this
change adds none), 46 chain current and at a fixed point.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…e-wave SDK, and a ratchet nobody can satisfy

Both found while executing other work, and both registered rather than worked
around.

GT-634 (P1) — the published CLI and MCP resolve an SDK build that predates the
security wave. cli@1.2.1 and mcp@1.2.1 both declare
`@beyondnet/evolith-sdk: ^1.1.0`, and that resolves to EXACTLY 1.1.0: the SDK
publishes 1.0.0, 1.1.0 and 2.0.0 with nothing in between, and a caret cannot
cross a major. sdk@1.1.0 is from 2026-07-18, sdk@2.0.0 from 2026-07-27 as part of
the release that closed GT-570, and both consumers from 2026-07-28 — published
AFTER 2.0.0 existed, still pointing at the 1.x line. So the exposure GT-570
declared closed for "anyone installing latest" is not closed for this dependency.
The row deliberately does NOT claim sdk@1.1.0 carries a specific vulnerability:
what is measured is the dates and the resolution, not the contents, and verifying
which fixes are in 2.0.0 is part of closing it.

GT-635 (P2) — `Governance guards (GT-578)` fails on main itself and has for at
least three consecutive runs: 309 dead references against a budget of 305. The
budget was set in 4a1b92d "where it was measured"; ten commits have edited
gap-closure-evidence.json since. A ratchet whose entire purpose is that dead
references must not grow is reporting exactly that while being ignored, because a
permanently red job reads as background noise — the same failure mode GT-622
records for the orphaned CodeQL configuration. The row says explicitly what not
to do: raise the budget to 309 and ratify the breach.

Counters recomputed 593/633 -> 593/635, pending 22 -> 24. Verified:
08-validate-tracking (635 gaps, 611/611 EN/ES sections), 04 bilingual parity,
01-validate-docs (1491 files), 41 ratchet unchanged at 309 (these rows add no
dead references), 46 chain current and at a fixed point.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…rity wave (GT-634)

`@beyondnet/evolith-sdk: ^1.1.0` -> `^2.0.0` in `src/sdk/cli/package.json` and
`src/packages/mcp-server/package.json`. The SDK publishes 1.0.0, 1.1.0 and 2.0.0
with nothing in between, so a caret under 1.x pinned EXACTLY 1.1.0 — published
2026-07-18, five days before the security wave that 2.0.0 shipped.

DOING IT PROVED THE ROW UNDERSTATED THE DEFECT. package-lock.json did not merely
record the range; it pinned the registry TARBALL of sdk@1.1.0, with integrity
hashes, at both:

  src/sdk/cli/node_modules/@beyondnet/evolith-sdk
  src/packages/mcp-server/node_modules/@beyondnet/evolith-sdk

So `npm ci` on a clean checkout fetched the pre-wave SDK and nested it inside each
consumer, where it SHADOWS the workspace link: the top-level symlink to the local
2.0.0 is what every developer reads, and the nested 1.1.0 is what a fresh install
actually resolves. Same class as GT-625 — the workspace hiding what a real install
does — and the reason nothing caught this.

Both nested entries disappear once the range is ^2.0.0, because the workspace's
own 2.0.0 then satisfies it. The lockfile diff is exactly two range strings plus
those two removals, with no collateral drift: the hand edit was made first, then
`npm install --package-lock-only` was run to confirm npm writes byte-for-byte the
same thing, rather than trusting the edit.

The SDK surface both consumers use is narrow — `EvolithRestClient` only — so
2.0.0's breaking change (payload types re-exported from core-domain, `.passed` ->
`.verdict`, `'info'` severity retired) touches neither call site.

Verified against 2.0.0, resolution confirmed by require.resolve rather than
assumed: CLI 1436/1436 in 99 suites, mcp-server 433/433 in 53 suites. Board
validators green: 08 (635 gaps, 611/611 EN/ES), 04, 01 (1491 files), 46 chain at a
fixed point. `tsc --noEmit` on mcp-server reports two errors for
`@nestjs/cache-manager`, which is a worktree artifact (that dependency is nested
in the main checkout's tree, which this worktree symlinks around) and unrelated to
this change.

GT-634 stays OPEN: a range in the repository is not a range on the registry, and
its first criterion is only met by a release.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Version bumps and changelogs only — nothing is published by this commit.

@beyondnet/evolith-cli and @beyondnet/evolith-mcp go 1.2.1 -> 1.2.2. A patch, and
the reason is stated rather than assumed: neither package re-exports the SDK and
both use only `EvolithRestClient`, so 2.0.0's breaking change (payload types
re-exported from core-domain, `.passed` -> `.verdict`, `'info'` severity retired)
reaches no public API of either. cli is a bin; mcp exposes `dist/main` and no SDK
type.

REHEARSED, and the decisive check is an install rather than a range:

  - plan-npm-release.mjs -> 2 of 8 packages WILL PUBLISH, in dependency order,
    the other 6 correctly reported as already on the registry.
  - `npm pack` + clean install of beyondnet-evolith-cli-1.2.2.tgz in a directory
    that has never seen this workspace resolves
    @beyondnet/evolith-sdk@2.0.0. Same for beyondnet-evolith-mcp-1.2.2.tgz. That
    is the fix demonstrated end to end: the range is not the claim, the resolved
    version is.
  - check:install-smoke -> 36 @beyondnet/* specifiers resolve in a clean install
    and the installed binary boots printing 1.2.2. This is the gate GT-625 was
    closed with, and it is what makes a workspace-hidden break visible.
  - check:release-drift -> passed, the built dist carries the expected fixes.
  - CLI jest 1436/1436 (99 suites), mcp-server 433/433 (53 suites) against
    sdk 2.0.0.

Lockfile touched only where it had to be: two `version` lines. Verified by
snapshotting it, running `npm install --package-lock-only`, and diffing — npm
writes exactly what is committed.

NOT DONE HERE, deliberately: publishing. `npm-release.yml` is a workflow_dispatch
whose `dry_run` defaults to true, and it also fires on a `v*` tag — neither was
triggered, and no tag was created. GT-634's first criterion stays open until the
registry serves the new range.

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

The 1.2.2 release rehearsal (`npm-release.yml`, dry_run, run 30499155684) failed
with:

  npm pack reported "beyondnet-evolith-cli-1.2.2.tgz" but no such tarball exists
  in /tmp/evolith-install-smoke-Fr4e7I.

The artifact was fine. `--pack-destination` is not honoured identically across npm
majors when the cwd is a WORKSPACE package: npm 11 (local, Node 24) writes to the
destination, npm 10 (the Node 20 runner) writes to the package directory — and
prints the same filename either way. The guard trusted one of them, so it passed
on a laptop and failed on the runner, which is the exact shape this repository
keeps catching in its own gates.

Now it looks in both, and MOVES a stray tarball out of the source tree instead of
leaving it for the root-cleanliness guard to trip over. The failure message names
both locations and says why both are checked, so the next person does not have to
re-derive it.

Worth stating: the previous release ran this same gate green on the runner
(30356577427, 2026-07-28), so this is not a regression in the workflow — it is an
environment dependence that happened not to bite until now. A gate whose result
depends on which npm packed is not evidence about the package.

Verified locally: check:install-smoke passes, 36 @beyondnet/* specifiers resolve,
the installed binary boots printing 1.2.2, and no stray .tgz is left in
src/sdk/cli. The npm 10 path is verified by re-running the rehearsal on the
runner — the environment that failed is the only honest place to prove it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
beyondnetPeru added a commit that referenced this pull request Jul 29, 2026
Both were caught by required checks on PR #282, and both are the gates working.

`maturity-reconciliation.json` records `cliPackage: @beyondnet/evolith-cli@1.2.1`,
so the version bump made it stale and `Validate documentation` went red at
"Reconcile maturity evidence". Regenerated, then the executive summary re-checked
in that order — it was already current, since the field it reads did not move.

WORTH RECORDING, because it is a hole in a declaration this repository added
yesterday: `09-reconcile-maturity.mjs` reads `src/sdk/cli/package.json`, and the
GT-630 chain declares that link's `consumes` as the gap board plus the maturity
assessment ONLY. So the CLI manifest is an UNDECLARED INPUT to a derived artifact
— exactly the "generator whose output does not depend only on its declared
consumes" case the fixed-point pass exists to catch, and here it was caught by
staleness on a runner instead. The chain declaration lives on the branch of
PR #277; the `consumes` entry belongs there rather than in a release commit.

`evolith-machine-contracts.json` pins `producer.version` to the CLI's version, and
`10-validate-contract-conformance.mjs` fails when they diverge (GT-563 records that
this check was silently crashing until recently, so it is newly effective). Bumped
to 1.2.2. The contract itself is unchanged: `contractVersion` is untouched and all
four schema hashes still resolve.

Verified: 10-validate-contract-conformance -> 4 schemas hashed and resolved;
contracts jest 104/104; 01-validate-docs 1491 files; 08-validate-tracking;
46-validate-derived-artifact-order -> 3 links current and at a fixed point.

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

Copy link
Copy Markdown
Contributor Author

Closing without merging: every code change on this branch has since landed from other sessions, and what remains — the three board rows — is now #289 against main.

what was here superseded by
capture script + extracted triage #276
the two derived-artifact chain links #287 — identical to the specification: same producer, checkArgs, the three consumes sources and both written artifacts, in the position after the ABAC link
SDK range fix + 1.2.2 release prep #285
GT-624 deprecations + the publish-lag gate #288

The one thing this branch carried that is NOT superseded is the merge conflict itself: it holds a reconciliation of the two independent GT-633 implementations (#276's capture script on main, #279's in-spec renderer on develop). That reconciliation is not abandoned — it is the open blocker on #284 (developmain), and it belongs to whoever owns the two halves rather than to a board registration. Deliberately not resolved unilaterally here.

@beyondnetPeru
beyondnetPeru deleted the claude/happy-rubin-634587 branch July 30, 2026 19:56
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