Skip to content

feat: add Codex App visible thread ledger#212

Closed
SSBrouhard wants to merge 19 commits into
kunchenguid:mainfrom
SSBrouhard:fm/firstmate-codex-ledger-nm-j8
Closed

feat: add Codex App visible thread ledger#212
SSBrouhard wants to merge 19 commits into
kunchenguid:mainfrom
SSBrouhard:fm/firstmate-codex-ledger-nm-j8

Conversation

@SSBrouhard

@SSBrouhard SSBrouhard commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • Added a Codex App visible-thread backend and fm-codex-app ledger workflow for preparing, recording, adopting, inspecting, and archiving Desktop-owned threads.
  • Wired Codex App state through backend helpers, spawn/send/peek/crew-state/watch flows, PR merge metadata, and teardown safety for pending and external-worktree threads.
  • Documented the Codex App backend model and added smoke, state, teardown, backend, and watcher tests covering the new ledger behavior.

Risk Assessment

✅ Low: The Codex App ledger changes are well-scoped, guarded around app-owned operations, and the prior stale-wake issue is addressed by reporting visible/pending threads as busy.

Testing

Completed 1 recorded test check.

Pipeline

Updates from git push no-mistakes

⏭️ **intent** - skipped

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 1 issue found → auto-fixed ✅
  • ⚠️ bin/backends/codex-app.sh:56 - Visible Codex App threads return unknown busy state, but the existing watcher treats unknown as “check the captured tail for a TUI busy footer.” Codex App capture is just a cached transcript, often empty or unchanged while Desktop owns the live thread, so an active visible thread will be classified as idle/stale after two polls and wake firstmate spuriously. Make codex-app visible/pending states opt out of pane-stale detection or report a non-idle state until archived.

🔧 Fix: prevent Codex App stale wakes
✅ Re-checked - no issues remain.

✅ **Test** - passed

✅ No issues found.

  • command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; for t in tests/*.test.sh; do echo "== $t =="; bash "$t" || rc=1; done; exit "$rc"
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

@SSBrouhard SSBrouhard changed the title feat: add codex app visible thread ledger feat(bin): add Codex App visible-thread ledger Jul 3, 2026
@SSBrouhard SSBrouhard force-pushed the fm/firstmate-codex-ledger-nm-j8 branch from bf6d349 to 12a81f0 Compare July 3, 2026 04:32
@SSBrouhard SSBrouhard changed the title feat(bin): add Codex App visible-thread ledger feat: add Codex App visible-thread ledger Jul 3, 2026
@SSBrouhard SSBrouhard changed the title feat: add Codex App visible-thread ledger feat: add Codex App visible thread ledger Jul 3, 2026
@SSBrouhard SSBrouhard force-pushed the fm/firstmate-codex-ledger-nm-j8 branch 2 times, most recently from 1185465 to 1e2734f Compare July 3, 2026 06:17
@kunchenguid

Copy link
Copy Markdown
Owner

Thanks for the PR! It looks like this branch has a merge conflict with the base branch right now. When you get a chance, could you rebase onto (or merge in) the latest base branch, resolve the conflict, and push? Once GitHub shows the PR as mergeable again, it'll be picked back up for review.

Noted for firstmate#212 at 1e2734f9.

@SSBrouhard SSBrouhard force-pushed the fm/firstmate-codex-ledger-nm-j8 branch from 1e2734f to 7fd90cf Compare July 3, 2026 15:52
@kunchenguid

Copy link
Copy Markdown
Owner

Thanks for the pair - I reviewed both PRs in depth. I want to say clearly up front: supporting Codex App is a direction I like, and the code here is careful work (the archive double-gate, the always-refuse send that never pretends a steer landed, execFileSync throughout - all good instincts). But I'm not going to land this shape, and I want to be precise about why.

What this implements is a manual ledger wearing the backend label. tmux, herdr, and zellij all honor one contract: firstmate creates the endpoint, sends to it, observes it live, kills it. This adapter satisfies the same interface with inverted semantics - capture reads a hand-refreshed cache, send always refuses, kill requires a human to have archived the thread in the GUI, and creation happens entirely outside fm-spawn (hand-written brief, GUI clicks, hand-made worktree, then "adopt"). Admitting a second, passive semantics into the abstraction is a standing tax: five supervision surfaces each grow a special case, and the resulting tasks sit outside the supervision model entirely - busy forever, no steer path, and no proven way to write the status files the whole wake model runs on.

The bar for codex-app is an architecturally consistent implementation: same contract as the other backends, driven through Codex Desktop's host tools (create_thread / send_message_to_thread / archive - exactly the surface #211 already catalogs). Concretely, what I'd take:

  1. One reconciled docs file. Right now docs: document Codex App backend protocol #211 and feat: add Codex App visible thread ledger #212 ship two different docs/codex-app-backend.md at the same path - the pair conflicts with itself in both merge orders (six files).
  2. A live smoke transcript proving the host-tool loop actually works against a real Codex Desktop - the smoke contract both PRs describe but neither exercises.
  3. An answer on whether a Desktop-owned thread can write firstmate's status files. If it can't, there's no return channel and no backend design can fix that.

If the host tools prove drivable, a real codex-app backend lands with no semantic fork and I'd be glad to take it. I'll leave this open for now in case you want to rework in that direction - happy to talk through the contract details here.

@SSBrouhard

Copy link
Copy Markdown
Contributor Author

Superseded by #222. The replacement removes the visible-thread ledger approach and records the verified Codex Desktop host-tool smoke, the status-file write result, and the shell-bridge blocker contract.

@SSBrouhard SSBrouhard closed this Jul 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants