fix(ci): unwedge the develop base — test-mock rejection, bsc-brief infinite loop, job timeouts - #2415
Merged
Merged
Conversation
…finite loop, job timeouts Three fixes so every open PR's CI gate can go green (#2414): - useTunnelHookTelemetry.test.ts mocked the bsc bridge as a bare vi.fn(); this file imports @/store, whose persist-rehydrate calls `bscJson(...).then(...)` — undefined.then → an unhandled rejection that failed every frontend job while all 3389 tests passed. The mock now resolves its fallback, matching the real bridge's contract. - coord-emit.sh flag parsers (bsc-issue/bsc-assign/bsc-brief) spun forever on a dangling flag: `shift 2` with one arg left shifts NOTHING in bash. The test's unquoted `--ref #77` (bash eats `#77` as a comment) hit exactly that, hanging the Rust job to the 6-hour runner timeout on six PRs. Parsers now degrade (`shift 2 2>/dev/null || shift`, `"${2-}"`), the test quotes the ref, and a dangling-flag regression case pins it. This was a live-agent hazard too: a planner emitting an unquoted `bsc-brief director --ref #123` would wedge its session forever. - ci.yml jobs now carry timeout-minutes so a future hang fails in minutes, not 6 hours per runner. Closes #2414. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The bsc-brief hang meant the Rust suite never ran to completion on CI, so two born-broken tests (both fleet-pushed straight to develop) were invisible until the hang fix let the run finish: - pty_faults::extracts_a_rust_panic_with_its_note (#2264, born broken): a Rust panic head ends with ':' and carries its message on the NEXT line (the 1.65+ two-line format). That message line matches no frame shape, so the stack walk stopped on it and dropped the note line the test asserts on. extract_faults now absorbs the panic-message line into the stack (guarded to never absorb another fault head), which also gives the fault fingerprint the actual message. - planner::directives::embedded_directive_key_set_matches_the_migrated_set: the new test_ui stage (data/stages/test_ui.json) carries a directive but the drift-guard's expected set was never updated. Added test_ui. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s per run - bsc-agent's project_cli_with_its_store_present_is_not_flagged rotted when the `errors` sidecar (#2260) added BSC_ERROR_DB as a project store: the test hardcoded only PLAN + DATA, so `errors` was flagged "needs a project context". The store list now derives from SIDECARS, so the next project-scoped sidecar cannot rot it again. - ci.yml: `cargo test --workspace --no-fail-fast` — the default aborts at the first failing test target, which is why this base rot has surfaced one crate per 12-minute CI round instead of all at once. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…d was dead code Fourth and final masked rot (#2414): slug_check_rejects_empty_id_with_the_ stores_noun expects safe_id("..") to be rejected, but the mapper turns every dot into '_' before the guard runs, so `safe == "."` / `".."` could never match and ".." sailed through as Ok("__"). Requiring at least one alphanumeric rejects the same traversal shapes the guard intended and keeps all-punctuation ids from colliding onto one underscores-only file. Diverges from fsx::safe_dir_segment only for those degenerate ids (the doc comment now says so); identical output for every real id. The --no-fail-fast sweep confirms this was the last red test target in the workspace. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… tests Develop grew a fifth rot mid-repair: PR #2424 merged while the base gate was red, bringing the TextArea primitive with tests that never ran green. - Field.test.tsx asserted `ta.spellcheck === false`, but jsdom doesn't implement that IDL reflection on textarea — the property reads undefined regardless of the attr. Assert getAttribute("spellcheck") instead (what React actually renders). - specimens.test.tsx requires every react-ui primitive to have a bespoke specimen; TextArea was registered in the manifest without one and hit the "rendered in-app" fallback. Added the bespoke specimen (TextField's multiline sibling) + a shape-matched loading skeleton (84px, matching the component's own Skeleton h). Also merges origin/develop (#2422-#2425) into the branch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…thout one #2426 (fill UI-kit manifest gaps) merged past the red gate mid-repair and registered LabelChip, ActivityFeed, Pane, TelemetryPanel, ItemBars, and SplitBar in the react-ui kit with no Design Studio specimen — each one a fresh no-fallback guard failure. Added all six in the established inline style, verified complete by statically diffing the kit's component names against the specimen switch (no more one-per-CI-round whack-a-mole). Also merges origin/develop (#2426). Co-Authored-By: Claude Fable 5 <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.
Every open PR's CI gate is red from two develop-base breakages (the tail #2408 didn't reach). Fixed here:
1. Frontend — unhandled rejection fails the job while all 3389 tests pass
useTunnelHookTelemetry.test.tsmocks the bsc bridge as a barevi.fn(), but also imports@/store— whose persist-rehydrate callsbscJson(null, ["blueprint","list","--full"], []).then(...). The bare mock returnsundefined→.thenof undefined → Unhandled Rejection → vitest exits non-zero. Reproduced identically on PR #2400 and the frontend-untouched dependabot PR #2410. The mock now resolves its fallback (the real bridge's documented degrade behavior) and stubsbscWrite.2. Rust —
bsc_brief_emits_tab_aligned_coord_linehangs 6 hoursThe test runs
bash -c "bsc-brief director --ref #77"— bash eats unquoted#77as a comment, leaving--refdangling, and incoord-emit.shshift 2with one arg left shifts nothing, so the parser loops forever. Verified empirically both ways. Six PRs burned a 6-hour runner each on this.bsc-issue/bsc-assign/bsc-brief):"${2-}"+shift 2 2>/dev/null || shift— a dangling flag falls through instead of spinning. This was a live-agent hazard too: a planner emitting an unquotedbsc-brief director --ref #123would wedge its session forever.--ref '#77', so it actually round-trips into the log) and adds the dangling-flag shape as a terminating regression case.3. ci.yml job timeouts
No job had
timeout-minutes; a hang cost 6h × N runners. Added: changes 10 / frontend 25 / plan-contract 15 / rust 90 (cold DuckDB build headroom) / gate 5.Gate: typecheck clean · lint 0 errors ·
cargo clippy --workspace --all-targets -D warningsclean.Closes #2414.
🤖 Generated with Claude Code