Repository navigation
fix(strix): record cached sandbox lifecycle diagnostics - #2573
seonghobae wants to merge 59 commits into
Conversation
fast-mlsirm 0.11.3's published PyPI description carried the internal commercial boundary: an enterprise sales gate, a KRW 2,000,000,000 product gate, buyer and procurement evidence links, and 16 repo-relative links that are 404s on the registry page because only LICENSE and the package sources ship. Checking the live sdist finds 68 such findings; threadweave 0.1.0 and rankweave 0.1.0 carry 3 each, one of them a source module path. The gate reads the description a registry renders - PKG-INFO from an sdist, METADATA from a wheel - rather than the README on disk, because a release is built from a commit and packaging config decides what is included. A repository with no release yet can point it at the README instead. A repository README may link internal design records; that is public development history. The same text on a package page is different, because only the distribution's files exist there and the reader is installing rather than developing. So docs/adr links stay legitimate and only have to be absolute, while docs/superpowers, docs/product, docs/commercial, docs/planning and docs/doctoring are findings. Hard-coded deal values follow the rule the organization already set in fast-mlsirm's acquisition_readiness_gate doctoring record: product quality evidence must not depend on a monetary target. Product vocabulary that merely looks commercial is deliberately not a finding. appguardrail ships a real buyer-diligence subcommand and scopeweave really does check procurement packages; the rule targets internal framing, not a domain. --allow lets a repository adopt the gate before its README is fully converted instead of landing a red check it cannot fix in one PR. No repository calls this yet, so this PR cannot break one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YHVBDaZS5NZT9aQcbRg9Av
The first run against the three repositories that had just been corrected produced 16, 1 and 2 findings, and nearly all of them were wrong. contextual-orchestrator genuinely ships /api/v1/commercial_readiness/latest, /api/v1/saleability_decisions/latest and /api/v1/commercial_due_diligence_rooms/latest, with tests named after them; wardnet's crate genuinely computes commercial readiness snapshots; semantic-data-portal's only finding was the sentence explaining that PRD/TRD records are excluded. The exception for product domain vocabulary was stated in the prose and absent from the regex. So go-to-market-vocabulary and requirement-map now report without failing, and --strict promotes them for a repository that wants them enforced. The mechanical rules keep blocking because they need no judgement: a relative link is dead on the registry page, a quoted module path is plumbing, and a hard-coded deal value is never a product feature. The same pass showed ADRs filed under docs/planning/adrs/ being caught by the docs/planning/ prefix. An ADR is a public design record wherever a repository files it, so the path check exempts it and a test pins both directions. Verified after the change: the live fast_mlsirm-0.11.3.tar.gz still reports 22 blocking findings and 63 under --strict, the corrected fast-mlsirm README is clean, and the three corrected READMEs pass with advisory notes only. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YHVBDaZS5NZT9aQcbRg9Av
pg-llm-batch's README links docs/doctoring/bootstrap-dsn-precedence.md, cli-secret-input.md and postgres-logical-restore.md, and those are operator documentation a package user needs. That repository files operational guidance under the same directory name this one uses for incident records. A worker removed the links to satisfy the gate and restored them in the next commit because they were legitimate - the gate causing damage rather than preventing it. So internal-working-record advises. Nothing is lost: a link into such a directory that is also repo-relative is still blocked by relative-link, which is the mechanical defect, since the page cannot resolve it. An absolute URL to the same file resolves, and whether that audience wants it is judgement. That is now the line across both corrections in this branch: block only what is broken regardless of context, advise on anything that needs to know what the product is. Re-verified: the live fast_mlsirm-0.11.3.tar.gz still reports 22 blocking findings, OriginWeave's seven repo-relative links still block, pg-llm-batch's corrected README passes with 18 advisory notes, and the corrected fast-mlsirm README is clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YHVBDaZS5NZT9aQcbRg9Av
The first revision of this reusable workflow took a free-form `build-command`
string input and interpolated it straight into a `run:` block. A caller could
have passed arbitrary shell into a workflow running in its own repository
context, and it is what ADR 0023 forbids outright: reusable inputs are data and
capability flags, not shell source.
The contract test for the fast-mlsirm reusable workflow in this same branch
series asserts that no input reaches a `run:` body. I did not apply that rule
here and did not notice until the org's own Semgrep gate failed the PR with
yaml.github-actions.security.run-shell-injection. The gate was right.
The input is now `build: sdist | wheel | none`, mapped to a fixed `python -m
build` invocation and validated in-shell so an unexpected value exits 2 rather
than silently building nothing. `dist-path` is passed through env to that step
instead of being read from a scope where it was undefined. A contract test pins
the absence of `build-command` and the absence of any `${{ inputs.* }}` inside
any `run:` body.
Local Semgrep on this file after the change: 0 findings. Contract tests: 19
passed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YHVBDaZS5NZT9aQcbRg9Av
Use the called job's workflow repository and exact workflow SHA for the central checkout, remove the unhashed runtime build install in favor of a pinned uv action and version, validate every sdist/wheel description in an upload set, and reject release-contract links to moving GitHub branches. Regression tests cover workflow identity, immutable build tooling, mutable blob/tree links, and matching/divergent artifact metadata. The operator note now matches the implemented blocking/advisory policy.
…e the consumer root Green step for a8d6261. The 24 specialized cases in test_strix_quick_gate.sh installed the trusted gate/model/binder into $repo_root_dir/scripts/ci and ran ./scripts/ci/strix_quick_gate.sh, so a consumer-root binder lookup could never fail there and masked the #2292 defect. Each case now materializes into $tmp_dir/trusted-source/scripts/ci and runs the gate from that directory with STRIX_REPO_ROOT=$repo_root_dir, which keeps the old repo-root semantics (the gate defaults REPO_ROOT to SCRIPT_DIR/../..). Evidence: - tests/test_strix_trusted_fixture_boundary.py: fails on a8d6261 (CI job 106083294309), passes here. - bash scripts/ci/test_strix_quick_gate.sh on Linux, umask 022: a8d6261 PASS (rc=0, 727s) and this commit PASS (rc=0, 726s). - strix-related pytest (8 files): 242 passed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P5o6j4zfxGPdRaH4Lug8UY
Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
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 |
Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
Current-head hosted admission RCAExact #2573 head
Observed check-run ids: The local exact-tree verification remains recorded separately; it does not replace hosted acceptance. The actionable recovery is to resolve the GitHub account billing lock, then trigger normal current-head admission on the active successor stack. After real Actions jobs start, current-head security results and non-author formal approval remain required. This comment is evidence only, not approval or merge authorization. |
Drop the session GOAL.md and restore .github/actionlint.yaml to main's bytes; main already declares cwlab-ci-isolated and cwlab-control. Full suite under GITHUB_ACTIONS=true: 5351 passed, 4 skipped, 40 subtests.
Reuse protected-main CodeQL workflow bytes to eliminate hosted fallback on the package PR stack. Preserve exact trusted-main control admission and route PR revisions only to CWL CI isolated. Align all three runner contract tests. CI-mode full suite: 5351 passed, 4 skipped, 40 subtests; focused both modes: 46 passed. Independent source and test delta reviews approved, not formal App approvals.
…sted-only-20261009 fix(ci): route package gate to isolated self-hosted runners
There was a problem hiding this comment.
Noema LLM review
The new reusable package-description gate reads its identity from unsupported Actions job-context properties, causing valid callers to fail before inspection. Static probes also checked shell-injection resistance, README path containment, and CodeQL runner selection. The truncated diff and allowed-location list prevent a complete verdict on the Strix implementation and tests.
Reviewed changed lines
.github/workflows/package-description-boundary.yml:152 (RIGHT): job.workflow_repository and the adjacent job.workflow_sha are not supported properties of the Actions job context. Missing properties resolve to empty strings, which the following identity validation rejects..github/workflows/package-description-boundary.yml:100 (RIGHT): The build selector is passed through the environment and restricted by an exact shell case statement. Caller-supplied shell syntax cannot become an executable build command..github/workflows/package-description-boundary.yml:116 (RIGHT): Canonicalizing the README path before checking the caller-root prefix rejects both parent-directory traversal and symlinks resolving outside the checkout..github/workflows/codeql-pr.yml:64 (RIGHT): The exact trusted-main workflow reference retains the central-control group; other references select the isolated group. The adjacent labels expression uses the same predicate, so the changed mapping does not mix groups and labels across branches.
Adversarial validation
.github/workflows/package-description-boundary.yml:152 (RIGHT)confirmed: A legitimate reusable-workflow invocation fails identity validation because the selected job-context properties do not exist. — The Actions job context does not supply workflow_repository or workflow_sha. Missing-property evaluation produces empty strings. The subsequent repository comparison rejects the empty WORKFLOW_REPOSITORY and exits 2 before central checkout or description inspection. This is a static evaluation, not an executed workflow reproduction..github/workflows/package-description-boundary.yml:100 (RIGHT)falsified: A caller can inject shell commands through the build input. — BUILD is an environment value rather than interpolated shell source. The value matches neither sdist nor wheel, so the default case exits 2 before uv runs; the embedded semicolon is not reparsed as shell syntax..github/workflows/package-description-boundary.yml:116 (RIGHT)falsified: README staging can copy a file outside the caller checkout through traversal or a symlink. — realpath -e resolves the candidate before the case statement. An existing external target lacks the canonical caller-root-plus-slash prefix and is rejected before cp; a missing target fails under set -e..github/workflows/codeql-pr.yml:64 (RIGHT)falsified: The runner-selection rewrite routes a PR-authored workflow revision into the central-control group. — The equality predicate is false, selecting CWL CI isolated and the cwlab-ci-isolated label. The labels expression repeats the same predicate; only the exact central main reference selects central control.- Residual risk: Validation was static; no Actions runs or local tests were executed. Findings and probe citations are restricted to the supplied allowed locations. The omitted implementation and tests remain without a formal verdict, and runner disposability and group access require operational evidence.
Findings
- [medium] .github/workflows/package-description-boundary.yml:152 (RIGHT): Resolve the called workflow's identity through a supported mechanism. The Actions job context has neither workflow_repository nor workflow_sha; these are not equivalents of the reusable-workflow OIDC claims job_workflow_ref and job_workflow_sha. Both environment values therefore resolve to empty strings, and every otherwise valid invocation fails the repository check before running the inspector. Obtain and validate the called-workflow identity through an authenticated supported source, retain the exact-SHA checkout, and add a real cross-repository invocation regression. Do not substitute github.workflow_sha, which identifies the caller in a reusable workflow.
- Result: REQUEST_CHANGES
- Head SHA:
44eba247e76ae5be5c32927a1374c70aca328557 - Reviewer credential:
noema-review-github-app-refresh - Actor:
cwl-noema-review[bot]
There was a problem hiding this comment.
Pull request overview
OpenCode reviewed the current-head product diff. Coverage is a separate gate.
Changed files
.github/actionlint.yaml— repository behavior.github/workflows/codeql-pr.yml— GitHub Actions review job.github/workflows/package-description-boundary.yml— GitHub Actions review jobCHANGELOG.d/20260920-strix-trusted-binder-runtime-fixture.md— repository behaviorCHANGELOG.d/20261002-strix-sandbox-lifecycle-diagnostics.md— repository behaviorCHANGELOG.md— repository behaviordocs/doctoring/package-description-boundary.md— operator or user guidancedocs/doctoring/strix-sandbox-lifecycle-diagnostics-20261002.md— operator or user guidancedocs/product-technical-gap-baseline.md— operator or user guidancescripts/ci/package_description_boundary.py— review and security gate shell pathscripts/ci/strix_quick_gate.sh— review and security gate shell pathscripts/ci/strix_timeout_compat.py— review and security gate shell pathscripts/ci/test_strix_quick_gate.sh— review and security gate shell pathtests/fixtures/strix_login_as_guest_1_5_3.LICENSE.txt— regression suitetests/fixtures/strix_login_as_guest_1_5_3.py— regression suitetests/test_audit_org_codeql_coverage.py— regression suitetests/test_codeql_pr_workflow_contract.py— regression suitetests/test_materialize_base_python_requirements.py— regression suitetests/test_organization_commercial_readiness_loop_receipt_contract.py— regression suitetests/test_package_description_boundary.py— regression suitetests/test_required_review_runner_image_contract.py— regression suitetests/test_sandboxed_web_e2e.py— regression suitetests/test_scheduler_and_codeql_dispatch_runner_image_contract.py— regression suitetests/test_strix_llm_timeout_contract.py— regression suitetests/test_strix_sandbox_diagnostics.py— regression suite
Changed behavior
flowchart LR
PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
Evidence --> S1["Repository file: actionlint.yaml"]
S1 --> I1["repository behavior"]
I1 --> R1["Review risk: Repository file: actionlint.yaml"]
R1 --> V1["required checks"]
Evidence --> S2["Workflow: codeql-pr.yml"]
S2 --> I2["GitHub Actions review job"]
I2 --> R2["Review risk: Workflow: codeql-pr.yml"]
R2 --> V2["actionlint plus required checks"]
Evidence --> S3["Workflow: package-description-boundary.yml"]
S3 --> I3["GitHub Actions review job"]
I3 --> R3["Review risk: Workflow: package-description-boundary.yml"]
R3 --> V3["actionlint plus required checks"]
Evidence --> S4["Repository file: 20260920-strix-trusted-binder-runtime-fixture.md"]
S4 --> I4["repository behavior"]
I4 --> R4["Review risk: Repository file: 20260920-strix-trusted-binder-runtime-fixture.md"]
R4 --> V4["required checks"]
Evidence --> S5["Repository file: 20261002-strix-sandbox-lifecycle-diagnostics.md"]
S5 --> I5["repository behavior"]
I5 --> R5["Review risk: Repository file: 20261002-strix-sandbox-lifecycle-diagnostics.md"]
R5 --> V5["required checks"]
Evidence --> S6["Repository file: CHANGELOG.md"]
S6 --> I6["repository behavior"]
I6 --> R6["Review risk: Repository file: CHANGELOG.md"]
R6 --> V6["required checks"]
Evidence --> S7["Docs: package-description-boundary.md (3 files)"]
S7 --> I7["operator or user guidance"]
I7 --> R7["Review risk: Docs: package-description-boundary.md (3 files)"]
R7 --> V7["docs review"]
Evidence --> S8["CI script: package_description_boundary.py"]
S8 --> I8["review and security gate shell path"]
I8 --> R8["Review risk: CI script: package_description_boundary.py"]
R8 --> V8["bash -n plus Strix self-test"]
Evidence --> S9["CI script: strix_quick_gate.sh"]
S9 --> I9["review and security gate shell path"]
I9 --> R9["Review risk: CI script: strix_quick_gate.sh"]
R9 --> V9["bash -n plus Strix self-test"]
Evidence --> S10["CI script: strix_timeout_compat.py"]
S10 --> I10["review and security gate shell path"]
I10 --> R10["Review risk: CI script: strix_timeout_compat.py"]
R10 --> V10["bash -n plus Strix self-test"]
Evidence --> S11["CI script: test_strix_quick_gate.sh"]
S11 --> I11["review and security gate shell path"]
I11 --> R11["Review risk: CI script: test_strix_quick_gate.sh"]
R11 --> V11["bash -n plus Strix self-test"]
Evidence --> S12["Test: strix_login_as_guest_1_5_3.LICENSE.txt (2 files)"]
S12 --> I12["regression suite"]
I12 --> R12["Review risk: Test: strix_login_as_guest_1_5_3.LICENSE.txt (2 files)"]
R12 --> V12["targeted test run"]
Evidence --> S13["Test: test_audit_org_codeql_coverage.py (10 files)"]
S13 --> I13["regression suite"]
I13 --> R13["Review risk: Test: test_audit_org_codeql_coverage.py (10 files)"]
R13 --> V13["targeted test run"]
Findings
No source-backed product finding is synthesized from the coverage gate. A coverage miss belongs in the status comment.
- Head SHA:
44eba247e76ae5be5c32927a1374c70aca328557 - Workflow run: 38507530699
- Workflow attempt: 1
- Coverage gate:
failure
Review outcome
Coverage is a gate, not the review. This body reviews the changed product files.
Changed-File Evidence Map
flowchart LR
PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
Evidence --> S1["Repository file: actionlint.yaml"]
S1 --> I1["repository behavior"]
I1 --> R1["Review risk: Repository file: actionlint.yaml"]
R1 --> V1["required checks"]
Evidence --> S2["Workflow: codeql-pr.yml"]
S2 --> I2["GitHub Actions review job"]
I2 --> R2["Review risk: Workflow: codeql-pr.yml"]
R2 --> V2["actionlint plus required checks"]
Evidence --> S3["Workflow: package-description-boundary.yml"]
S3 --> I3["GitHub Actions review job"]
I3 --> R3["Review risk: Workflow: package-description-boundary.yml"]
R3 --> V3["actionlint plus required checks"]
Evidence --> S4["Repository file: 20260920-strix-trusted-binder-runtime-fixture.md"]
S4 --> I4["repository behavior"]
I4 --> R4["Review risk: Repository file: 20260920-strix-trusted-binder-runtime-fixture.md"]
R4 --> V4["required checks"]
Evidence --> S5["Repository file: 20261002-strix-sandbox-lifecycle-diagnostics.md"]
S5 --> I5["repository behavior"]
I5 --> R5["Review risk: Repository file: 20261002-strix-sandbox-lifecycle-diagnostics.md"]
R5 --> V5["required checks"]
Evidence --> S6["Repository file: CHANGELOG.md"]
S6 --> I6["repository behavior"]
I6 --> R6["Review risk: Repository file: CHANGELOG.md"]
R6 --> V6["required checks"]
Evidence --> S7["Docs: package-description-boundary.md (3 files)"]
S7 --> I7["operator or user guidance"]
I7 --> R7["Review risk: Docs: package-description-boundary.md (3 files)"]
R7 --> V7["docs review"]
Evidence --> S8["CI script: package_description_boundary.py"]
S8 --> I8["review and security gate shell path"]
I8 --> R8["Review risk: CI script: package_description_boundary.py"]
R8 --> V8["bash -n plus Strix self-test"]
Evidence --> S9["CI script: strix_quick_gate.sh"]
S9 --> I9["review and security gate shell path"]
I9 --> R9["Review risk: CI script: strix_quick_gate.sh"]
R9 --> V9["bash -n plus Strix self-test"]
Evidence --> S10["CI script: strix_timeout_compat.py"]
S10 --> I10["review and security gate shell path"]
I10 --> R10["Review risk: CI script: strix_timeout_compat.py"]
R10 --> V10["bash -n plus Strix self-test"]
Evidence --> S11["CI script: test_strix_quick_gate.sh"]
S11 --> I11["review and security gate shell path"]
I11 --> R11["Review risk: CI script: test_strix_quick_gate.sh"]
R11 --> V11["bash -n plus Strix self-test"]
Evidence --> S12["Test: strix_login_as_guest_1_5_3.LICENSE.txt (2 files)"]
S12 --> I12["regression suite"]
I12 --> R12["Review risk: Test: strix_login_as_guest_1_5_3.LICENSE.txt (2 files)"]
R12 --> V12["targeted test run"]
Evidence --> S13["Test: test_audit_org_codeql_coverage.py (10 files)"]
S13 --> I13["regression suite"]
I13 --> R13["Review risk: Test: test_audit_org_codeql_coverage.py (10 files)"]
R13 --> V13["targeted test run"]
OpenCode Review Overview
Coverage evidence did not pass, so approval is blocked. The formal pull-request review is the source-backed diff review, not this status comment. |
RCA boundary
Current-head runs #2261 and #2550 passed gateway health, provider-route, and chat preflight, then failed guest authentication against in-container Caido at
127.0.0.1:48080. The evidence identifies a sandbox-bootstrap failure, not provider 429 or an LLM failure. Historical logs do not contain an OCI image digest or lifecycle state, so they cannot distinguish slow startup from a terminal process failure.Change
The trusted Strix launcher now records only already-cached, SDK-bound Docker metadata around guest authentication: phase,
freshness=cached, image configuration ID, lifecycle status, exit code, and OOM flag. It does not reload Docker, query the daemon, read logs, look up images, change authentication, skip terminal containers, alter retries/deadlines/backend selection, or call settings loading. Unsupported SDK/ABI bindings emit a fixed unavailable marker and leave the scan behavior unchanged.Verification
scripts/ci/strix_timeout_compat.py: statement·branch coverage 100%; docstrings 100%; diff check passed.This diagnostic does not claim Caido recovery, a green Strix scan, hosted acceptance, or merge authorization.
Developer experience: future failed scans emit bounded lifecycle context instead of forcing operators to infer sandbox state from a connection refusal.
User experience: incomplete sandbox scans remain failed evidence; no zero-finding result is promoted to a security pass.
🤖 Generated with Claude Code