Skip to content

Commit 9eb629c

Browse files
authored
Merge pull request #124 from codeacme17/codex/bootstrap-trusted-verifier-sync
Fix trusted verifier and bootstrap authorization
2 parents c0972f4 + 66fc518 commit 9eb629c

13 files changed

Lines changed: 1354 additions & 29 deletions

.github/workflows/issue-dev-loop-evidence.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ jobs:
1616
bootstrap-evidence:
1717
if: >-
1818
github.event_name == 'pull_request' &&
19-
github.head_ref == 'codex/issue-dev-loop' &&
19+
startsWith(github.event.pull_request.head.ref, 'codex/bootstrap-') &&
2020
github.event.pull_request.head.repo.full_name == github.repository &&
21-
github.event.pull_request.user.login == 'codeacme17'
21+
github.event.pull_request.user.login == 'Ethandasw'
2222
runs-on: ubuntu-latest
2323
timeout-minutes: 45
2424
steps:
@@ -105,16 +105,16 @@ jobs:
105105
- name: Protect trusted control plane
106106
if: steps.run.outputs.has_run == 'true'
107107
run: >-
108-
node trusted/loops/issue-dev-loop/scripts/validate-candidate-control-plane.mjs --loop-root candidate/loops/issue-dev-loop --run-id "${{ steps.run.outputs.run_id }}" --base-sha "${{ steps.run.outputs.base_sha }}" --head-sha "${{ github.event.pull_request.head.sha }}"
108+
node control/loops/issue-dev-loop/scripts/validate-candidate-control-plane.mjs --loop-root candidate/loops/issue-dev-loop --run-id "${{ steps.run.outputs.run_id }}" --base-sha "${{ steps.run.outputs.base_sha }}" --head-sha "${{ github.event.pull_request.head.sha }}" --trusted-control-sha "${{ github.event.pull_request.base.sha }}"
109109
110110
- name: Protect append-only loop history
111111
if: steps.run.outputs.has_run == 'true'
112112
run: >-
113-
node trusted/loops/issue-dev-loop/scripts/validate-history.mjs --loop-root candidate/loops/issue-dev-loop --base-ref "${{ steps.run.outputs.base_sha }}"
113+
node control/loops/issue-dev-loop/scripts/validate-history.mjs --loop-root candidate/loops/issue-dev-loop --base-ref "${{ steps.run.outputs.base_sha }}"
114114
115115
- name: Build trusted verifier image
116116
run: >-
117-
docker build --tag echo-ui-loop-verifier:${{ github.run_id }}-${{ github.run_attempt }} --file trusted/loops/issue-dev-loop/scripts/verifier.Dockerfile trusted/loops/issue-dev-loop/scripts
117+
docker build --tag echo-ui-loop-verifier:${{ github.run_id }}-${{ github.run_attempt }} --file control/loops/issue-dev-loop/scripts/verifier.Dockerfile control/loops/issue-dev-loop/scripts
118118
119119
- name: Prepare isolated candidate and baseline volumes
120120
shell: bash
@@ -191,7 +191,7 @@ jobs:
191191
- name: Generate exact-head manifest
192192
if: steps.run.outputs.has_run == 'true' && always()
193193
run: >-
194-
node trusted/loops/issue-dev-loop/scripts/generate-evidence.mjs --loop-root candidate/loops/issue-dev-loop --run-id "${{ steps.run.outputs.run_id }}" --head-sha "${{ github.event.pull_request.head.sha }}" --trusted-workflow-sha "${{ steps.run.outputs.base_sha }}" --workflow-base-sha "${{ github.event.pull_request.base.sha }}" --workflow-run-sha "${{ github.event.pull_request.head.sha }}" --status "${{ steps.verify.outputs.verdict || 'blocked' }}" --baseline-status "${{ steps.verify.outputs.baseline_status || 'blocked' }}" --started-at "${{ steps.verify.outputs.started_at || github.event.pull_request.updated_at }}" --finished-at "${{ steps.verify.outputs.finished_at || github.event.pull_request.updated_at }}" --output "${RUNNER_TEMP}/issue-dev-evidence/manifest.json"
194+
node control/loops/issue-dev-loop/scripts/generate-evidence.mjs --loop-root candidate/loops/issue-dev-loop --run-id "${{ steps.run.outputs.run_id }}" --head-sha "${{ github.event.pull_request.head.sha }}" --trusted-workflow-sha "${{ steps.run.outputs.base_sha }}" --workflow-base-sha "${{ github.event.pull_request.base.sha }}" --workflow-run-sha "${{ github.event.pull_request.head.sha }}" --status "${{ steps.verify.outputs.verdict || 'blocked' }}" --baseline-status "${{ steps.verify.outputs.baseline_status || 'blocked' }}" --started-at "${{ steps.verify.outputs.started_at || github.event.pull_request.updated_at }}" --finished-at "${{ steps.verify.outputs.finished_at || github.event.pull_request.updated_at }}" --output "${RUNNER_TEMP}/issue-dev-evidence/manifest.json"
195195
196196
- name: Upload review evidence
197197
if: steps.run.outputs.has_run == 'true' && always()

loops/issue-dev-loop/LOOP.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,13 @@ Complete the generated handoff with acceptance criteria, scope, TDD seams, requi
7979

