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
+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
@@ -8,7 +8,7 @@ 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 informational and does not ask the owner for another decision, but successful canonical GitHub delivery is a hard prerequisite for completion. `prepare-finalization` posts it only after remotely observing the owner-authored Ready transition, exact-head owner approval, and owner merge; it waits for the bounded optional webhook attempt and binds both notification outcomes before any terminal journal publication. GitHub delivery failure leaves the run active and retryable.
11
+
`pr_completed` is informational and does not ask the owner for another decision, but successful canonical GitHub delivery is a hard prerequisite for completion. `prepare-finalization` posts this reserved marker only after remotely observing the strictly post-notification owner Ready transition, exact-head owner approval, and owner merge. Its body binds the merge SHA, its remote timestamp must be at or after the merge, and it must use a comment URL distinct from the Ready notification. The command waits for the bounded optional webhook attempt and binds both notification outcomes before any terminal journal publication. GitHub delivery failure leaves the run active and retryable.
12
12
13
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.
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
@@ -103,13 +103,13 @@ When the owner requests changes, verify the owner-authored GitHub comment or `CH
103
103
104
104
### 10. Complete
105
105
106
-
Only the remote owner-merge gate permits `completed`. Before a completion record exists, `prepare-finalization` remotely verifies the automation-authored Ready notification, an owner `ready_for_review` timeline event after that comment with no later redraft, an `APPROVED` review for the exact reviewed head SHA, and a merge performed by `codeacme17`. It then requires successful canonical `pr_completed` GitHub delivery and waits for the optional webhook attempt to settle within its bound. The finalization record binds the Ready and completion comment URLs/timestamps plus webhook outcome. Only after those prerequisites may the automation identity publish the record to the GitHub state journal. Publication, `observe-owner-merge`, terminal transition, and future reconciliation re-fetch that proof; a failed delivery or crash before publication leaves the active checkpoint resumable instead of suppressing it. Mutable local events are audit records, never authorization. Record merge SHA and timestamp, remove `loop:claimed`, update state, append the run summary, and retain links to published evidence. A closed unmerged PR is `cancelled`, not completed.
106
+
Only the remote owner-merge gate permits `completed`. Before a completion record exists, `prepare-finalization` remotely verifies the automation-authored Ready notification, a strictly later owner `ready_for_review` timeline event with no later redraft, an `APPROVED` review for the exact reviewed head SHA, and a merge performed by `codeacme17`. It then requires successful canonical `pr_completed` GitHub delivery whose body binds the merge SHA and whose remote timestamp is at or after the merge, and waits for the optional webhook attempt to settle within its bound. The identity router reserves `pr_completed` for the trusted finalization command. The finalization record binds distinct Ready and completion comment URLs/timestamps plus webhook outcome. Only after those prerequisites may the automation identity publish the record to the GitHub state journal. Publication, `observe-owner-merge`, terminal transition, and future reconciliation re-fetch that proof; a failed delivery or crash before publication leaves the active checkpoint resumable instead of suppressing it. Mutable local events are audit records, never authorization. Record merge SHA and timestamp, remove `loop:claimed`, update state, append the run summary, and retain links to published evidence. A closed unmerged PR is `cancelled`, not completed.
107
107
108
108
## State and history
109
109
110
110
Keep `state.md` small and deliberate. It may be rewritten and contains only active runs, open PRs, blockers, follow-ups, current hypotheses, and learned constraints.
111
111
112
-
`logs/index.jsonl` is append-only and contains one compact summary per finalized run; `logs/triggers.jsonl` is the append-only record of cheap trigger decisions, including successful no-ops and resumes. The dedicated GitHub state-journal issue is the durable cross-worktree source for both active checkpoints and terminal records. After every durable run phase, publish the exact `prepare-checkpoint` body and validate it with `record-checkpoint`; the next phase re-fetches that automation-authored comment and refuses stale, absent, edited, or locally forged proof. Each compact checkpoint also embeds the digest-bound `$implement` result, evidence manifest, review result, and finalization record referenced by its event chain, when present, so later gates remain resumable. Terminal comments supersede active checkpoints only after finalization reconciliation validates them, including remote owner proof for completion. `loopctl reconcile` discovers resumable state and recomputes evolve metrics; it does not write run state into an arbitrary checkout. The orchestrator creates a clean worktree at the recorded exact branch/head, then `restore-checkpoint` verifies both before restoring run files and required small artifacts. A resumable run is returned as `workType: resume` before new issue selection. Commit sanitized `run.json`, pre-publication `events.jsonl`, summaries, and relevant screenshots to the issue branch so they are reviewable in its PR. The exact-head CI manifest and full proof travel in an Actions artifact. Keep raw local command output and large recordings in ignored `raw/` or `test-results/` directories. GitHub journal comments, PR reviews, workflow artifacts, and merge metadata are authoritative; local indexes and metrics are reconstructable caches.
112
+
`logs/index.jsonl` is append-only and contains compact finalized-run summaries plus reconciliation tombstones for rows that lack a durable counterpart; metrics ignore tombstoned rows. `logs/triggers.jsonl` is the append-only record of cheap trigger decisions, including successful no-ops and resumes. The dedicated GitHub state-journal issue is the durable cross-worktree source for active checkpoints, terminal records, and pending/completed evolve sessions. After every durable run phase, publish the exact `prepare-checkpoint` body and validate it with `record-checkpoint`; the next phase re-fetches that automation-authored comment and refuses stale, absent, edited, or locally forged proof. Each compact checkpoint also embeds the digest-bound `$implement` result, evidence manifest, review result, and finalization record referenced by its event chain, when present, so later gates remain resumable. Terminal comments supersede active checkpoints only after finalization reconciliation validates them, including remote owner proof for completion. `loopctl reconcile` discovers resumable state, excludes local terminal rows without verified remote records, rebuilds evolve request/completion state, and recomputes metrics from verified journal history; it does not write run state into an arbitrary checkout. The orchestrator creates a clean worktree at the recorded exact branch/head, then `restore-checkpoint` verifies both before restoring run files and required small artifacts. A resumable run is returned as `workType: resume` before new issue selection. Commit sanitized `run.json`, pre-publication `events.jsonl`, summaries, and relevant screenshots to the issue branch so they are reviewable in its PR. The exact-head CI manifest and full proof travel in an Actions artifact. Keep raw local command output and large recordings in ignored `raw/` or `test-results/` directories. GitHub journal comments, PR reviews, workflow artifacts, and merge metadata are authoritative; local indexes and metrics are reconstructable caches.
113
113
114
114
Never log secrets, full environment dumps, cookies, auth headers, private user data, or raw prompts containing sensitive information.
Copy file name to clipboardExpand all lines: loops/issue-dev-loop/SKILL.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
@@ -12,7 +12,7 @@ Run exactly one bounded issue cycle. Treat [`LOOP.md`](./LOOP.md) as the constit
12
12
1. Read `LOOP.md`, `state.md`, and `dependencies.md` completely.
13
13
2. Require absolute `ECHO_UI_LOOP_CONTROL_PLANE` and `ECHO_UI_LOOP_TARGET_ROOT` values from the scheduler. Run activation through `"$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"`. The installed launcher verifies its hash manifest and probes both configured profiles before starting validation.
14
14
3. Read [`references/github-operations.md`](./references/github-operations.md). Run every operational `loopctl`, executor GitHub command, remote Git command, trigger, and reviewer publication through the installed control plane with the explicit target root. Never use the credential-refusing repository launcher, invoke the `.mjs` router directly, install control code from an issue branch, or alter global `gh` or Git credential configuration.
15
-
4. Run `loopctl.mjs reconcile` through the automation wrapper to rebuild terminal history and discover active runs from the append-only GitHub state journal. For returned `workType: resume`, fetch the recorded branch through the wrapper, create a clean isolated worktree at the returned exact head, and run `restore-checkpoint --run-id <id>` inside that worktree. The restore command rejects the wrong branch, a dirty checkout, or any head other than the durable head. Resume it before selecting a new issue.
15
+
4. Run `loopctl.mjs reconcile` through the automation wrapper to rebuild verified terminal history, pending/completed evolve state, and active runs from the append-only GitHub state journal. It tombstones local terminal-cache rows with no durable counterpart before recomputing metrics. For returned `workType: resume`, fetch the recorded branch through the wrapper, create a clean isolated worktree at the returned exact head, and run `restore-checkpoint --run-id <id>` inside that worktree. The restore command rejects the wrong branch, a dirty checkout, or any head other than the durable head. Resume it before selecting a new issue.
16
16
5. Run `loopctl.mjs evolve-status`. If `evolveDue` is true, start `echo_ui_loop_evolver` with fresh context; do not silently replace it with product work.
17
17
6. Run the installed `triggers/detect-work.mjs` through the automation wrapper with `--loop-root "$ECHO_UI_LOOP_TARGET_ROOT"`. The detector paginates every open issue and PR page. Exit without invoking an implementation agent when it reports `hasWork: false`.
18
18
7. Refuse to start when another active run or PR already claims the issue.
@@ -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`. For completion, that command paginates the PR timeline and reviews, requires a Ready transition authored by `codeacme17` after the remotely verified Ready-notification comment with no later redraft, requires the owner's exact-head approval and merge, delivers the informational `pr_completed` GitHub notification, waits for the bounded webhook attempt to settle, and binds both notification URLs/timestamps into the record. If canonical GitHub delivery fails, no terminal record is created. Only then publish the exact body to the configured state-journal issue and pass its result/comment URL to `observe-owner-merge`; that command revalidates the remote record, appends the local notification/owner audit events, and finalizes. Future workspaces run `reconcile` to revalidate the same notification, Ready, approval, and merge proof before rebuilding local history or suppressing an active checkpoint.
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`. For completion, that command paginates the PR timeline and reviews, requires a Ready transition authored by `codeacme17` strictly after the remotely verified Ready-notification comment with no later redraft, requires the owner's exact-head approval and merge, delivers the informational `pr_completed` GitHub notification with the merge SHA after the remote merge timestamp, waits for the bounded webhook attempt to settle, and binds distinct notification URLs/timestamps into the record. Raw executor comments cannot use the reserved `pr_completed` marker. If canonical GitHub delivery fails, no terminal record is created. Only then publish the exact body to the configured state-journal issue and pass its result/comment URL to `observe-owner-merge`; that command revalidates the remote record, appends the local notification/owner audit events, and finalizes. Future workspaces run `reconcile` to revalidate the same notification, Ready, approval, and merge proof before rebuilding local history or suppressing an active checkpoint.
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
+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
@@ -41,6 +41,6 @@ The installer refuses a dirty checkout, a branch other than `dev`, a commit othe
41
41
42
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.
43
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 rejects the originally configured path when it is a symlink, then canonicalizes the real directory, checks descendants, permissions, ownership, repository coverage, and overlap with agent-visible roots, and routes `GH_CONFIG_DIR` through that validated canonical path. `$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.
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 first lexically resolves trailing separators and `/.`, rejects that originally named top-level entry when it is a symlink, then canonicalizes the real directory, checks descendants, permissions, ownership, repository coverage, and overlap with agent-visible roots, and routes `GH_CONFIG_DIR` through that validated canonical path. `$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
45
46
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.
Copy file name to clipboardExpand all lines: loops/issue-dev-loop/evolve/EVOLVE.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
@@ -18,4 +18,4 @@ Every evolve change requires a dedicated `codex/evolve-<request-id>` draft PR ta
18
18
19
19
Never optimize by weakening evidence, increasing autonomous authority, deleting unfavorable history, or hiding no-work and failure runs.
20
20
21
-
After the owner merges the evolve PR, run `loopctl.mjs evolve-complete --request-id <id> --summary <summary> --pr-url <url>`. A pending requestis not cleared by silence or an unmerged PR.
21
+
After the owner merges the evolve PR, run `loopctl.mjs evolve-complete --request-id <id> --summary <summary> --pr-url <url>` through the installed automation wrapper. The trusted command re-fetches the digest-bound request, owner Ready/approval/merge proof, posts a digest-bound `evolve-completion` record to the state journal, and only then clears the pending request. The identity router reserves that marker for this command. Every scheduled `reconcile` rebuilds pending and completed evolve requests, `lastEvolvedRunCount`, and completion counters from those automation-authored journal records before deciding whether another evolve session is due. A local file, silence, an unmerged PR, or a completion comment created before the recorded merge never clears a request.
0 commit comments