Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 2 additions & 37 deletions .github/workflows/agent-isolation.yml
Original file line number Diff line number Diff line change
@@ -1,44 +1,9 @@
name: Agent isolation
# Runs on every pull request and on pushes to the same branches as CI, so `real-docker` can be a required check.
on:
push:
branches: [main]
paths:
- 'agents/**'
- 'git/clone.ts'
- 'test/agent-*.test.ts'
- 'runner/question-*.ts'
- 'runner/questions.ts'
- 'runner/planning*.ts'
- 'runner/workspace.ts'
- 'runner/runner-repository.ts'
- 'runner/execution.ts'
- 'core/run-audit.ts'
- 'runner/review.ts'
- 'runner/store.ts'
- 'git/history.ts'
- 'test/runner-workspace.test.ts'
- 'test/vitest-config.test.ts'
- 'vitest.config.ts'
- '.github/workflows/agent-isolation.yml'
branches: [main, 'codex/**']
pull_request:
paths:
- 'agents/**'
- 'git/clone.ts'
- 'test/agent-*.test.ts'
- 'runner/question-*.ts'
- 'runner/questions.ts'
- 'runner/planning*.ts'
- 'runner/workspace.ts'
- 'runner/runner-repository.ts'
- 'runner/execution.ts'
- 'core/run-audit.ts'
- 'runner/review.ts'
- 'runner/store.ts'
- 'git/history.ts'
- 'test/runner-workspace.test.ts'
- 'test/vitest-config.test.ts'
- 'vitest.config.ts'
- '.github/workflows/agent-isolation.yml'
permissions:
contents: read
jobs:
Expand Down
10 changes: 7 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ permissions:
jobs:
test:
runs-on: ubuntu-latest
# The longest recent run took 20 min, about half of this limit. A hung browser suite would otherwise hold the
# runner for GitHub's default of 360 min.
timeout-minutes: 45
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
Expand All @@ -16,8 +19,9 @@ jobs:
cache: npm
- run: npm ci --ignore-scripts
- run: npm run typecheck
# The Docker agent suites run one file at a time in the Agent isolation workflow; running them here
# would put them in parallel against the same image tag and daemon.
- 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
# The Docker-backed files run one at a time in the Agent isolation workflow; running them here would put them in
# parallel against the same image tag and daemon. Exclude exactly the dockerTests list in vitest.config.ts;
# test/vitest-config.test.ts fails if the two differ.
- 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
- run: npx playwright install --with-deps chromium
- run: npm run test:browser
48 changes: 48 additions & 0 deletions .github/workflows/live-probes.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Live probes
# Runs the live Claude startup probes against the real Claude service. It is not a pull request check: it runs
# nightly on the default branch and when started by hand. See docs/implementation/ci.md.
on:
workflow_dispatch:
schedule:
- cron: '23 6 * * *'
permissions:
contents: read
concurrency:
group: live-probes
cancel-in-progress: false
jobs:
live-probes:
runs-on: ubuntu-latest
# The probes' own time limits total 33 min (6, 8, 8 and 11). agent-container and agent-supervisor may each spend
# up to 10 min building the image before their probes; agent-question builds inside its probe's own 11 min. The
# teardown hooks have Vitest limits that total 9 min: agent-container 2 after each test and 2 at the end,
# agent-supervisor 3 and agent-question 2. That is 62 min, plus setup. These are only Vitest's limits: the afterAll
# hooks in agent-container and agent-question call docker through spawnSync with no timeout of their own, and
# Vitest's hook timer cannot fire while such a call blocks. The 75 min job limit caps the run.
timeout-minutes: 75
steps:
# Fail at once when the secret is missing, so a missing secret never looks like a passing run.
- name: Require the Claude token
env:
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
run: |
if [ -z "$CLAUDE_CODE_OAUTH_TOKEN" ]; then
echo "::error::The repository secret CLAUDE_CODE_OAUTH_TOKEN is not set. Add it to run the live probes."
exit 1
fi
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '26.7.0'
cache: npm
- run: npm ci --ignore-scripts
# The docker project runs these files one at a time, as in the Agent isolation workflow. The filter keeps only
# the tests whose titles end in "(live Claude)".
- name: Run the live Claude probes
env:
CODEBOOST_RUN_AUTH_PROBES: '1'
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
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
# Vitest exits 0 when it skips every probe, so check that each probe passed and nothing else ran.
- name: Check that every probe passed
run: node scripts/live-probes.ts check live-probes.json
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ npm run typecheck
npm test
```

Tests create disposable local repositories and exercise command checks in disposable credential-free containers. They do not invoke model providers or access GitHub.
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.

## Guarded GitHub merge

Expand Down
4 changes: 2 additions & 2 deletions docs/designs/codeboost-plan-indexed-review.md
Original file line number Diff line number Diff line change
Expand Up @@ -1922,7 +1922,7 @@ Read each row left to right: finish and validate step 1 before step 2 within tha
| 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. |
| 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. |
| 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. |
| 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. |
| 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. |
| 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. |
| 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. |
| 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. |
Expand Down Expand Up @@ -1981,7 +1981,7 @@ F, G and H ran together within these ownership boundaries. G and H are done; for

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.

**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.
**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.

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.

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

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

## What the gate proves

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

## Limits of this gate

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