7.7 KiB
JOURNAL — phase poe2e (Builder)
Ownership: per protocol §6.1 JOURNAL is Builder-owned (my reasoning; the Adversary does not read it before forming a verdict, for anti-anchoring). The Adversary pre-created this file with its D5 baseline; I have preserved that baseline verbatim in the "Adversary pre-Builder D5 baseline" section below (it is reproducible — plain sha256 of the live files — so nothing is lost) and sent an ADVERSARY-INBOX note that I took JOURNAL over and that baselines belong in REVIEW.
2026-06-13T19:30Z — Bootstrap / orientation
Read in full: plan-phase-poe2e-end-to-end.md, plan-agent-orchestrator.md,
plan-phase-porepo-project-orchestrator.md, the engine README.md, the live agents.toml +
build_loop_kickoff() in the live agents.py. Inspected the PO repo and engine clone.
Established facts:
- Engine v0.1.0 working clone:
/home/loops/aoeng/agent-orchestrator(tagv0.1.0→ commit289ef07). PO repo working clone:/home/loops/porepo/project-orchestrator(main@346ed31, engine submodule pinned289ef07). Both public on Gitea. - Live cc-ci status (the parity target), captured read-only from
/srv/cc-ci/cc-ci-planvia the liveagents.py status:Note the builder=opus / adversary=sonnet rows are the per-phase model override for phase poe2e (defaults.model is sonnet; the poe2e phase entry setsphase: poe2e [19/19] plan=plan-phase-poe2e-end-to-end.md (in progress) orchestrator persistent claude claude-opus-4-8 heal RUNNING builder loop claude claude-opus-4-8 heal+stall RUNNING adversary loop claude claude-sonnet-4-6 heal+stall RUNNING assistant persistent claude claude-sonnet-4-6 none stopped (disabled) upgrader task claude claude-sonnet-4-6 none RUNNING (disabled) report task claude claude-opus-4-8 none RUNNING (disabled) cleanlogs service - - - RUNNING watchdog service - - - RUNNINGmodels = { builder=opus, adversary=sonnet }). Parity is on the agents / models / phases columns — NOT the STATE column (the staged project is never started, so its rows will readstopped, which is correct and expected).
Design approach (the WHY)
- Staging form = a local git repo + engine submodule, not a new Gitea repo. The phase says "new
repo OR a staging dir"; a local staging repo is the safer choice (no collision with the live
recipe-maintainers/cc-cirepo, fully local, obviously staging). Itsengine/is a real pinned submodule (DoD requires "engine submodule pinned"). fleet.toml registers it by local path; the cutover runbook documents the eventual production repo/location. - Kickoff template migration. The live preamble is hardcoded in the live
agents.pybuild_loop_kickoff()with/srv/cc-ci/cc-ci-plan/{plan}paths. The engine v0.1.0 generalizes this to a project-suppliedprompts/kickoff.mdwith{phase_id}/{plan}/{status}/{role}slots +roles_dir. I reproduce the live preamble text in the staged project'sprompts/kickoff.md(baking the/srv/cc-ci/cc-ci-plan/plan-path prefix into the template so the phases array keeps bare filenames, which is what the statusplan=column shows — preserving parity). - prompts/ builder.md + adversary.md copied verbatim from live
/srv/cc-ci/cc-ci-plan/prompts/. - session_prefix decision: deferred to the build step (recorded there). The prefix never appears
in
statusoutput, so it does not affect parity; the guardrail is about never starting a watchdog on thecc-ci-namespace, which I will not do. - Scratch lifecycle (D1) uses the engine's dependency-free
demobackend soupreally starts tmux sessions (provable RUNNING) without spending tokens or risking any collision, on a unique isolatedsession_prefix. Thendown+ delete the throwaway.
2026-06-13T19:41Z — All 5 DoD built + cold-verified; claiming gate
Built and verified end to end. The WHY behind the STATUS facts:
- D1 (lifecycle). Used the PO's
create-project.shto scaffold/tmp/poe2e-scratch/scratch-e2e(engine pinned289ef07; tracked files exactly.gitignore .gitmodules agents.toml engine— no PO/fleet metadata), switched it to thedemobackend soupreally starts tmux sessions with no token spend and on the isolatedpoe2e-scratch-namespace. Observed:up→ both sessions;status→ RUNNING;down→ killed;status→ stopped; deleted. The 8 livecc-ci-*sessions never moved. - D2 (migration + parity). The migration is faithful:
role_model()andcmd_status()render byte-identical between the live engine and v0.1.0 (I diffedrole_model— IDENTICAL — and readcmd_status). I copied thephasesarray verbatim (incl. the"opus"shorthand for dstamp and all per-phasemodels), sotomllib-comparing the two configs' phase arrays givesTrue. The biggest confidence boost: rendering the staged builder/adversary kickoffs via the engine and diffing against the live generatedkickoff-cc-ci-*.txt→ byte-identical, proving prompts/kickoff.md + prompts/{builder,adversary}.md reproduce the livebuild_loop_kickoff()exactly. The stagedstatusis byte-identical to live including STATE, becausesession_prefix="cc-ci-"meanssession_alive()(read-onlytmux has-session) sees the live sessions — the staged project starts nothing. Critical safety finding: the engine'sload_config()doesPath(log_dir/state).mkdir(exist_ok=True)on EVERY invocation incl.status— so the stagedlog_dirmust be the isolated.ao-state, never the live/srv/cc-ci/.cc-ci-logs(the cutover runbook flips it back). That's why staging uses an isolated state dir. - D3. Registered
cc-ciin the POfleet.tomlasenabled=false(the PO must never start it — shared namespace would collide with live).fleet.py validate→ OK, 2 projects. - D4. Cutover runbook derived from the actual live boot chain I inspected
(
cc-ci-loops.service → cc-ci-loops-start → launch.sh start → launch.py [shim] → agents.py up, cwd/srv/cc-ci/cc-ci,RESUME_PHASE=1). The cutover is one indirection change (re-pointlaunch.pyat the project engine) + one config delta (log_dir→ live path to resume phase/ids)- quiesce-then-start to avoid a double watchdog; rollback is just restoring the old shim. The
in-place
agents.{py,toml}stay present throughout → trivial rollback.
- quiesce-then-start to avoid a double watchdog; rollback is just restoring the old shim. The
in-place
- D5. Re-checksummed live
agents.{py,toml}(both == baseline),phase-idx=18, the 8 baseline sessions, exactly 1cc-ci-watchdog, cc-ci host has no tmux. Nothing I did wrote live files/state or started acc-ci-session.
Deliverable SHAs: staged cc-ci /home/loops/poe2e/cc-ci @ 38e5c90 (engine 289ef07 v0.1.0);
PO recipe-maintainers/project-orchestrator @ 6cc3ed4 (pushed). Cleaned up /tmp scratch +
cold-clone artifacts. Claiming the gate.
Adversary pre-Builder D5 baseline (preserved verbatim from the Adversary's init)
The Adversary recorded this in JOURNAL-poe2e.md at phase start, before I took ownership. Kept here so it is not lost; the Adversary owns/should track it in REVIEW-poe2e.md.
Baseline @2026-06-13T19:25Z (pre-Builder):
- agents.toml SHA256:
0d78ba55329705055bbb39722292b6d131cdd30f37eb814e50316f7c0e222b88 - agents.py SHA256:
b4567b73099a587b5727a194f80a5e908d1a1589691294230e6ad1492fb9fe9a - state/phase-idx: 18 (poe2e)
- tmux sessions on orchestrator (pre-Builder): cc-ci-adv, cc-ci-assistant3, cc-ci-cleanlogs, cc-ci-builder, cc-ci-orchestrator, cc-ci-report, cc-ci-upgrader, cc-ci-watchdog
- cc-ci host tmux:
no tmux sessions