8080
Explicitly invoke `$implement`. The orchestrator does not write product code. `$implement` owns TDD at agreed seams, implementation, regular typechecking and targeted tests, the final full suite, `$code-review`, and a local commit. It must not push, create a PR, or merge. Every invocation writes a unique schema-validated result with its invocation ID, timestamps, frozen brief digest, passed checks, and a new commit descending from the prior implementation commit (or the frozen base SHA for the first invocation); record it before PR publication or update.
8181

82-
The recorded implementation commit is the product-code boundary. Later commits may contain only the current run's handoff, sanitized logs, screenshots, and evidence. `record-pr` diffs the implementation commit against the proposed head and rejects every other path, so the orchestrator cannot append unrecorded product changes. Issue runs may not modify the loop runtime, owner channel, workflow, package manifests, verification scripts, or verification configuration. Such control-plane work belongs to a dedicated owner-reviewed evolve/bootstrap PR and becomes executable only after installation from a clean owner-merged `dev`.
82+
The recorded implementation commit is the product-code boundary. Later commits may contain only the current run's handoff, sanitized logs, screenshots, and evidence. `record-pr` diffs the implementation commit against the proposed head and rejects every other path, so the orchestrator cannot append unrecorded product changes. Issue runs may not modify the loop runtime, owner channel, workflow, package manifests, verification scripts, or verification configuration, except for an explicitly allowlisted verifier synchronization whose Git tree entry exactly matches the live owner-merged control SHA. Such control-plane work and every change to that narrow exception belong to a dedicated owner-reviewed evolve/bootstrap PR and become executable only after installation from a clean owner-merged `dev`.
83+
84+
A bootstrap PR is still pushed by the automation identity, never by the owner identity. Before that push, `codeacme17` must publish the exact generated authorization body on the state-journal issue. The authorization binds the configured automation login, repository, `codex/bootstrap-*` branch, current live `dev` SHA, exact local head SHA, purpose, and an expiry of at most 24 hours. The installed router re-fetches that owner comment for every push or Draft-PR creation, requires a clean non-merge descendant of the still-current `origin/dev`, permits only added or modified control-plane paths, and rejects a missing, advanced, or mismatched remote branch. The authorization never permits product paths, Ready, Approve, Merge, force push, or a different commit.
8385

8486
### 5. Verify before publication
8587

86-
Run relevant checks and `pnpm verify`. For UI behavior, capture before/after screenshots under `screen-shots/<run-id>` at meaningful desktop and mobile viewports and include interaction or accessibility evidence where applicable. Bind `before` to the frozen base and `after` to the latest `$implement` commit; never put the containing commit's not-yet-known hash inside its own files. Commit sanitized screenshots and run metadata to the issue branch. The Draft PR body must render at least one representative before/after pair with Markdown image syntax, using `raw.githubusercontent.com` URLs pinned to the exact recorded head; links to an index or manifest alone are not UI evidence. The low-privilege `pull_request` evidence workflow checks out the exact candidate head, resolves its frozen run base, proves that base remains an ancestor of live `dev`, and separately checks out the immutable owner-merged base without persisted credentials. It installs candidate and baseline dependencies with lifecycle scripts disabled into distinct Docker volumes. Candidate `pnpm verify` and the actual frozen owner-merged baseline `pnpm test` run in separate no-network containers that receive no GitHub token and cannot mount any host checkout. Before accepting the artifact, the installed control plane independently rejects any exact-head change to the workflow or trusted control/verification plane. The manifest binds candidate head, workflow-run SHA, frozen owner-merged base SHA, and the live PR base SHA that selected the workflow.
88+
Run relevant checks and `pnpm verify`. For UI behavior, capture before/after screenshots under `screen-shots/<run-id>` at meaningful desktop and mobile viewports and include interaction or accessibility evidence where applicable. Bind `before` to the frozen base and `after` to the latest `$implement` commit; never put the containing commit's not-yet-known hash inside its own files. Commit sanitized screenshots and run metadata to the issue branch. The Draft PR body must render at least one representative before/after pair with Markdown image syntax, using `raw.githubusercontent.com` URLs pinned to the exact recorded head; links to an index or manifest alone are not UI evidence. The low-privilege `pull_request` evidence workflow checks out the exact candidate head, resolves its frozen run base, proves that base remains an ancestor of live `dev`, and separately checks out the immutable owner-merged base without persisted credentials. It installs candidate and baseline dependencies with lifecycle scripts disabled into distinct Docker volumes. Candidate `pnpm verify` and the actual frozen owner-merged baseline `pnpm test` run in separate no-network containers that receive no GitHub token and cannot mount any host checkout. The live owner-merged control plane may permit an old active run to synchronize only an explicitly allowlisted verifier file whose Git tree entry is byte-for-byte and mode-for-mode identical to the live PR base; every other candidate change to the workflow or trusted control/verification plane remains forbidden. Before accepting the artifact, the installed control plane independently revalidates that exact synchronization against the manifest's live workflow base SHA. The manifest binds candidate head, workflow-run SHA, frozen owner-merged base SHA, and the live PR base SHA that selected the workflow.
8789

8890
### 6. Create the draft PR
8991

0 commit comments

Comments
 (0)