chore(openspec): rebind the isolated-branch-stack row to the landed #481 squash - #482
Conversation
squash The #477 convention's second half: the row bound its evidence-carrying branch commit inside #481 so the pre-merge gate could verify it; the squash landed, so the row now binds the permanently reachable trusted snapshot. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015QTVFY89rS2xRwRB2TpFP6
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe lifecycle ledger updates the recorded ChangesLifecycle ledger update
Estimated code review effort: 1 (Trivial) | ~2 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
monkey1sai-blip
left a comment
There was a problem hiding this comment.
Approved by monkey1sai-blip (the reviewer account pinned by the repo's merge governance).
Submitted through scripts/blip_review.py — a scripted approval carrying the operator's authority, pinned to head 61f48265c67900268dc3c33e1a297b0a9791a208. This is the mechanism the GitHub App cannot satisfy: an App's approving review does not count toward required_approving_review_count.
There was a problem hiding this comment.
Pull request overview
This PR is a one-line follow-up to the merged #481. It rebinds the subject_commit for the isolated-branch-stack-browser-e2e lifecycle row in openspec/lifecycle-ledger.json from the squash-discarded pre-merge branch commit (64cab2c) to the landed #481 squash commit (5e8d677), which is permanently reachable in trusted-base main history.
The rebind is required by the machine-truth reconciliation contract: verify-openspec-machine-truth.mjs (resolveRowSubjectWatermark) fails closed with subject_unavailable/subject_not_ancestor when a row's subject points at a commit that a squash merge discarded, so subsequent PRs would go red until the row is re-pointed at the landed squash. This follows the same convention established in #477 and #481.
Changes:
- Rebind
isolated-branch-stack-browser-e2e'ssubject_committo the reachable #481 squash5e8d677, restoring the reconciliation path.
I verified via the GitHub API that 5e8d677 is the actual #481 squash merge commit on main and that 64cab2c is the pre-merge branch commit that squash discards. The row stays status: active, so NOW.md (which already lists it as active) needs no update, and no other files reference either hash. No issues found.
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
…achine truth (#485) * fix(governance): gate the real repository against its own lifecycle machine truth scripts/lib/openspec-machine-truth.mjs already owns a complete lifecycle comparator, but its CLI needs a GitHub observation and a pinned openspec binary, so CI could only ever exercise it against synthetic temporary fixtures. The one assertion that touched the real tree was a hand-written regex for a single change id, so drift between openspec/changes, the machine ledger and the NOW projection was corrected by hand after landing (#477, #481, #482) instead of being refused at PR time. This adds the repository-local subset of that comparison as a gate that needs no network, git or external binary, and wires it into the already required agent-governance check. It compares the change directories and their proposal markers, openspec/lifecycle-ledger.json, and the NOW projection, reports disagreement rather than resolving it, and fails closed on any input it cannot read as declared. Proven on a real historical commit: run against main at c41e29d the gate reports now_unexpected_change for introduce-executable-architecture-contracts, drift that existed on main and was only fixed later by #481. Claude-Session: cowork scheduled task ai-bim-geo Co-authored-by: Claude Opus 5 <noreply@anthropic.com> * fix(governance): close the ship-gate survivors on the lifecycle parity gate Codex tri-adversarial gate on PR #485 returned SHIP with five non-blocking survivors. Four are closed here; the fifth is disclosed. - L1-1: the current-change cap counted the mandatory archive namespace, so the filesystem observation could not represent the same 512-row boundary the NOW parser accepts. One raw slot is now reserved and the filtered set is bounded instead. - SEC-001: path-derived values reached the text renderers verbatim, so a directory name carrying a newline or ESC byte could forge extra report lines. Values with control characters are now JSON-quoted; JSON output is unchanged. - TG-001: the input_too_large budgets had no coverage. Added the accepted boundary and one past it for change directories, NOW rows, ledger rows and file bytes. - TG-003: the non-regular proposal.md predicate was only reachable through a skippable symlink fixture. Added a portable directory-named-proposal.md case. Not closed: SEC-002 (readdirSync materialises the full Dirent list before the entry cap is applied). Rated low by the apex; incremental opendirSync iteration is a larger refactor and is left as disclosed follow-up. Claude-Session: cowork scheduled task ai-bim-geo Co-authored-by: Claude Opus 5 <noreply@anthropic.com> * fix(governance): close the marker fail-open pair found by the second gate run Second Codex tri-adversarial run on head 40d93c6 returned SHIP with four survivors; the two medium ones were real fail-open defects in the marker parser, which this gate promotes to merge-blocking authority. - L1-1: the canonical marker regex had no trailing token boundary, so `> **Status: active123**` captured `active` and read as a clean active row. The status token must now end at `**`, whitespace or end of line; anything else is reported as an unreadable marker. - L1-2: near-miss detection ran only when no canonical marker was found, so a proposal carrying two disagreeing declarations resolved silently to the canonical one. Every bolded status-like line in the prologue is now inventoried and an unconsumed one is reported even beside a canonical marker. - L1-3: the raw namespace budget is now separate from the canonical change budget, so one stray entry beside a full change set stays a targeted `change_entry_not_a_directory` mismatch instead of a generic budget error. - TG-1: added a control-character assertion for the text input-error path. Verified against all 120 real proposals: the ten current ones are unchanged; only one archived proposal reads `invalid` (`Status: closeout reconciled`), and archived markers are outside this gate's scope. Claude-Session: cowork scheduled task ai-bim-geo Co-authored-by: Claude Opus 5 <noreply@anthropic.com> * fix(governance): correct the orphan-directory record and per-declaration marker counting Both from PR #485 review threads. - The `directory_without_ledger_row` record had its observations reversed: the directory is present in `openspec/changes` and absent from the ledger, so the record now names the directory as the observed value and `absent` as what the ledger was expected to carry. - Status-like declarations are now counted per declaration rather than per line, so `> **Status: active** **Status: deferred**` on a single blockquote line is reported as an unreadable marker instead of resolving to `active`. Claude-Session: cowork scheduled task ai-bim-geo Co-authored-by: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
#512) Same pattern as #482/#501: the row's subject_commit pointed at the pre-squash branch commit (bccf251) which is not an ancestor of main after the #504 squash (881f6da); any PR CI running the machine-truth source observation against this ledger fails subject_not_ancestor. Rebound to the landed squash. Local gates: machine-truth 24/0, metrics 13/0. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
squash (#514) Same pattern as #482/#501/#512: the row's subject_commit pointed at the pre-squash branch commit (1229171) which is not an ancestor of main after the #506 squash (cba6265) and whose branch was auto-deleted; any PR CI running the machine-truth source observation against this ledger fails subject_unavailable. Rebound to the landed squash. Local gates: machine-truth 24/0, metrics 13/0. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…nd hifi row to #507 squash 一、撤除 bootstrap 層(依 #520 裁決=docs/agents/self-referential-bootstrap.md §2.1,PR #521): 量測 harness 的報告無任何 gate 機器消費者,不屬 mechanism surface,不入 ledger。 classifier 擴張+open entry gpu-session-baseline-harness+evidence 一併撤除, scripts/lib/self-referential-bootstrap.ps1、scripts/tests/test-self-referential-bootstrap.ps1、 scripts/self-referential-bootstrap-ledger.json 還原為 origin/main 版本。 機械上這條路也是死路:base-pinned 裁決者以 base 版 classifier 驗證新 entry 宣告的 mechanism paths,同 PR 擴張 classifier 永遠無法讓自己的 entry 合法(實測兩輪 pr-metadata-contract-diagnostic 均以 not classified verification-mechanism paths 拒絕)。 二、rebind migrate-console-to-hifi-design row:#507 squash 後該 row 仍綁 pre-squash commit af60c29(已被丟棄,CI checkout 抓不到)→ 全部後續 PR 的 machine-truth test 25 紅。依 #482/#501/#512 慣例 rebind 到 landed squash 4187102。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Same pattern as #482/#501/#512/#514: subject_commit pointed at the pre-squash branch commit (af60c29) which is not an ancestor of main after the #507 squash (4187102); PR CIs fail subject_not_ancestor until rebound. Local gates: machine-truth 24/0, metrics 13/0. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…baseline 1.1) (#511) * feat(scripts): add GPU session baseline measurement harness (gpu-session-baseline-and-idle-reclaim 1.1) Add scripts/measure-session-baseline.ps1 (root CLI) and scripts/lib/measure-session-baseline.ps1 (testable core) implementing task 1.1 of openspec/changes/gpu-session-baseline-and-idle-reclaim: a read-only harness that captures nvidia-smi GPU inventory (VRAM/utilization, consumer RTX classification, MIG availability), a GET-only WebRTC/coordinator health probe (/health, /api/runtime/status), and the environment fingerprint required by the gpu-session-baseline spec (GPU model, driver version, Kit version from kit-sdk.packman.xml, fixture hash+size). The harness never opens a WebRTC session or creates/joins/closes a review session, so TTFF and session-creation success rate cannot be honestly measured locally; those fields are null with measured:false and an explicit reason unless supplied by a caller (e.g. a future task 1.3 soak run), never fabricated. Every other unmeasurable signal (no nvidia-smi, no GPU rows, insufficient OS permission on the compute-apps VRAM column, coordinator unreachable) degrades the same way instead of throwing or guessing. Registered in scripts/script-registry.json as a measurement-harness (not deploy.ps1/verify-all.ps1: it measures, it does not deploy or gate; not scripts/lib alone: it is the operator-invoked CLI entry; not scripts/tests: it produces a JSON report, not a pass/fail check). Add scripts/tests/test-measure-session-baseline.ps1: unit tests for GPU line parsing/consumer-RTX/MIG classification, fail-safe behavior with nvidia-smi entirely absent, report schema shape, script-registry.json consistency, and a real CLI smoke test (both -OutputPath and the default artifacts/gpu-baseline/<timestamp>.json path). Verified on pwsh 7.5.4 and Windows PowerShell 5.1 (powershell.exe), invoke-powershell-static.ps1, and scripts/tests/test-agent-governance-check.ps1 (45/45 green). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore(openspec): tick gpu-session-baseline-and-idle-reclaim task 1.1 Mark tasks.md 1.1 done (measure-session-baseline.ps1 harness landed) and sync openspec/lifecycle-ledger.json: task_ledger completed 0->1, current_slice points at the 1.2 env-fingerprint gate as the next slice, last_verified refreshed, subject_commit rebound to 405e2b6 (the commit that landed the harness + tests + registry entry), evidence_refs extended to the new script and test paths. Verified: node scripts/tests/verify-openspec-repository-lifecycle.mjs --repo-root . (openspec/changes, lifecycle-ledger.json and docs/plans/NOW.md agree -- NOW.md's projection is id+status only, and status stays "active", so it needed no edit); node --test scripts/tests/test-openspec-machine-truth.mjs (24/24) and scripts/tests/test-ai-coding-metrics.mjs (13/13); pwsh scripts/tests/test-agent-governance-check.ps1 (45/45 embedded repository-lifecycle subtests green). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(scripts): honest gpu-baseline measurements — real binding enum, per-role lease counts, validated inputs, untick 1.1 (review) * fix(scripts): declare gpu fingerprint scope — multi-GPU host is first_gpu_only, per-GPU fingerprint deferred to 1.2 (review) * fix(scripts): harden GPU baseline harness per PR #511 review Addresses the valid findings from the 13 unresolved review threads on scripts/measure-session-baseline.ps1 (gpu-session-baseline-and-idle-reclaim task 1.1/1.2), keeping the "measured:false, never fabricate" contract intact: - Get-SafeProperty: fix a PowerShell pipeline-unroll bug where `return $value` on an empty array collapsed to $null, making an observed empty kit_instance_bindings/viewer_leases indistinguishable from "unmeasured". - Get-WebRtcHealthProbe: count non-terminal KitInstanceBinding statuses (allocated/starting/ready/draining) instead of a literal status='active' that the real coordinator API never emits; count active primary/spectator viewer_leases by role (the actual 1-primary-plus-k-spectator cardinality) instead of sessions.active_count; clarify that `reachable` reflects only coordinator /health liveness, not independent WebRTC/signaling reachability. - Get-SessionVramWatermark: only claim a clean measured total when exactly one Kit GPU process is observed and fully readable; multi-process or partially-readable readouts are surfaced only as the informational unscoped_total_kit_vram_mb, never as a fabricated measured:true total. - Get-EnvironmentFingerprint: fail closed (measured:false) on a multi-GPU host instead of blindly binding the fingerprint to gpus[0]. - Get-KitVersionFingerprint: carry an explicit source/caveat noting this is the checkout's declared dependency version, not a live-process read. - Get-SessionBaselineReport: range-validate caller-supplied -TtffMs / -SessionCreationSuccessRate (reject negative/out-of-range instead of recording as measured); resolve host.hostname via the cross-platform Dns API with HOSTNAME/COMPUTERNAME fallback so Linux deployment targets don't silently null out host identity. - Root wrapper: derive the default -OutputPath from the report's own collision-resistant run_id instead of a bare second-resolution timestamp. - CI: run test-measure-session-baseline.ps1 (PS7 + Windows PowerShell 5.1) as part of the required `powershell-static` job, mirroring the existing test-spec-to-done-port-helper.ps1 pattern -- neither `root-contracts` (pytest) nor the PSScriptAnalyzer-only `powershell-static` gate command previously executed this suite. The lifecycle-ledger subject-ancestry finding (PRRT_kwDOSPoer86YcZ4d) was independently verified as already resolved at current HEAD and needed no change; see PR reply for evidence. Verified: pwsh + Windows PowerShell 5.1 test-measure-session-baseline.ps1, invoke-powershell-static.ps1, and node --test test-openspec-machine-truth.mjs (24/24) all green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(scripts): carry a live-build staleness caveat on kit_version (PR #511 review) Get-KitVersionFingerprint reads bim-streaming-server/tools/deps/kit-sdk.packman.xml -- the checkout's DECLARED kit-kernel dependency version -- not a value read from the live Kit process. If the checkout is updated without a rebuild/restart, this can be stale relative to the session actually being measured, and no local mechanism exists to introspect a running Kit.exe's build identity to close that gap. Surface a `source` ('checkout_packman_declared') and an explicit `caveat` string alongside the existing value/measured/reason shape (both on the raw fingerprint and propagated through Get-EnvironmentFingerprint's kit_version field) so downstream SLO-writers know what this field does and does not attest to, rather than silently trusting checkout state as if it were live-process state. This was the one review thread not already covered by the concurrent fixes landed in 37e3247/2eee19b on this branch (real KitInstanceBinding status enum, per-role viewer lease counts, VRAM attribution transparency, TTFF/success-rate validation, hostname fallback, GPU fingerprint scope disclosure, collision-resistant default filename, task 1.1 unticked); this commit reconciles with that work rather than duplicating it. Verified: pwsh + Windows PowerShell 5.1 test-measure-session-baseline.ps1, invoke-powershell-static.ps1, and node --test test-openspec-machine-truth.mjs (24/24) all green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(scripts): fold GPU-attribution gap into complete, fix MIG-gating and test cleanup (PR #511 review round 2) Three round-2 findings on the GPU baseline harness: - Get-EnvironmentFingerprint: gpu_fingerprint_scope='first_gpu_only' (a multi-GPU host) was disclosure-only -- `complete` was computed from the five base fields before the scope was known, so a report that has admittedly NOT attributed every relevant GPU could still report complete:true and silently suppress the wrapper's "SHALL NOT be used to set SLOs or admission parameters" warning. `complete` now also requires gpu_fingerprint_scope != 'first_gpu_only'. - Get-GpuInventorySnapshot: software_queue_required was gated on consumer_grade_all AND NOT mig_available_any. On a non-consumer, non-MIG fleet (e.g. a lone RTX A6000, which Test-ConsumerRtxGpuName excludes but which does not support MIG at all), that reported software_queue_required=false with no MIG route in fact available. Software queuing is now required whenever MIG is unavailable, regardless of consumer/professional classification. - test-measure-session-baseline.ps1: the default-OutputPath cleanup deleted every new file under artifacts/gpu-baseline/, not just the one this test produced -- a concurrent harness invocation sharing the checkout would have its evidence collaterally deleted. Now deletes only "$($defaultReport.run_id).json". Also strengthened Assert-ReportSchemaShape's `complete` expectation and added regression tests for the professional/no-MIG inventory shape and the multi-GPU complete=false path. Verified: pwsh + Windows PowerShell 5.1 test-measure-session-baseline.ps1, invoke-powershell-static.ps1, and node --test test-openspec-machine-truth.mjs (24/24) all green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * revert(ci): defer harness CI wiring until the open mechanism debt closes ci.yml is a classified verification-mechanism path (design gate infrastructure, Lane G minimum + self-referential bootstrap scope); wiring test-measure-session-baseline.ps1 into CI from this measurement-harness PR would collide with the open mechanism-hardening-2 ledger entry owned by PR #513. The wiring moves to a follow-up alongside issue #516 (CI coverage for the streaming pytest suite) after fixpoint closure. Refs #516 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(scripts): gpu-baseline r2 - bootstrap registration, honest kit-version provenance, MIG-driven queue flag (review r2) * fix(scripts): honest fixture provenance binding for baseline fingerprint (review r4, operator-delegated adjudication) * fix(governance): revert harness bootstrap-layer per #520 ruling; rebind hifi row to #507 squash 一、撤除 bootstrap 層(依 #520 裁決=docs/agents/self-referential-bootstrap.md §2.1,PR #521): 量測 harness 的報告無任何 gate 機器消費者,不屬 mechanism surface,不入 ledger。 classifier 擴張+open entry gpu-session-baseline-harness+evidence 一併撤除, scripts/lib/self-referential-bootstrap.ps1、scripts/tests/test-self-referential-bootstrap.ps1、 scripts/self-referential-bootstrap-ledger.json 還原為 origin/main 版本。 機械上這條路也是死路:base-pinned 裁決者以 base 版 classifier 驗證新 entry 宣告的 mechanism paths,同 PR 擴張 classifier 永遠無法讓自己的 entry 合法(實測兩輪 pr-metadata-contract-diagnostic 均以 not classified verification-mechanism paths 拒絕)。 二、rebind migrate-console-to-hifi-design row:#507 squash 後該 row 仍綁 pre-squash commit af60c29(已被丟棄,CI checkout 抓不到)→ 全部後續 PR 的 machine-truth test 25 紅。依 #482/#501/#512 慣例 rebind 到 landed squash 4187102。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(scripts): gpu-baseline r5 — unknown-runtime honesty, session-scoped lease counts, fixture overwrite guard (review r5) PR #511 review r5, three of four threads: 1. PRRT_kwDOSPoer86YeUls — an unreachable/malformed /api/runtime/status left every observed count null, and the fixture-binding defaults coerced those nulls to 0, so an UNKNOWN runtime state was published under the 'no_live_session_observed' (observed-idle) label with complete=true beside a declared fixture. Adds a distinct fixture_binding_scope='runtime_state_unknown' that withdraws completeness and names the failed probe (GET /api/runtime/status). A positive observation still outranks the unknown; an observed 0/0 idle host keeps its previous semantics. 2. PRRT_kwDOSPoer86YeUlw — per-role lease counts are summed across every sessions.items[] entry while total_kit_vram_mb is one host-wide sample, so a host serving 2+ sessions mixed multiple primaries/spectators against a single VRAM number. Takes the reviewer's reject option: the aggregate counts are kept (they are real observations) but session_scope='multi_session_aggregate' is published and the 1-primary+k-spectator watermark interpretation is marked measured=false with reason 'non-isolated multi-session snapshot; per-session VRAM attribution unavailable in this slice'. Exactly one active session yields session_scope='single_session' and keeps current semantics. 3. PRRT_kwDOSPoer86YeUly — -FixturePath and -OutputPath resolving to the same file made Set-Content truncate the fixture with the report, destroying the very artifact the report fingerprints. Canonicalises both ([System.IO.Path]::GetFullPath, case-insensitive only on Windows) and throws before any write. PRRT_kwDOSPoer86YeUlo (P1, bootstrap mechanism-path regression) is NOT addressed here and is moot as of 286bbac on this branch: per the #520 ruling the harness is not a mechanism surface, and the three measure-session-baseline classifier patterns the thread asked the test to pin were removed. Adding them to $expectedMechanismPaths now would fail the suite; re-registering them would revert an owner ruling. Verified on Windows: test-measure-session-baseline.ps1 (all groups pass), test-self-referential-bootstrap.ps1 (all assertions pass), Invoke-ScriptAnalyzer -Severity Error on the changed .ps1 files = 0. * fix(scripts): gpu-baseline r6 — reject malformed runtime counts, require observed primary, finite TTFF (review r6) - Get-SessionVramWatermark / Get-EnvironmentFingerprint: a non-null-but- unparseable observed_active_session_count / observed_kit_instance_binding_count (coordinator version skew, e.g. a string) was silently coerced to 0 via a try/catch default, relabeling an UNKNOWN runtime state as an OBSERVED zero. New ConvertTo-NonNegativeIntOrNull helper returns null instead of 0 on parse failure; both call sites now treat that null the same as a missing probe (new 'malformed_runtime_observation' session scope; runtime_state_unknown fixture-binding scope). - Get-SessionVramWatermark: exactly one active session was enough to accept the "1 primary + k spectator" watermark interpretation even when zero primary viewers had joined (idle-but-created or spectator-only session). Now requires observed_primary_lease_count == 1. - New-OptionalMeasurement TTFF validator only checked ">= 0", which +Infinity satisfies; now also rejects non-finite values. - openspec/lifecycle-ledger.json: added scripts/lib/measure-session-baseline.ps1 to the change's evidence_refs (the entire measurement implementation lives there; only the CLI wrapper and test were previously listed). Addresses the three still-open findings from the chatgpt-codex-connector review on c759057, plus the infinite-TTFF gap from an earlier round that was never landed. Co-authored-by: monkey1sai <26239865+monkey1sai@users.noreply.github.com> * fix(scripts): gpu-baseline r7 — keep kit process-count fields in every report shape (review r7) gpu-session-baseline-report/v1 的兩個早退路徑補齊 kit_process_count 與 kit_process_vram_unreadable_count:查詢失敗=null(未知非零)、查詢成功但無 Kit process=0(觀測到的真零),consumer 不再因 host 狀態拿到不同 shape。 測試補四條斷言鎖住兩態。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: monkey1sai <xshiujj@gmail.com> Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
One-line follow-up promised on the #481 review thread: the isolated-branch-stack-browser-e2e row rebinds from the squash-discarded branch commit to the landed #481 squash (permanently reachable trusted-base history), restoring the full verifier path.
Validation: machine-truth 24/24 locally after the rebind.
🤖 Generated with Claude Code
https://claude.ai/code/session_015QTVFY89rS2xRwRB2TpFP6
Summary by CodeRabbit