You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: loops/_shared/owner-channel/CHANNEL.md
+4-2Lines changed: 4 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,12 +8,14 @@ GitHub issue and PR comments are the canonical, auditable channel. The runtime m
8
8
9
9
`--dry-run` stages a simulated payload only. It never records `owner_notified`, never pauses the run, and never satisfies a blocking delivery gate.
10
10
11
+
`pr_completed` is immediate but informational and must remain non-blocking. After remotely observing the owner-authored Ready transition, exact-head owner approval, and owner merge, the runtime durably posts this GitHub notification and performs the same bounded optional webhook attempt before it records the local merge/final state.
12
+
11
13
Each blocking GitHub notification prints a unique resume instruction. To continue after answering, include `RESUME <run-id>` in a normal issue/PR comment; submitting a GitHub `CHANGES_REQUESTED` review is also an explicit response. The runtime verifies author, target, timestamp, successful delivery, and response URL before resuming. Silence and unrelated comments never count.
12
14
13
15
## Runtime setup
14
16
15
-
1. Authenticate the unattended executor and fresh reviewer with distinct GitHub identities. Their exact logins and the names of their profile-path environment variables live in `channel.json`. For the current configuration, set `ECHO_UI_LOOP_AUTOMATION_GH_CONFIG_DIR` to the `Ethandasw``gh` profile directory and `ECHO_UI_LOOP_REVIEWER_GH_CONFIG_DIR` to the `Traviinam` profile directory in the scheduler environment. The directory names themselves are local details and do not need to match the roles.
16
-
2. From a clean owner-merged `dev` checkout at exact `origin/dev`, install a new versioned control plane outside every repository worktree and every scheduler-writable root with `install-trusted-control-plane.mjs`. Expose it read/execute-only to the unattended process through the scheduler sandbox or separate ownership/ACLs; the automation identity must not be able to rewrite it, its parent, the pinned executables, modes, ACLs, or sandbox policy. Set `ECHO_UI_LOOP_CONTROL_PLANE` to its `issue-dev-loop` directory and `ECHO_UI_LOOP_TARGET_ROOT` to the scheduled worktree's loop directory. Run `"$ECHO_UI_LOOP_CONTROL_PLANE/scripts/with-github-identity" --loop-root "$ECHO_UI_LOOP_TARGET_ROOT" automation -- node "$ECHO_UI_LOOP_CONTROL_PLANE/scripts/loopctl.mjs" validate --activation --loop-root "$ECHO_UI_LOOP_TARGET_ROOT"` before scheduling.
17
+
1. Authenticate the unattended executor and fresh reviewer with distinct GitHub identities. Their exact logins and the names of their profile-path environment variables live in `channel.json`. For the current configuration, set `ECHO_UI_LOOP_AUTOMATION_GH_CONFIG_DIR` to the `Ethandasw``gh` profile directory and `ECHO_UI_LOOP_REVIEWER_GH_CONFIG_DIR` to the `Traviinam` profile directory in the trusted router environment. The directory names themselves are local details and do not need to match the roles. Both directories must be private (`0700`, with no group/other access on any descendant) and outside every untrusted agent-visible root.
18
+
2. From a clean owner-merged `dev` checkout at exact `origin/dev`, install a new versioned control plane outside every repository worktree and every scheduler-writable root with `install-trusted-control-plane.mjs`. Expose it read/execute-only to the unattended process through the scheduler sandbox or separate ownership/ACLs; the automation identity must not be able to rewrite it, its parent, the pinned executables, modes, ACLs, or sandbox policy. Set `ECHO_UI_LOOP_CONTROL_PLANE` to its `issue-dev-loop` directory, `ECHO_UI_LOOP_TARGET_ROOT` to the scheduled worktree's loop directory, and `ECHO_UI_LOOP_UNTRUSTED_ROOTS` to a JSON array covering the repository plus every root mounted into `$implement`, reviewer, or test sandboxes. Those sandboxes must not inherit either profile-path variable or `GH_CONFIG_DIR` and must be unable to read the profile directories. Run `"$ECHO_UI_LOOP_CONTROL_PLANE/scripts/with-github-identity" --loop-root "$ECHO_UI_LOOP_TARGET_ROOT" automation -- node "$ECHO_UI_LOOP_CONTROL_PLANE/scripts/loopctl.mjs" validate --activation --loop-root "$ECHO_UI_LOOP_TARGET_ROOT"` before scheduling.
17
19
3. Run every operational loop command, executor GitHub command, remote Git command, trigger, and reviewer publication through that installed launcher with the explicit target root. The repository launcher intentionally refuses credentials. The installed launcher hash-verifies its files and absolute executables, compares trusted channel fields, removes Node preload hooks, clears token overrides and process hooks, verifies `gh api user`, and gives Git a one-command credential helper without changing global Git or `gh` configuration. A PATH gate applies the role and current-run policy to descendant `git` and `gh` processes too; issue-worktree routers, PATH shims, arbitrary shell/environment commands, and arbitrary Node scripts are rejected.
18
20
4. Create one dedicated repository issue for the append-only loop state journal and set its number as `stateIssueNumber`. It stores active checkpoints and terminal records. Restrict journal entries to the automation identity; humans may read but should not edit or delete them.
19
21
5. Enable GitHub notifications for mentions and review requests for `codeacme17`.
Copy file name to clipboardExpand all lines: loops/issue-dev-loop/LOOP.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -126,11 +126,11 @@ Never log secrets, full environment dumps, cookies, auth headers, private user d
126
126
127
127
GitHub issue/PR comments are the canonical communication record. The shared owner channel may mirror notifications to a webhook. The notification runtime automatically transitions blocking events to `waiting_for_owner`; delivery failure is itself a blocker. `pr_ready_for_review` means the still-Draft PR has passed the loop's automated gates; it moves from that pause to `awaiting_owner_review` only after its SHA-bound evidence gates pass, and asks the owner to perform the GitHub Ready transition.
128
128
129
-
All credential-bearing commands run from an installed, hash-verified control plane outside the issue worktree and outside every unattended-writable root. The scheduler/OS must expose that bundle read/execute-only; mode bits and a co-located manifest are not themselves a trust boundary against the same OS principal. The installed launcher pins and hashes absolute Node, Git, and GitHub CLI executables; treats the worktree loop root only as data; compares its security-critical channel fields with the installed owner channel; and refuses detected tampering or PATH impersonation before loading either GitHub profile. The repository launcher never receives credentials.
129
+
All credential-bearing commands run from an installed, hash-verified control plane outside the issue worktree and outside every unattended-writable root. The scheduler/OS must expose that bundle read/execute-only; mode bits and a co-located manifest are not themselves a trust boundary against the same OS principal. The installed launcher pins and hashes absolute Node, Git, and GitHub CLI executables; treats the worktree loop root only as data; compares its security-critical channel fields with the installed owner channel; and refuses detected tampering or PATH impersonation before loading either GitHub profile. The repository launcher never receives credentials. Activation also requires private credential profiles outside every declared untrusted agent root. `$implement`, reviewers, product tests, and verifier containers receive no profile variables or `GH_CONFIG_DIR`, and their OS sandbox must not be able to read those directories.
130
130
131
131
A paused run resumes only after successful canonical GitHub delivery and a new, run-bound owner decision. The notification tells the owner to include `RESUME <run-id>` in a normal reply; a GitHub request-changes review is accepted without that token. An unrelated, stale, wrong-author, wrong-target, or pre-delivery comment never unlocks the run.
132
132
133
-
Notify immediately for `approval_required`, `clarification_required`, `blocked`, `review_dispute`, `pr_ready_for_review`, `pr_updated_for_review`, and `loop_failed`. Routine no-work checks belong in a digest, not an interruption.
133
+
Notify immediately for `approval_required`, `clarification_required`, `blocked`, `review_dispute`, `pr_ready_for_review`, `pr_updated_for_review`, and `loop_failed`. After the owner marks the PR Ready, approves the exact head, and merges it, emit the non-blocking `pr_completed` GitHub notification (plus the bounded webhook mirror) before recording terminal completion. Routine no-work checks belong in a digest, not an interruption.
Copy file name to clipboardExpand all lines: loops/issue-dev-loop/SKILL.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -61,7 +61,7 @@ Run verification appropriate to the change and require `pnpm verify` before the
61
61
62
62
Before publishing the final review round, write the complete cycle result with an unassigned final `reviewUrl`, then run `loopctl.mjs review-digest --result <absolute-path>`. Add the returned marker to the final review body, publish the non-approving review, replace the unassigned URL with GitHub's actual review URL, and confirm `review-digest` is unchanged. After all responses are posted, run `loopctl.mjs record-review --run-id <id> --result <absolute-path> --review-url <github-review-url>`. The publication digest deliberately canonicalizes GitHub-assigned review URLs while the stored full-file digest still protects the final artifact. Both evidence and review gates must name the current PR head. Keep the PR Draft, emit a blocking `pr_ready_for_review` notification asking `codeacme17` to mark it Ready and review it, then transition from `waiting_for_owner` to `awaiting_owner_review` with the PR URL and exact head SHA.
63
63
64
-
The owner is the only actor allowed to mark a Draft PR Ready, approve it, or merge it. Never call non-`--undo``gh pr ready`, `gh pr merge`, enable auto-merge, push to `main`, push to `dev`, dismiss owner feedback, or bypass branch protections. Before any terminal transition, run `prepare-finalization`, publish its exact body to the configured state-journal issue, and validate the returned comment URL with `record-finalization`. A completed run passes the same result and comment URL to `observe-owner-merge`, which queries GitHub and requires both `codeacme17`'s approval and merge at the reviewed head SHA. Future workspaces run `reconcile` to rebuild local history and evolve metrics from those automation-authored journal comments.
64
+
The owner is the only actor allowed to mark a Draft PR Ready, approve it, or merge it. Never call non-`--undo``gh pr ready`, `gh pr merge`, enable auto-merge, push to `main`, push to `dev`, dismiss owner feedback, or bypass branch protections. Before any terminal transition, run `prepare-finalization`, publish its exact body to the configured state-journal issue, and validate the returned comment URL with `record-finalization`. A completed run passes the same result and comment URL to `observe-owner-merge`, which paginates the PR timeline and reviews, requires a post-notification Ready transition authored by `codeacme17` with no later redraft, and requires the owner's exact-head approval and merge. It then delivers the informational `pr_completed` GitHub/webhook notification before recording the merge and terminal state. Future workspaces run `reconcile` to rebuild local history and evolve metrics from those automation-authored journal comments.
65
65
66
66
For any pause, do not resume from silence or an arbitrary comment. First require a successfully delivered blocking notification. Then verify the owner's GitHub decision with `loopctl.mjs record-owner-response --run-id <id> --response-url <comment-or-review-url>`. A normal comment must include the exact `RESUME <run-id>` token printed in the notification; a `CHANGES_REQUESTED` review is itself an explicit decision and must be submitted against the run's current exact head SHA. Only then may `loopctl.mjs transition --run-id <id> --status running` continue. Before any repair work or new push, publish that transition's checkpoint, run the unchanged exact PR through `gh pr ready --undo --repo codeacme17/echo-ui`, observe the same head as Draft with `record-pr`, and publish another checkpoint. `$implement` repair attestations and later PR rebinds are rejected unless this durable redraft happened after the current owner response.
Copy file name to clipboardExpand all lines: loops/issue-dev-loop/dependencies.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,6 +12,7 @@
12
12
- GitHub CLI (`gh`) authenticated for issue, Actions artifact download, branch, PR, review, and comment work
13
13
-`ECHO_UI_LOOP_AUTOMATION_GH_CONFIG_DIR` pointing to the executor's dedicated `gh` profile
14
14
-`ECHO_UI_LOOP_REVIEWER_GH_CONFIG_DIR` pointing to the reviewer's dedicated `gh` profile
15
+
-`ECHO_UI_LOOP_UNTRUSTED_ROOTS` containing a JSON array of every absolute filesystem root exposed read/write to `$implement`, candidate tests, or another untrusted agent sandbox
15
16
-`ECHO_UI_LOOP_CONTROL_PLANE` pointing to the installed `issue-dev-loop` control-plane directory outside every repository worktree
16
17
-`ECHO_UI_LOOP_TARGET_ROOT` pointing to the active worktree's `loops/issue-dev-loop` directory
17
18
- Repository trust enabled so project `.codex` agents can load
The installer refuses a dirty checkout, a branch other than `dev`, a commit other than `origin/dev`, an in-repository target, or an existing target. It pins and hashes the absolute Node/Git/GitHub CLI executables, copies the owner channel and runtime, hashes every installed file, and makes the bundle mode-only read-only. Install updates only after an owner-merged loop-control change; never install control code from an issue branch.
39
41
40
42
The trust root is the scheduler/OS boundary, not Unix mode bits or a self-hashed manifest. Put the installed bundle outside every filesystem root writable by the unattended Codex process, and expose it read/execute-only through the scheduler sandbox or separate ownership/ACLs. The automation identity must not have permission to change the bundle, its parent, the pinned executables, file modes, ACLs, or the sandbox policy. A same-OS-principal process allowed to rewrite both code and its manifest cannot establish a cryptographic trust root in user space; do not activate the loop under that permission model.
41
43
44
+
Credential profiles are a separate secret boundary. Put both profile directories outside every root listed by `ECHO_UI_LOOP_UNTRUSTED_ROOTS`, set each directory to mode `0700` and every entry below it to deny group/other access, and expose them only to the trusted orchestration/identity-router process. The activation check canonicalizes these paths, rejects symlinks, broad permissions, wrong ownership, missing repository coverage, profiles inside an untrusted root, and overlapping agent-visible roots. `$implement`, fresh reviewers, candidate scripts, local product tests, and verifier containers must receive neither profile-path variables nor `GH_CONFIG_DIR`, and their sandbox must not be able to read the profile directories. If the scheduler cannot enforce that read boundary, do not activate the loop.
45
+
42
46
Never run `gh auth setup-git` for this loop. Route commands through `"$ECHO_UI_LOOP_CONTROL_PLANE/scripts/with-github-identity" --loop-root "$ECHO_UI_LOOP_TARGET_ROOT" <role> -- ...`. The repository copy is installer source and intentionally refuses credential use. The installed launcher verifies its manifest before selecting an identity, removes Node preload hooks, scopes `GH_CONFIG_DIR` and the Git credential helper to one allowlisted child tree, gates descendant `git`/`gh` calls, and leaves the user's default `gh` account and global Git credential configuration unchanged.
0 commit comments