Repository navigation
test(web): pin agent-status-changed and session-ingested narrowing to the shared types - #1
Merged
Merged
Conversation
… the shared types The two sibling realtime arms were still narrowed by hand with no type pin (L4 follow-up, found-not-taken 2026-09-09). An exhaustive `satisfies Record<keyof AgentStatusChangedEvent, true>` field list makes a shared-schema field change a compile error in apps/web, a drop-one-field sweep proves the guard reads every field, and a SessionIngestedEvent-typed frame pins ingestedSessionId. Mutation-checked: all three mutations went red. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FXNMQzi7tUcVA65eSi6mPp
… 10 (D10) The seed carried Sonnet 5 at 3 / 15 with derived cache rates. The platform pricing page (re-read 2026-09-26) says the $2 / $10 launch price is now the standard price and the scheduled increase to $3 / $15 will not occur, so every Sonnet 5 dollar shown was 1.5x too high. Migration 20 rewrites the five seeded floor rows in place (ON CONFLICT DO UPDATE) instead of adding a later-dated row, so the cancelled price never becomes history; no row is added and operator rows at other instants are untouched. Stored usage re-prices at read time. Checksum identical under tsx, vitest and node strip-types. Four new migration tests; dollar expectations that read the seeded Sonnet rate re-derived by hand; migration 19's tests bounded to <= 19. Docs: data-model ledger gains rows 19 and 20, migration counts corrected to twenty. WP-C1 ratification stays the owner's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FXNMQzi7tUcVA65eSi6mPp
…t race - DONE.md: a 2026-09-26 milestone entry (D10 / migration 20, the realtime pins, the test race, the migration-count drift), plus a note that the 2026-09-04..09-25 entry is still the Wave-4 R2 item - Code comments: PRICING_SEED's sonnet row points at migration 20; queries.ts counts migrations 18-20; isAgentStatusChangedEvent and ingestedSessionId name the test that pins them - api.md: all three realtime frames are narrowed by hand and pinned - apps/web/test/app.test.tsx: the 401 test waited for nothing before asserting the SSE stream closed, but React 19 runs that cleanup after the commit when the 401 arrives outside act; it failed ~1 in 17 coverage runs. It now waits for the eventual close and asserts a stream existed. Proved with the close deferred (old 3/3 red, new 3/3 green) and removed (new red). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FXNMQzi7tUcVA65eSi6mPp
…5..09-26 DONE milestone - R1 (Wave 4) rehearsed on a clean tree: all seven CI commands plus gate:node exit 0 at 167 test files / 3060 tests, 100% in all five packages; spawner 313 files, policy file the only allowlisted one; licences 406 packages / 428 installed versions, one documented exception; RELEASE §2 greps clean; P0 4/19; backup.test 4/4; the live-drill command proven on a scratch schema-20 database only. No box ticked. Recorded in RELEASE.md, TODO Wave 4 and the analysis README. - R2: the 2026-09-23 "140 / 2621" reading was already stale on main; the dated 2026-09-26 figure now sits beside it on every page that quotes the suite size, and the gate outputs are re-dated in testing.md and licensing.md. Historical readings are kept, not overwritten. - DONE.md: the milestone entry for 40f1524, 39e565a, closing-board Waves 0-2, docs sweeps #3-#6 and 4b3cd2d, with commit attribution checked against git. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FXNMQzi7tUcVA65eSi6mPp
…e other four packages apps/web guarded only the coverage-ignore pragma. Lowering a web threshold or adding a file to the web coverage `exclude` passed CI; RELEASE.md §1 told the release reader to diff vitest.config.ts by hand for that reason. The web honesty block now reads the config as text and pins the exact thresholds object (four keys at 100, no extras), include 'src/**' and the exact two-entry exclude list, each entry required to exist. Mutations killed: branches 99, a third exclude, an extra perFile key, exclude via a variable. Docs: RELEASE.md §1, testing.md "Three asymmetries", CONTRIBUTING.md (also "raising" -> "lowering"), PROJECT-STATE, CHANGELOG, TODO, DONE. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FXNMQzi7tUcVA65eSi6mPp
testing.md's "Third" asymmetry still said check-no-spawner.mjs and check-licenses.mjs have no unit tests and are exercised only by CI. apps/server/test/scripts-gates.test.ts drives each gate's pure core (and the Node-major guard's) against throwaway fixture trees. Dated note added; the part that still holds - scripts outside every coverage denominator, CLI wrappers deliberately unexecuted - is kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FXNMQzi7tUcVA65eSi6mPp
WP-F5 was always "static no-spawner + no-SSRF gate" and CD-7 makes no-SSRF CI-blocking, but check-no-spawner.mjs never carried an outbound pattern: the invariant rested on RELEASE.md §2's grep and on review, and a fetch() added to the server passed CI. The Phase-1 row was ticked with only the spawner half. The gate now applies an outbound-network family to server-process source (apps/server/src/, packages/*/src/): fetch(, the node http/https/http2/net/ tls/dgram/dns modules, 13 HTTP client packages matched as specifiers only, WebSocket/EventSource clients and XMLHttpRequest; and refuses an HTTP client package in the server and library manifests. Browser code and tests are out of scope by path, not by exemption. The OK line reports the file count (93, all clean). v2.0's dispatcher line will need a visible inline marker. scripts-gates.test.ts 41 -> 60: every pattern, scope in and out, look-alike words, the inline hatch, manifests. Six gate mutations each killed. Docs: RELEASE.md §1/§2, SECURITY.md §9, security model rule 6 and summary, threat model, ADR CD-7, telegram.md (two "planned" / "upheld by review" passages), roadmap guide, licensing.md, testing.md, CHANGELOG, TODO, DONE. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FXNMQzi7tUcVA65eSi6mPp
… IN9, X8) A read-only audit of every ticked v1.0 work package against its development-plan Done-when found clauses the code met but no test proved: - WP-D10: redaction determinism/idempotence, and a redelivered or re-ingested secret-bearing hook event storing one row with unchanged bytes (SQLite-backed route test). - WP-IN9: every token_usage row attributed to exactly one agent of its own session, over the whole fixture registry, in the P0 reconciliation suite. - WP-X8: new hooks-end-to-end.test.ts replays the request read out of the installer-generated command against the real loopback server into events_raw, including the per-firing delivery id. Each new test was shown to fail on a matching regression (key over the unredacted body; main usage left unattributed; installer path, content type and delivery-id header drift). Stale api.md readSince claim and a rows.ts reference corrected. TODO gains the audit section; CHANGELOG updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FXNMQzi7tUcVA65eSi6mPp
…(IN8 #10) Two Done-when clauses the WP audit found ticked but never built. WP-U1 "resumable": RealtimeHub keeps the last 256 frames (replayCapacity, 0 disables) and /api/stream replays every buffered frame after the request's Last-Event-ID - which EventSource sends on its own reconnect, so the SPA needs no change - before live fan-out, in one synchronous step. Non-decimal headers are ignored. Fixed while writing it: replay writes through the route's write(), which can reap the stream, and close() read `unsubscribe` and `heartbeat` from their temporal dead zone; both hoisted, a writer throwing during replay is dropped and counted, and a stream reaped by its own replay is unsubscribed at once. A guard for "ids from an earlier process" was dead code (survived mutation) and is replaced by a written-down restart limit. Nine tests; replay off-by-one, empty buffer and the reaped-during-replay check each killed by mutation. IN8 parser-gate #10: parseSession returns claudeCodeVersions (sorted distinct per-record `version` strings) for provenance only; parsing still branches on directory shape. Not persisted. Three tests, core 100%. Docs: api.md (three places), ADR CD-5 addendum and index, parser-spec #10, web comments that said "no replay buffer", TODO audit section, CHANGELOG. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FXNMQzi7tUcVA65eSi6mPp
…ilestone Nine audit findings are product or process calls rather than code, so they go to the board with a recommended default each: Q5 dashboard reader (D11), U7 live/force layout (D12), C6 staleness gate vs synthetic fixtures (D13), X1 real-session corpus (D14), X5 coverage-block demonstration (D15), X10 WORKLOG check (D16), C1 pricing refresh cadence (D17), C2 PricingProvider port (D18), the dead is_compaction_baseline column (D19). Each was re-verified against the code before being written down. DONE.md records the audit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FXNMQzi7tUcVA65eSi6mPp
IvanBBaev
added a commit
that referenced
this pull request
Oct 5, 2026
test(web): pin agent-status-changed and session-ingested narrowing to the shared types
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.
The two sibling realtime arms were still narrowed by hand with no type pin
(L4 follow-up, found-not-taken 2026-09-09). An exhaustive
satisfies Record<keyof AgentStatusChangedEvent, true>field list makes ashared-schema field change a compile error in apps/web, a drop-one-field sweep
proves the guard reads every field, and a SessionIngestedEvent-typed frame pins
ingestedSessionId. Mutation-checked: all three mutations went red.
Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01FXNMQzi7tUcVA65eSi6mPp