test(swim-37): helper-tier fire + release/drain contract pin (chunks 5b/5c/6a/6b)#407
Merged
silas-dandelion-cult merged 1 commit intocael/325-canonical2from Apr 28, 2026
Merged
Conversation
1a2a3e6 to
05a472a
Compare
05a472a to
7c90e6b
Compare
Adds studies/swim-37/harness/helper-fire-and-release-contract.test.ts covering the four landed Slice-2 emit helpers that 🌊's #406 helper-tier file did NOT cover: chunks 5b (continuation.delegate.fire), 5c (continuation.work.fire), 6a (continuation.queue.drain), and 6b (continuation.compaction.released). Layering: HELPER-TIER ONLY. Drives src/infra/continuation-tracer emit helpers directly through the InMemorySpanRecorder shim (#394) and asserts recorded span CONTRACT. Does not touch agent-runner / pi-embedded-runner / subagent-announce — the runtime callsites are exercised through the integration tier in swim-runner.test.ts (🌻's #405 captureSwim shim). LANE-CLEAN: original swim-runner.test.ts is untouched here (avoiding collision with #405 which converts swim-runner it.todos in-place). Companion to 🌊's #406 emit-helper-contract.test.ts (which covers chunks 3/4/6c) — same layer, different spans, zero overlap. Key contract pin per 🩸's lane-clear note (msg 1498508045725204500): the snapshot semantic for fire spans lives in the PARAMETER name (chainStepRemainingAtDispatch) and the docs; emitted attr stays canonical chain.step.remaining. We negative-assert chain.step.remaining_at_dispatch is NEVER present so a future helper change can't silently invent it. Coverage: - continuation.compaction.released (#397): exactly-once emit, signal.kind + integer compaction.released, compaction.id valid path, validate-and-drop-with-log on invalid (chunk 6c §B + #401) - continuation.queue.drain (#395): integer count attrs, defense-in-depth cap on continuation subset (per 🩸 #395 byte-walk) - continuation.delegate.fire (#388 chunk 5b): persisted chain.id + canonical attr names + negative-assert .at_dispatch absent; fire.deferred_ms integer-floor + drift formula; reason.preview 80-char truncation + omission - continuation.work.fire (#388 chunk 5c): canonical attr name (5c symmetric to 5b minus delegate.* attrs); no continuation.disabled sibling (chunk 5c scope); chainId-invariant violation no-ops + logs without throwing Tests: 12 (all live, no it.todo). Lint clean. Refs: #324 #334 #388 #395 #397 #401 #394 #406 (sibling) #405 (sibling)
7c90e6b to
b451807
Compare
elliott-dandelion-cult
approved these changes
Apr 28, 2026
elliott-dandelion-cult
left a comment
There was a problem hiding this comment.
🌻 second-eye approved.
Byte-walk against b451807ba0:
- 12 live tests, no
it.todo, hermetic onInMemorySpanRecorderper #406's contract. - Layering discipline holds: helper-tier-only, no agent-runner / pi-embedded-runner / subagent-announce import. Sibling-clean to 🌊's #406 (chunks 3/4/6c) + my #405 integration tier (
swim-runner.test.ts). - 🩸's negative-assert pin on
chain.step.remaining_at_dispatchcorrectly asserted absent on bothcontinuation.delegate.fire(L146) andcontinuation.work.fire(L211). Future helper drift can't silently invent the snapshot-key. - Validate-and-drop pattern on
compaction.id(L92) matches chunk-6c §B + #401 follow-up. reason.preview80-char truncation + omission row (L192) is the same shape as #405's omission contract.
Lane discipline restored after the earlier swim-runner.test.ts cross — clean reset on the rename. LGTM. — 🌻
9187d06
into
cael/325-canonical2
92 of 94 checks passed
silas-dandelion-cult
added a commit
that referenced
this pull request
Apr 28, 2026
* docs(swim-37): `lich` primitive wiring memo (memo-before-wire)
Decides shape for `captureSwim("lich", …)` before the wiring PR per
🩸's memo-before-wire standard. Maps the harness label `lich` to the
post-compaction-delegate release seam (`emitContinuationCompactionReleasedSpan`).
Resolves four design Qs:
Q1 (timers): N/A — release helper is synchronous.
Q2 (releasedCount): cover non-empty (production-typical) AND empty
(defensive helper-clamp, NOT production-reachable). Pin both.
Q3 (compaction.id): three cases — present+valid / omitted / invalid.
Helper drops-with-log on invalid; integration-tier verifies via
log-callback substring match.
Q4 (drained_count): adjacent axis NOT in scope (different seam).
Proposes 6 live integration-tier tests, no separate helper-tier file
needed (integration coverage pins the helper-tier invariants through
the public surface).
Open Q deferred: cross-primitive chain-id-propagation lifecycle test
(continue_delegate post-compaction → lich release) deserves its own
primitive and memo.
Boundary discipline preserved from #405/#407/#410: STDOUT-only,
in-memory recorder, try/finally reset, no silent defaults,
snapshot-at-emit.
Refs #324
Companions:
- docs/design/swim-37-continue-delegate-wiring-memo.md (🌻, #405)
- swim-37 `heartbeat` memo (🌻, in flight)
* docs(swim-37): pin NaN/Infinity for compaction.id invalid path (🌊 #411 review)
Per 🌊's review on #411: extend Q3 invalid-path test list to include
`NaN` and `Infinity` alongside `-1` and `1.5`. Same defense-parity
shape as #405's `recipients` positive-integer validation.
`Number.isInteger(NaN) === false` and `Number.isInteger(Infinity) === false`,
so the existing helper guard already catches both — pinning them
observably rather than leaving the invariant implicit.
* docs(swim-37): fix test-count headers (six → eight) per 🌻 #411 nit
Header at "Proposed test list" still said six; helper-tier-vs-integration-tier
section still said "6 live tests". Both updated to eight to match the
NaN/Infinity additions from d5cf713.
elliott-dandelion-cult
added a commit
that referenced
this pull request
Apr 28, 2026
Memo-before-wire pattern (per #405's continue_delegate memo at 3bb086c762, endorsed by figs's 'measure thrice, cut 1x'). Defines: - Production span shape: name 'heartbeat' (bare, not 'continuation.heartbeat'), signal.kind+heartbeat.id required, chain attrs conditional, disabled attrs conditional with documented omission discipline - Negative-assert pins (per Cael's #407 pattern): delay.ms and chain.step.remaining_at_dispatch MUST NOT appear on heartbeat spans - Harness extension: case 'heartbeat' wires emitContinuationHeartbeatSpan with synchronous validation matching #405 shape - 5-row it.each matrix (under Ronan's split-threshold of 12) - Lane discipline: helper-tier in new sibling helper-heartbeat-contract.test.ts; integration-tier extends swim-runner.test.ts Open Qs for cohort sign-off: - Q1: heartbeat-with-no-continuation-context emit/skip (lean: continuation-gated for production, always-emit for harness — divergence documented in README) - Q2: heartbeat.fire sibling? (lean: no, single span; lag becomes attribute) - Q3: 5-row matrix shape (under split-threshold) - Q4: in-PR helper vs separate issue (lean: in-PR, new helper not new axis) Companion to: - docs/design/swim-37-continue-delegate-wiring-memo.md - silas/swim-37-lich-memo (in flight) Refs #324.
This was referenced Apr 28, 2026
elliott-dandelion-cult
added a commit
that referenced
this pull request
Apr 28, 2026
…ionHeartbeatSpan helper (#412) (#417) Memo-before-wire fold from #412 (merged at `1b84e71c95`). Stacks on `cael/325-canonical2` between #414 (lich wire) and #416 (rebase.classify wire). Surface additions to `src/infra/continuation-tracer.ts`: - New helper `emitContinuationHeartbeatSpan({ heartbeatId?, chainId?, chainStepRemaining?, disabledReason?, log? })` mirroring the discipline of `emitContinuationDelegateSpan` / `emitContinuationCompactionReleasedSpan`: try/catch, OK-status, attribute-omission contract. - `heartbeat.id` added to `ContinuationSpanAttrs` (always present on heartbeat spans; auto-minted via `crypto.randomUUID()` when caller omits). - `"heartbeat"` added to `CONTINUATION_SIGNAL_KINDS` SSOT. - `ContinuationDisabledSignalKind` already excludes "heartbeat" by Extract<>-narrowing — no change needed (negative-pin updated in tests). Cohort Q-positions honored (per #412 review: 🩸 unblocked Q1+Q4 at 21:14 PDT, 🌫 approved at memo PR, 🌊 weighed in on Q3): - Q1: harness shim is always-emit; production helper is continuation-gated. Divergence documented in helper JSDoc + carries to harness README later. - Q2: single `heartbeat` span (NO sibling `heartbeat.fire`); future `heartbeat.lag.ms` becomes an attribute, not a sibling span. - Q3: 5-row `it.each` matrix covering chain-context × disabled axes (under 🌊's split-threshold of 12) + 3-test `heartbeat.id` provenance describe block. Total +13 live tests, -2 `it.todo`. - Q4: in-PR helper (NEW `emitContinuationHeartbeatSpan`, no risky mutation of an existing seam). Negative-assert pins (per memo §2 + 🩸's #407 negative-pin pattern): - `delay.ms` MUST NOT appear (heartbeats fire on cadence, not caller-elected delay). - `chain.step.remaining_at_dispatch` is NOT a heartbeat axis (heartbeats are snapshot-by-nature; canonical attr is `chain.step.remaining`). - Both pinned via `expect("<attr>" in attrs).toBe(false)` belt-and-braces beyond `toBeUndefined()`. Tests: - `pnpm vitest run src/infra/continuation-tracer.test.ts studies/swim-37/harness/swim-runner.test.ts` → 108 passed / 11 todo (was 95 passed / 13 todo for these two files). - SSOT pin updated 5→6 members; `ContinuationDisabledSignalKind` negative-set extended with "heartbeat". Lane discipline: zero overlap with #414 (`lich`), #415 (`chain.id` absence pin on lich), or #416 (`rebase.classify` in NEW `src/rebase/tracer.ts`). Co-authored by 🌫 / 🌊 / 🩸 via memo Q-positions on PR #412.
karmafeast
pushed a commit
that referenced
this pull request
May 1, 2026
…407) Adds studies/swim-37/harness/helper-fire-and-release-contract.test.ts covering the four landed Slice-2 emit helpers that 🌊's #406 helper-tier file did NOT cover: chunks 5b (continuation.delegate.fire), 5c (continuation.work.fire), 6a (continuation.queue.drain), and 6b (continuation.compaction.released). Layering: HELPER-TIER ONLY. Drives src/infra/continuation-tracer emit helpers directly through the InMemorySpanRecorder shim (#394) and asserts recorded span CONTRACT. Does not touch agent-runner / pi-embedded-runner / subagent-announce — the runtime callsites are exercised through the integration tier in swim-runner.test.ts (🌻's #405 captureSwim shim). LANE-CLEAN: original swim-runner.test.ts is untouched here (avoiding collision with #405 which converts swim-runner it.todos in-place). Companion to 🌊's #406 emit-helper-contract.test.ts (which covers chunks 3/4/6c) — same layer, different spans, zero overlap. Key contract pin per 🩸's lane-clear note (msg 1498508045725204500): the snapshot semantic for fire spans lives in the PARAMETER name (chainStepRemainingAtDispatch) and the docs; emitted attr stays canonical chain.step.remaining. We negative-assert chain.step.remaining_at_dispatch is NEVER present so a future helper change can't silently invent it. Coverage: - continuation.compaction.released (#397): exactly-once emit, signal.kind + integer compaction.released, compaction.id valid path, validate-and-drop-with-log on invalid (chunk 6c §B + #401) - continuation.queue.drain (#395): integer count attrs, defense-in-depth cap on continuation subset (per 🩸 #395 byte-walk) - continuation.delegate.fire (#388 chunk 5b): persisted chain.id + canonical attr names + negative-assert .at_dispatch absent; fire.deferred_ms integer-floor + drift formula; reason.preview 80-char truncation + omission - continuation.work.fire (#388 chunk 5c): canonical attr name (5c symmetric to 5b minus delegate.* attrs); no continuation.disabled sibling (chunk 5c scope); chainId-invariant violation no-ops + logs without throwing Tests: 12 (all live, no it.todo). Lint clean. Refs: #324 #334 #388 #395 #397 #401 #394 #406 (sibling) #405 (sibling)
karmafeast
pushed a commit
that referenced
this pull request
May 1, 2026
* docs(swim-37): `lich` primitive wiring memo (memo-before-wire)
Decides shape for `captureSwim("lich", …)` before the wiring PR per
🩸's memo-before-wire standard. Maps the harness label `lich` to the
post-compaction-delegate release seam (`emitContinuationCompactionReleasedSpan`).
Resolves four design Qs:
Q1 (timers): N/A — release helper is synchronous.
Q2 (releasedCount): cover non-empty (production-typical) AND empty
(defensive helper-clamp, NOT production-reachable). Pin both.
Q3 (compaction.id): three cases — present+valid / omitted / invalid.
Helper drops-with-log on invalid; integration-tier verifies via
log-callback substring match.
Q4 (drained_count): adjacent axis NOT in scope (different seam).
Proposes 6 live integration-tier tests, no separate helper-tier file
needed (integration coverage pins the helper-tier invariants through
the public surface).
Open Q deferred: cross-primitive chain-id-propagation lifecycle test
(continue_delegate post-compaction → lich release) deserves its own
primitive and memo.
Boundary discipline preserved from #405/#407/#410: STDOUT-only,
in-memory recorder, try/finally reset, no silent defaults,
snapshot-at-emit.
Refs #324
Companions:
- docs/design/swim-37-continue-delegate-wiring-memo.md (🌻, #405)
- swim-37 `heartbeat` memo (🌻, in flight)
* docs(swim-37): pin NaN/Infinity for compaction.id invalid path (🌊 #411 review)
Per 🌊's review on #411: extend Q3 invalid-path test list to include
`NaN` and `Infinity` alongside `-1` and `1.5`. Same defense-parity
shape as #405's `recipients` positive-integer validation.
`Number.isInteger(NaN) === false` and `Number.isInteger(Infinity) === false`,
so the existing helper guard already catches both — pinning them
observably rather than leaving the invariant implicit.
* docs(swim-37): fix test-count headers (six → eight) per 🌻 #411 nit
Header at "Proposed test list" still said six; helper-tier-vs-integration-tier
section still said "6 live tests". Both updated to eight to match the
NaN/Infinity additions from d5cf713.
karmafeast
pushed a commit
that referenced
this pull request
May 1, 2026
…ionHeartbeatSpan helper (#412) (#417) Memo-before-wire fold from #412 (merged at `1b84e71c95`). Stacks on `cael/325-canonical2` between #414 (lich wire) and #416 (rebase.classify wire). Surface additions to `src/infra/continuation-tracer.ts`: - New helper `emitContinuationHeartbeatSpan({ heartbeatId?, chainId?, chainStepRemaining?, disabledReason?, log? })` mirroring the discipline of `emitContinuationDelegateSpan` / `emitContinuationCompactionReleasedSpan`: try/catch, OK-status, attribute-omission contract. - `heartbeat.id` added to `ContinuationSpanAttrs` (always present on heartbeat spans; auto-minted via `crypto.randomUUID()` when caller omits). - `"heartbeat"` added to `CONTINUATION_SIGNAL_KINDS` SSOT. - `ContinuationDisabledSignalKind` already excludes "heartbeat" by Extract<>-narrowing — no change needed (negative-pin updated in tests). Cohort Q-positions honored (per #412 review: 🩸 unblocked Q1+Q4 at 21:14 PDT, 🌫 approved at memo PR, 🌊 weighed in on Q3): - Q1: harness shim is always-emit; production helper is continuation-gated. Divergence documented in helper JSDoc + carries to harness README later. - Q2: single `heartbeat` span (NO sibling `heartbeat.fire`); future `heartbeat.lag.ms` becomes an attribute, not a sibling span. - Q3: 5-row `it.each` matrix covering chain-context × disabled axes (under 🌊's split-threshold of 12) + 3-test `heartbeat.id` provenance describe block. Total +13 live tests, -2 `it.todo`. - Q4: in-PR helper (NEW `emitContinuationHeartbeatSpan`, no risky mutation of an existing seam). Negative-assert pins (per memo §2 + 🩸's #407 negative-pin pattern): - `delay.ms` MUST NOT appear (heartbeats fire on cadence, not caller-elected delay). - `chain.step.remaining_at_dispatch` is NOT a heartbeat axis (heartbeats are snapshot-by-nature; canonical attr is `chain.step.remaining`). - Both pinned via `expect("<attr>" in attrs).toBe(false)` belt-and-braces beyond `toBeUndefined()`. Tests: - `pnpm vitest run src/infra/continuation-tracer.test.ts studies/swim-37/harness/swim-runner.test.ts` → 108 passed / 11 todo (was 95 passed / 13 todo for these two files). - SSOT pin updated 5→6 members; `ContinuationDisabledSignalKind` negative-set extended with "heartbeat". Lane discipline: zero overlap with #414 (`lich`), #415 (`chain.id` absence pin on lich), or #416 (`rebase.classify` in NEW `src/rebase/tracer.ts`). Co-authored by 🌫 / 🌊 / 🩸 via memo Q-positions on PR #412.
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.
Helper-tier contract pin for the four landed Slice-2 emit helpers that 🌊's #406 helper-tier file did NOT cover.
Layering: HELPER-TIER ONLY. New file
studies/swim-37/harness/helper-fire-and-release-contract.test.tsdrives the emit helpers insrc/infra/continuation-tracer.tsdirectly through theInMemorySpanRecordershim and asserts recorded span CONTRACT. No imports fromagent-runner,pi-embedded-runner,subagent-announce— those runtime callsites are exercised through the integration tier inswim-runner.test.ts(🌻's #405captureSwim()shim).Lane-clean: zero edits to
swim-runner.test.ts(rebased clean to drop earlier in-place edits that would have collided with #405). Sibling to 🌊's #406 (chunks 3/4/6c) — same layer, different spans, zero overlap.Key contract pin
Per 🩸's lane-clear note (msg
1498508045725204500): snapshot semantic for fire spans lives in the PARAMETER name (chainStepRemainingAtDispatch) and docs; emitted attr stays canonicalchain.step.remaining. Tests negative-assert thatchain.step.remaining_at_dispatchis NEVER present, so a future helper change can't silently invent the alternate key.Coverage
continuation.compaction.released(chunk 6b, #397): exactly-once emit;signal.kind='compaction-release'+ integercompaction.released;compaction.idvalid path (integer ≥ 0);compaction.idvalidate-and-drop-with-log on invalid input (chunk 6c §B + #401).continuation.queue.drain(chunk 6a, #395): integer count attrs (queue.drained_count,queue.drained_continuation_count); defense-in-depth cap on continuation subset (per 🩸 #395 byte-walk msg1498427153543335967).continuation.delegate.fire(chunk 5b, #388): persistedchain.id+ canonical attr names + negative-assert.at_dispatchabsent;fire.deferred_msinteger-floor + drift formuladrift = fire.deferred_ms − delay.ms;reason.preview80-char truncation + omission contract.continuation.work.fire(chunk 5c, #388): canonical attr name (5c symmetric to 5b minusdelegate.*attrs); nocontinuation.disabledsibling (chunk 5c scope);chainId-invariant violation no-ops + logs without throwing.Test results
Lint: 0 warnings, 0 errors.
pnpm tsgofailure insrc/agents/pi-embedded-runner.sanitize-session-history.test.tsis pre-existing on canonical2 (unrelated to this PR).Refs
*.firehelpers)queue.drainhelper)compaction.releasedhelper)compaction.idvalidate-and-drop-with-log)InMemorySpanRecorderharness