test(generated): ts-rs export sync ratchet (#1132 PR-2)#1137
Merged
Conversation
…1132 PR-2) (#1136) The auto-generated per-module index.ts barrels in shared/generated/ must stay in sync with the .ts files emitted by the ts-rs export tests. When they drift, types are invisible to TS consumers even though the .ts file exists on disk — exactly the regression that bit PR #1129 (commit db271d3 manually added 12 export lines after the fact). This ratchet makes the same regression structurally impossible: - Walks every module dir under src/shared/generated/ - For each, lists the .ts files on disk + parses index.ts for `export type { X } from './Y'` lines - Asserts every on-disk file is referenced; every reference has a file - Failure message names exact drift + suggests `npx tsx generator/generate-rust-bindings.ts` recovery Critical correctness detail: extracts the FROM path (`Y`), not the exported type name (`X`). ts-rs `#[ts(rename = "...")]` produces `export type { ToolCall } from './AgentToolCall'` where the file is AgentToolCall.ts but the type is renamed to ToolCall. Earlier draft of this ratchet got this wrong and falsely flagged every rename usage on canary; corrected before commit. Tests (8/8 passing on canary state): - 5 parser unit tests pinning canonical / rename / double-quote / multi-line / malformed-tolerance behaviour - 1 drift-detection unit test asserting both regression modes (missing-from-barrel + dangling-export) surface correctly - 1 integration scan over real shared/generated/ tree - 1 known-modules sanity check guarding against accidental dir deletion hiding drift behind an empty module Same shape as Lane F PR-1 deletion ratchet (#128) — walk source, assert pattern, fail loud with actionable message. Card: continuum#1136. Lane partner: claude-tab-2 PR #1135 (#1132 PR-1, AIRC + queue-lifecycle smoke slice; this is the ts-rs export check slice they explicitly handed to me). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 13, 2026
joelteply
added a commit
that referenced
this pull request
May 14, 2026
* test(#1132): canary smoke for jtag CLI + screenshot path Continuation of the canary smoke matrix (continuum#1132). Sibling tab #1 shipped the AIRC+queue slice (#1135), ts-rs ratchet (#1137), and Rust feature smoke (#1138). This PR adds the JTAG ping + screenshot slice — covers the user-facing CLI surface that Carl interacts with. What this catches ----------------- scripts/ci/canary-smoke-jtag.sh — three checks against the running Continuum stack: 1. Stack presence: pgrep for continuum-core/widget-server. Skips gracefully when stack is down (operator runs npm start to enable); hard-fails when STACK_REQUIRED=1 for CI gates that mandate stack. 2. jtag ping reaches stack: round-trip CLI → WebSocket → core → back. Catches: dangling-shim regression (#91-#93) where the global ~/.local/bin/jtag symlinks into a deleted temp dir and fails ERR_MODULE_NOT_FOUND on every invocation; UnixSocket missing despite running process; widget-server crashed. Includes specific recovery hints for the dangling-shim and ENOENT-socket patterns. 3. Screenshot writes valid PNG: jtag interface/screenshot --filename TMP.png produces a >1KB file with PNG magic bytes (89 50 4E 47). Catches the silent-blank-screenshot pattern where screenshot returns 200 but body is empty/HTML-error/non-PNG. Design notes ------------ - File-system check only for CLI presence — JTAG CLI requires the running stack for ANY command (including --help), so an invocation-based liveness probe is indistinguishable from a stack- down skip. Discovered while validating: ./src/jtag --help fails with `connect ENOENT continuum-core.sock` when stack is down. - Per-step pass/skip/fail with the failure detail inlined so operators don't grep through the full jtag output. - PNG magic-bytes detection validated against papers/example-of-collaboration.png locally (529KB, magic 89504e47 OK). Validated locally ----------------- - bash -n clean - Stack-down (default): 0 passed, 2 skipped, 0 failed → exit 0 - Stack-down (STACK_REQUIRED=1): 0 passed, 0 skipped, 3 failed → exit 2 - Magic-bytes detection works on a real PNG fixture Stack-UP path is NOT validated locally — local Mac stack happens to be down, and `npm start` (90+ sec) wasn't justified for this scope. The logic is straightforward (run command, check exit + magic bytes) and will surface any defect when sibling or Joel runs it against a live stack. Soft skip + clear recovery hints means a wrong-path failure is diagnostic, not silent. Remaining #1132 lanes --------------------- After this lands: only persona/chat path proof + Docker/Carl gates (blocked on amd64 image cards) remain. Card stays open with status log noting which slices are landed. * fix(#1132): harden jtag smoke stack detection --------- Co-authored-by: Test <test@test.com>
3 tasks
joelteply
pushed a commit
that referenced
this pull request
May 14, 2026
Implements Phase 1a of the design at docs/architecture/FORGE-RECIPE-AS-ENTITY.md (continuum#1165). Pure value types only. What ships: - ForgeRecipe entity (authored input): identity, prose, methodology, source, pipeline (stages opaque JSON for v1), calibration corpus, top-level quant tiers, evaluation benchmarks, hardware, lineage. - ForgeArtifact entity (foundry output): snapshot of recipe fields and execution outputs (forged_at_ms, duration, params_b, hardware_verified, alloy_hash, results/receipt/integrity opaque JSON for v1). Recipe lineage frozen so later recipe edits cannot retroactively rewrite what the artifact claims. - Supporting types: AlloySource, PriorBaseline, CorpusRef (canonical sha256 hex matching admission), QuantTier, BenchmarkDef, AlloyHardware, HardwareProfile. - ts-rs bindings to shared/generated/forge/ (9 files plus barrel). Tests: 26 passing covering serde roundtrip, minimal recipe with defaults, opaque blob preservation, partial artifact, recipe lineage immutability, ts-rs binding generation. Barrel-sync ratchet from PR #1137 still green. Phase 1b: rename existing TS-side ForgeAlloy to ForgeArtifact (15 files, separate slice). Phase 2: typed RecipeStage enum and typed results/receipt/integrity. Phase 3: entity registry plus forge/run IPC. Card: continuum#1169. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3 tasks
joelteply
added a commit
that referenced
this pull request
May 14, 2026
… (#1170) Implements Phase 1a of the design at docs/architecture/FORGE-RECIPE-AS-ENTITY.md (continuum#1165). Pure value types only. What ships: - ForgeRecipe entity (authored input): identity, prose, methodology, source, pipeline (stages opaque JSON for v1), calibration corpus, top-level quant tiers, evaluation benchmarks, hardware, lineage. - ForgeArtifact entity (foundry output): snapshot of recipe fields and execution outputs (forged_at_ms, duration, params_b, hardware_verified, alloy_hash, results/receipt/integrity opaque JSON for v1). Recipe lineage frozen so later recipe edits cannot retroactively rewrite what the artifact claims. - Supporting types: AlloySource, PriorBaseline, CorpusRef (canonical sha256 hex matching admission), QuantTier, BenchmarkDef, AlloyHardware, HardwareProfile. - ts-rs bindings to shared/generated/forge/ (9 files plus barrel). Tests: 26 passing covering serde roundtrip, minimal recipe with defaults, opaque blob preservation, partial artifact, recipe lineage immutability, ts-rs binding generation. Barrel-sync ratchet from PR #1137 still green. Phase 1b: rename existing TS-side ForgeAlloy to ForgeArtifact (15 files, separate slice). Phase 2: typed RecipeStage enum and typed results/receipt/integrity. Phase 3: entity registry plus forge/run IPC. Card: continuum#1169. Co-authored-by: Test <test@test.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Ratchet test that locks
shared/generated/<module>/index.tsbarrels in sync with the.tsfiles emitted by ts-rs export tests. When they drift, types are invisible to TS consumers even though the .ts file exists on disk — exactly the regression that bit PR #1129 (commit db271d3 manually added 12 export lines after the fact). This makes that regression structurally impossible.Scope (lane-separated with claude-tab-2)
PR-2 of continuum#1132. Lane separation acked on airc:
Card
continuum#1136.
Test design
The ratchet:
src/shared/generated/.tsfiles on disk + parsesindex.tsforexport type { X } from './Y'linesnpx tsx generator/generate-rust-bindings.tsrecovery commandCritical correctness detail: extracts the FROM path (
Y), not the exported type name (X).#[ts(rename = "...")]producesexport type { ToolCall } from './AgentToolCall'where the file isAgentToolCall.tsbut the type is renamed toToolCall. First draft of the ratchet got this wrong and falsely flagged every rename usage on canary; corrected before commit.Validation
8/8 tests covering:
shared/generated/treenpm run build:tsclean. Hooks ran without--no-verify.Same shape as Lane F PR-1 deletion ratchet (#128) — walk source, assert pattern, fail loud with actionable message.
Test plan
#[derive(TS)]type without regenerating the barrel fails this test in CI (would have caught feat(persona): typed Engram + admission membrane types (#1121 PR-1) #1129 pre-merge).tsfile but forgets to update the barrel fails this test (dangling-export detection)🤖 Generated with Claude Code