Skip to content

Commit ba8294d

Browse files
mchwangclaude
andauthored
F6c: run every T9 suite in CI and add the live probe workflow (#177)
* Run real-docker on every pull request and pin CI's Docker excludes Remove the Agent isolation workflow's path filter and run it on pushes to the same branches as CI, so `real-docker` can be a required check: a required check that a path filter skips never reports. Stop excluding test/agent-adapter.test.ts from the CI `test` job. It has never started Docker or a vendor CLI: since D4 (#47) its cases test pure parsers and budgets or refuse before anything is allocated, and it passes with no Docker binary on PATH. It was never on vitest.config.ts's Docker list. The excludes now equal that list, and a test fails if they differ or if real-docker gains a path filter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Add a nightly and manual Live probes workflow for the Claude startup probes The workflow runs on workflow_dispatch and a nightly schedule, never on a pull request or push, so it is not a required check. It reads the repository secret CLAUDE_CODE_OAUTH_TOKEN and fails at once when the secret is empty. It runs only the four live Claude probes, selected by a shared "(live Claude)" title suffix, through the docker Vitest project so the files run one at a time. Vitest exits 0 when it skips every test, so scripts/live-probes.ts then checks the JSON report: every listed probe must pass and no other test may run. Tests pin the triggers, the command, the secret guard, the probe list against the test files, and the report check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Document the CI workflows, required checks and what remains for T9 Add docs/implementation/ci.md: which workflow and job runs which tests on which triggers, the required checks and secret a repository administrator must set, the live probe job, and how to record the planning fixtures again. Link it from the README, agent isolation and planning acceptance, and update the T9 status in the plan. T9 stays unticked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Size the Live probes timeout from the probes' own limits Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Check every test the live probe switch enables, and correct the build-time note The probe-name check now finds every test inside a CODEBOOST_RUN_AUTH_PROBES gate and requires the "(live Claude)" suffix and a LIVE_PROBES entry, so an unsuffixed gated test cannot be silently skipped by the workflow's -t filter. Unrecognized gate forms fail the check. The workflow comment now says only agent-container and agent-supervisor build the image in beforeAll (53 min of limits, under 75). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Pin live probe full names and the CI test command Parse each live probe file with the Vite (oxc) parser instead of counting braces. The probe switch may only gate an if block of tests and call-free declarations, or it.runIf; the gated tests must match LIVE_PROBES by Vitest full name. The CI test job's npm test command may hold only --exclude <file> pairs after --. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Declare vite and close probe-switch gaps in the CI config test Declare vite 8.3.0 as a direct dev dependency, since the test imports parseSync from it. Count every textual occurrence of the probe switch in each probe file and require each to be a recognized gate; treat a template literal without expressions as a mention. Scan every .ts file under test/, not only *.test.ts, for the switch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Refuse skipped or soft-failing gate jobs and dead probe gates Assert that the required test and real-docker jobs and the live-probes job carry no if or continue-on-error at job or step level. Count a probe switch gate only at module load or in a describe callback. Scan every JS/TS source extension under test/ for the switch. Document the 60-day schedule disable. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Refuse unmodelled describes around probes and pin the required check jobs - Throw when a describe around a gated probe has a non-literal title or a modifier such as .each or .for, instead of computing a wrong full name. - Derive the live probe -t filter and the suffix checks from LIVE_PROBE_MARKER. - Pin the test and real-docker jobs: one job per workflow, keys runs-on, timeout-minutes and steps only (no name, no matrix), exact steps. - Give the CI test job a 45 min timeout (longest recent run: 20 min) and check that all three workflows use the same Node version. - Document that renaming either required job breaks the required checks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Pin workflow keys and live-probes steps; reject nested probe gates - Allow-list each workflow's top-level keys and the live-probes job keys, and pin the live-probes steps exactly. - Accept a probe gate only as a statement directly in the module body or in a describe callback body, not inside another if, block or expression. - Docs: say "variable declarations", list the pinned steps of each job. - live-probes.yml: include the teardown hooks in the timeout arithmetic. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Tighten gated-block declarations, pin the token step and correct the teardown comment - A gated if block may declare only const or let names with a function expression or a constant value; a var or an assignment such as (on = true) now fails the config test. - Pin the live-probes token step's run text exactly. - Say the teardown figures are Vitest's limits, that the afterAll docker calls have no timeout of their own, and that the job limit caps the run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Pin the Vitest projects exactly and refuse option objects and computed titles in probe files The scheduling test now compares the whole Vitest config, so an extra key such as an exclude fails it. Gated tests and the describes around them must take exactly a literal title, a function and an optional timeout. Every it/test/describe title in a probe file must be a literal, so the marker check sees each one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Refuse probe-file test calls that reach it/test/describe through unmodeled links A call such as it.each`table`('title', fn) has a tagged template in its callee chain, so the title check skipped it. suiteCall now throws when the chain reaches it, test or describe through a tagged template, computed member, parentheses or a TypeScript wrapper. it.each([...])(title, fn) stays modeled with the literal title check. The comment and ci.md now state exactly what is enforced. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Pin the package scripts both gating jobs call Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Refuse test.only in browser specs and pin the Playwright config Set forbidOnly: true in playwright.config.ts and pin the whole config in test/vitest-config.test.ts, so a committed .only, a grep or a narrower testDir fails the test job. In ci.md, state that only top-level test/*.test.ts files run, and that the static probe-title check does not see a marker added by a .each/.for placeholder (the live-probes report check refuses that test). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 04b9973 commit ba8294d

15 files changed

Lines changed: 788 additions & 111 deletions

‎.github/workflows/agent-isolation.yml‎

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,9 @@
11
name: Agent isolation
2+
# Runs on every pull request and on pushes to the same branches as CI, so `real-docker` can be a required check.
23
on:
34
push:
4-
branches: [main]
5-
paths:
6-
- 'agents/**'
7-
- 'git/clone.ts'
8-
- 'test/agent-*.test.ts'
9-
- 'runner/question-*.ts'
10-
- 'runner/questions.ts'
11-
- 'runner/planning*.ts'
12-
- 'runner/workspace.ts'
13-
- 'runner/runner-repository.ts'
14-
- 'runner/execution.ts'
15-
- 'core/run-audit.ts'
16-
- 'runner/review.ts'
17-
- 'runner/store.ts'
18-
- 'git/history.ts'
19-
- 'test/runner-workspace.test.ts'
20-
- 'test/vitest-config.test.ts'
21-
- 'vitest.config.ts'
22-
- '.github/workflows/agent-isolation.yml'
5+
branches: [main, 'codex/**']
236
pull_request:
24-
paths:
25-
- 'agents/**'
26-
- 'git/clone.ts'
27-
- 'test/agent-*.test.ts'
28-
- 'runner/question-*.ts'
29-
- 'runner/questions.ts'
30-
- 'runner/planning*.ts'
31-
- 'runner/workspace.ts'
32-
- 'runner/runner-repository.ts'
33-
- 'runner/execution.ts'
34-
- 'core/run-audit.ts'
35-
- 'runner/review.ts'
36-
- 'runner/store.ts'
37-
- 'git/history.ts'
38-
- 'test/runner-workspace.test.ts'
39-
- 'test/vitest-config.test.ts'
40-
- 'vitest.config.ts'
41-
- '.github/workflows/agent-isolation.yml'
427
permissions:
438
contents: read
449
jobs:

‎.github/workflows/ci.yml‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ permissions:
88
jobs:
99
test:
1010
runs-on: ubuntu-latest
11+
# The longest recent run took 20 min, about half of this limit. A hung browser suite would otherwise hold the
12+
# runner for GitHub's default of 360 min.
13+
timeout-minutes: 45
1114
steps:
1215
- uses: actions/checkout@v4
1316
- uses: actions/setup-node@v4
@@ -16,8 +19,9 @@ jobs:
1619
cache: npm
1720
- run: npm ci --ignore-scripts
1821
- run: npm run typecheck
19-
# The Docker agent suites run one file at a time in the Agent isolation workflow; running them here
20-
# would put them in parallel against the same image tag and daemon.
21-
- run: npm test -- --exclude test/agent-container.test.ts --exclude test/agent-network.test.ts --exclude test/agent-adapter.test.ts --exclude test/agent-supervisor.test.ts --exclude test/agent-gate.test.ts --exclude test/agent-question.test.ts --exclude test/agent-planning.test.ts --exclude test/runner-workspace.test.ts
22+
# The Docker-backed files run one at a time in the Agent isolation workflow; running them here would put them in
23+
# parallel against the same image tag and daemon. Exclude exactly the dockerTests list in vitest.config.ts;
24+
# test/vitest-config.test.ts fails if the two differ.
25+
- run: npm test -- --exclude test/agent-container.test.ts --exclude test/agent-gate.test.ts --exclude test/agent-network.test.ts --exclude test/agent-planning.test.ts --exclude test/agent-question.test.ts --exclude test/agent-supervisor.test.ts --exclude test/runner-workspace.test.ts
2226
- run: npx playwright install --with-deps chromium
2327
- run: npm run test:browser

‎.github/workflows/live-probes.yml‎

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: Live probes
2+
# Runs the live Claude startup probes against the real Claude service. It is not a pull request check: it runs
3+
# nightly on the default branch and when started by hand. See docs/implementation/ci.md.
4+
on:
5+
workflow_dispatch:
6+
schedule:
7+
- cron: '23 6 * * *'
8+
permissions:
9+
contents: read
10+
concurrency:
11+
group: live-probes
12+
cancel-in-progress: false
13+
jobs:
14+
live-probes:
15+
runs-on: ubuntu-latest
16+
# The probes' own time limits total 33 min (6, 8, 8 and 11). agent-container and agent-supervisor may each spend
17+
# up to 10 min building the image before their probes; agent-question builds inside its probe's own 11 min. The
18+
# teardown hooks have Vitest limits that total 9 min: agent-container 2 after each test and 2 at the end,
19+
# agent-supervisor 3 and agent-question 2. That is 62 min, plus setup. These are only Vitest's limits: the afterAll
20+
# hooks in agent-container and agent-question call docker through spawnSync with no timeout of their own, and
21+
# Vitest's hook timer cannot fire while such a call blocks. The 75 min job limit caps the run.
22+
timeout-minutes: 75
23+
steps:
24+
# Fail at once when the secret is missing, so a missing secret never looks like a passing run.
25+
- name: Require the Claude token
26+
env:
27+
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
28+
run: |
29+
if [ -z "$CLAUDE_CODE_OAUTH_TOKEN" ]; then
30+
echo "::error::The repository secret CLAUDE_CODE_OAUTH_TOKEN is not set. Add it to run the live probes."
31+
exit 1
32+
fi
33+
- uses: actions/checkout@v4
34+
- uses: actions/setup-node@v4
35+
with:
36+
node-version: '26.7.0'
37+
cache: npm
38+
- run: npm ci --ignore-scripts
39+
# The docker project runs these files one at a time, as in the Agent isolation workflow. The filter keeps only
40+
# the tests whose titles end in "(live Claude)".
41+
- name: Run the live Claude probes
42+
env:
43+
CODEBOOST_RUN_AUTH_PROBES: '1'
44+
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
45+
run: npx vitest run --project docker -t '\(live Claude\)$' --reporter=default --reporter=json --outputFile=live-probes.json test/agent-container.test.ts test/agent-question.test.ts test/agent-supervisor.test.ts
46+
# Vitest exits 0 when it skips every probe, so check that each probe passed and nothing else ran.
47+
- name: Check that every probe passed
48+
run: node scripts/live-probes.ts check live-probes.json

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ npm run typecheck
1414
npm test
1515
```
1616

17-
Tests create disposable local repositories and exercise command checks in disposable credential-free containers. They do not invoke model providers or access GitHub.
17+
Tests create disposable local repositories and exercise command checks in disposable credential-free containers. They do not invoke model providers or access GitHub. [CI](docs/implementation/ci.md) lists the workflows, the required checks and the live Claude probes.
1818

1919
## Guarded GitHub merge
2020

‎docs/designs/codeboost-plan-indexed-review.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1922,7 +1922,7 @@ Read each row left to right: finish and validate step 1 before step 2 within tha
19221922
| C — guarded merge gate | **C1.** Required-check and branch-rule reads (T12). **C2.** Snapshot/evidence blockers, with unavailable T6 execution evidence blocking merge. **C3.** Head-pinned, base-protected merge and refusal handling (T7). **C4.** Review UI, race regressions and final #21 / PR #23 review. | Before C1, record B0 evidence for the foundation contracts C consumes; existing work must supply that evidence before C4 completion. Continue existing work rather than restarting implemented steps. Release shared runner/UI files after C4 merges. |
19231923
| D — agent isolation | **D1.** Invocation contract and isolated task clone (T1). **D2.** Pinned, restricted container and startup self-test (T1). **D3.** Vendor-only egress and phase/tool enforcement (T2). **D4.** Claude/Codex adapters, cancellation settlement and bounded output. **D5.** Full real-Docker and hostile-input gate for this boundary (T9). | Can run alongside C and E. F requires D5 merged; G's production invocation requires D5. Add regressions with each step; D5 integrates them rather than postponing testing. |
19241924
| E — planning logic | **E1.** Audit existing T18 schema/parser/prompt behavior and remaining #6 gaps. **E2.** Read-only authoring-provider contract and safe prompt/response handling. **E3.** Identity/revision-bound suggestion orchestration using the existing store interface. **E4.** Import, replay, malformed-response and hostile-input acceptance fixtures (T18). | Can run alongside C and D with injected providers. G consumes E4; live invocation waits for D5. Shared schema/store fixes must go through the assigned integration owner. |
1925-
| F — runner and pre-merge automation | **F1.** Before implementation, publish and review the lifecycle/state-holder contract: pending, running, completed, failed, cancelled, stale and closing; legal transitions; ownership and settlement for persisted records, in-memory jobs, subprocesses, admitted HTTP requests and rendered UI; guarded retry; reject-admission → drain requests → cancel/await jobs → close storage. Then implement it and the feedback-event contract under the AGENTS.md async rules. **F2.** Per-item execution, review/reject rounds, pre-PR already-fixed checks, PR opening and hostile-issue eval (build step 5; T9). **F3.** Trusted rebase and ledger mapping (remaining T3). **F4.** Foreign-commit conflict handling (T11). **F5.** Post-rebase attribution/approval refresh and head-bound command execution (T6). **F6.** Required-check refresh, already-fixed check, guarded merge handoff and #22 integration regressions. F owns common CI after C: integrate every T9 suite (Docker, adapter, hostile-input/issue, recorded-output, unit and browser) into required CI, coordinating D's dedicated workflow. T9 remains incomplete until the combined head demonstrably runs and passes every suite. | Starts after C4 and D5 merge and B0 evidence is handed off for F's consumed contracts. Recheck that evidence against merged main before F1; existing T4/T5/T10 behavior is reused rather than rebuilt. F1 owns planning persistence/API additions needed by G. F2's working reject loop supplies the learning dependency. Ask already uses D's invocation contract (`runner/question-container.ts`), so F reuses that path rather than adding a second one. |
1925+
| F — runner and pre-merge automation | **F1.** Before implementation, publish and review the lifecycle/state-holder contract: pending, running, completed, failed, cancelled, stale and closing; legal transitions; ownership and settlement for persisted records, in-memory jobs, subprocesses, admitted HTTP requests and rendered UI; guarded retry; reject-admission → drain requests → cancel/await jobs → close storage. Then implement it and the feedback-event contract under the AGENTS.md async rules. **F2.** Per-item execution, review/reject rounds, pre-PR already-fixed checks, PR opening and hostile-issue eval (build step 5; T9). **F3.** Trusted rebase and ledger mapping (remaining T3). **F4.** Foreign-commit conflict handling (T11). **F5.** Post-rebase attribution/approval refresh and head-bound command execution (T6). **F6.** Required-check refresh, already-fixed check, guarded merge handoff and #22 integration regressions. F owns common CI after C: integrate every T9 suite (Docker, adapter, hostile-input/issue, recorded-output, unit and browser) into required CI, coordinating D's dedicated workflow. T9 remains incomplete until the combined head demonstrably runs and passes every suite. *F6c status:* the workflows are in place (`docs/implementation/ci.md`); required-check settings, a passing run of both required jobs on one head and a green `Live probes` run remain. | Starts after C4 and D5 merge and B0 evidence is handed off for F's consumed contracts. Recheck that evidence against merged main before F1; existing T4/T5/T10 behavior is reused rather than rebuilt. F1 owns planning persistence/API additions needed by G. F2's working reject loop supplies the learning dependency. Ask already uses D's invocation contract (`runner/question-container.ts`), so F reuses that path rather than adding a second one. |
19261926
| G — planning screen | **G1.** Import and plan display UI. **G2.** Authoring and suggestion cards. **G3.** Revision-bound Apply and draft/attachment preservation. **G4.** Real provider/store integration and complete T18 browser/adapter acceptance. | G1 starts after E4 and C4 merge; G1–G3 may use fixtures. G4 waits for D5 and F1's production planning API/persistence contract. Release shared web files after G4. |
19271927
| H — issue prioritization | **H1.** Decide and record ranking policy. **H2.** Issue retrieval/normalization. **H3.** Deterministic ranking with reasons and failure/stale states. **H4.** Issue-list UI and end-to-end checks (build step 8). | H1–H3 can run alongside F/G after the issue-access contract is inspected. H4 waits for G4 to release shared web files. No existing T-ID covers this entire milestone. |
19281928
| I — queue, schedule and recovery | **I1.** Queue admission and persisted transitions. **I2.** Run-window scheduling and cancellation. **I3.** Restart recovery, stale attempts and shutdown draining. **I4.** UI integration and controlled race acceptance (build step 7). | Starts after F6; owns shared runner/store files. UI work waits for G/H to release its exact files. No existing T-ID covers this entire milestone. |
@@ -1981,7 +1981,7 @@ F, G and H ran together within these ownership boundaries. G and H are done; for
19811981
19821982
Built from this review's findings. Each task comes from a specific decision above. Run with Claude Code or Codex, and tick each one as you ship it. Effort ratios assumed: features about 30x, tests about 50x, architecture about 5x.
19831983
1984-
**Status (checked against `main` on 2026-09-26, lane B0).** T1, T2, T4, T5, T10, T13 and T14 meet their Verify lines and are ticked, with evidence under each (T1, T2 and T14 re-checked 2026-09-26 after lane D merged). T9 stays open until lane F6 runs every suite in required CI. Ask calls the `agents/` boundary from `runner/question-container.ts`; it has no host adapter. The planned files `core/segments`, `core/choices` and `core/attribution` were never created. That logic lives in `core/linking.ts` (segments and ledger attribution) and `core/approvals.ts` (approvals and duplicate-segment choices). The Files lines below now name the real files.
1984+
**Status (checked against `main` on 2026-09-26, lane B0).** T1, T2, T4, T5, T10, T13 and T14 meet their Verify lines and are ticked, with evidence under each (T1, T2 and T14 re-checked 2026-09-26 after lane D merged). T9 stays open. Lane F6 (common CI) has added the workflows in `docs/implementation/ci.md`: `test` and `real-docker` run on every pull request with no path filter, and `Live probes` runs the live Claude probes nightly and by hand. T9 can be ticked when a repository administrator requires `test` and `real-docker` on `main`, both pass on the same head, and a `Live probes` run passes with the `CLAUDE_CODE_OAUTH_TOKEN` secret. Ask calls the `agents/` boundary from `runner/question-container.ts`; it has no host adapter. The planned files `core/segments`, `core/choices` and `core/attribution` were never created. That logic lives in `core/linking.ts` (segments and ledger attribution) and `core/approvals.ts` (approvals and duplicate-segment choices). The Files lines below now name the real files.
19851985
19861986
These `T` IDs are requirement identifiers, not the build-order numbers. Current merge-gate work is **build step 4, increment 1 (#21)** and spans parts of T6, T7, and T12; it is unrelated to the numbering of T4. See “Build step 4: scope and progress” for the current increment and remaining milestone criteria. An increment must not mark a broader requirement complete while any of its acceptance criteria remain deferred.
19871987

‎docs/implementation/agent-isolation.md‎

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,16 @@ npm test
1515
`vitest.config.ts` finishes the ordinary test project first, then runs the Docker-backed
1616
files one at a time because they share one image tag and daemon. Use
1717
`npx vitest run --project docker` to rerun only that serial project. The `Agent isolation`
18-
workflow runs the complete gate. The main `CI` workflow skips the Docker project so that
19-
it can cover the ordinary project independently.
18+
workflow's `real-docker` job runs the complete gate on every pull request. The main `CI`
19+
workflow's `test` job skips the Docker-backed files so that it can cover the ordinary
20+
project independently. [CI](ci.md) describes both jobs.
2021

21-
The live vendor probes need real credentials, so CI does not run them. To run them,
22-
set `CODEBOOST_RUN_AUTH_PROBES=1` and `CLAUDE_CODE_OAUTH_TOKEN`. Codex has no live
23-
probe while it is refused (#93). Do not put credentials in an issue, a pull request
24-
or chat.
22+
The live vendor probes need real credentials, so pull requests do not run them. The
23+
`Live probes` workflow runs them every night and when started by hand, with the
24+
repository secret `CLAUDE_CODE_OAUTH_TOKEN` ([CI](ci.md#live-probes)). To run them
25+
locally, set `CODEBOOST_RUN_AUTH_PROBES=1` and `CLAUDE_CODE_OAUTH_TOKEN`. Codex has no
26+
live probe while it is refused (#93). Do not put credentials in an issue, a pull
27+
request or chat.
2528

2629
## What the gate proves
2730

@@ -407,10 +410,16 @@ against real Docker, including two reviews with different Ask owners on one daem
407410

408411
## Limits of this gate
409412

410-
- CI does not run the live vendor probes. Run them locally with credentials before
411-
a release that changes the image, the adapters or the prompts. Codex has no live
412-
probe while it is refused in every phase (#93).
413-
- T9 as a whole is complete only when lane F runs every suite in required CI (F6).
413+
- Pull requests do not run the live vendor probes. The `Live probes` workflow runs them
414+
every night and by hand, and fails if the `CLAUDE_CODE_OAUTH_TOKEN` secret is missing.
415+
A pull request can therefore merge before a probe shows that it broke the Claude
416+
startup path. Start the workflow by hand, or run the probes locally, before a release
417+
that changes the image, the adapters or the prompts. Codex has no live probe while it
418+
is refused in every phase (#93).
419+
- T9 as a whole is not complete yet. Lane F6 has added the workflows ([CI](ci.md)). What
420+
remains: a repository administrator must require `test` and `real-docker` on `main`;
421+
both jobs must pass on the same head after that; and a `Live probes` run must pass
422+
once the secret exists.
414423
- Gitlink mounts and the pre-launch check apply to execute and fix only. In planning, questions and review, `/work`
415424
is a read-only volume, so nothing can be written beneath a gitlink there; that includes `check` attempts, which run
416425
as review. Running an item's `cmd` in a writable task filesystem is not built yet; when it is, each run must call

0 commit comments

Comments
 (0)