feat: add GitHub issue lifecycle runner#1334
Conversation
✅ CLI go.mod matches internal Go module releases
|
🚨 Dependency Audit — Vulnerabilities foundFull report |
|
Complexity Review — PR #1334: feat: add GitHub issue lifecycle runnerComposite Score: 1.0 / 1.0 Verdict: Low-complexity, high-reviewability change. Well-isolated, single-purpose addition with proportional test coverage and excellent documentation. Criterion Scores
Main Complexity Drivers
All complexity is appropriately contained within the new app boundary. No hidden complexity in existing code. |
|
Follow-up for the lifecycle review and final reflection requirement:
Validation run:
MoltNet diary: Per Edouard's request, legacy GitHub status check handling was intentionally left unchanged. |
|
Final reflection entry for this session:
This is the same publication shape now required from the issue-lifecycle final task. |
|
Follow-up: strengthened issue-lifecycle success criteria. The lifecycle tasks now require structured evidence per phase without changing transition parsing:
Validation run:
MoltNet diary: |
|
Manual local e2e smoke found and fixed a daemon continuation bug. Observed chain on local e2e:
Root cause: freeform continuation planning carried the producer worktree branch but not the producer workspaceId. The workspace materializer then fell back to a new task-scoped worktree path and tried to check out a branch already attached to the parent warm-session worktree. Fix: preserve the producer workspaceId when attaching warm-slot context for freeform continuations, plus a regression assertion. Validation run:
Diary:
|
|
Manual smoke follow-up: the second local lifecycle run failed after plan review because the review artifact returned structured finding objects, but the lifecycle parser kept only string findings and treated the review as empty. Fixed in Validation:
MoltNet-Diary: |
getlarge
left a comment
There was a problem hiding this comment.
When we start implementation, we should create a fresh task (not continue from) workspace to clear the context.
Just pass the plan one way or the other, via an artifact to pick from the previous work tree, an issue comment, an entry.
56e6d0b to
e10f6eb
Compare
MoltNet-Diary: e0d861ac-514f-43a8-9164-a83c3ee7e84e
MoltNet-Diary: 0abaef16-674e-4f71-8185-52be9669e178
MoltNet-Diary: 72278ccd-672b-4076-ae6e-14efe1c5a3ae
MoltNet-Diary: a9e6bb63-b0fd-4291-ad85-2955c82272aa
MoltNet-Diary: e79044f7-a688-47a4-a932-15c7ac5fa7a9
MoltNet-Diary: db74e69c-1042-4678-b688-983ca8b3c8a1
MoltNet-Diary: 8c30fb21-6a9f-4175-84d8-9b3b80c86c12
MoltNet-Diary: 14e8ae97-cb93-46cf-afb4-f3df5b9d5367
MoltNet-Diary: 961a0b11-7c82-407f-893c-042288cbdd91
MoltNet-Diary: 4b57412d-b84b-4a11-a4f6-2ca2dc071f36
MoltNet-Diary: d3b16ee3-7633-4ff1-b859-c6f392735174
MoltNet-Diary: 48eca512-32da-416a-a7fc-3ec5d9705d13
a048944 to
4943864
Compare
There was a problem hiding this comment.
This file is huge. Time to split, create separate step functions. I'm pretty sure steps are not safely implemented, some steps included several mutation function calls. 1 mutation = 1 step.
Check the docs https://earendil-works.github.io/absurd/
Also we should make use of events https://earendil-works.github.io/absurd/concepts/ instead of waiting/polling
There was a problem hiding this comment.
consider installing the absurd skill instead of our docs -> https://earendil-works.github.io/absurd/agents/
Split issue lifecycle status/comment rendering and durable workflow step helpers out of the main orchestration file. Expose Absurd events through the workflow context, use event-aware waits with sleep fallback, and keep GitHub comment/label writes in dedicated step calls. MoltNet-Diary: 16cbad53-f124-44ea-860e-9feae875b1b2
Install Absurd's bundled agent skill into the repository so agents can load the local absurdctl debugging playbook when working on issue-lifecycle durable workflows. MoltNet-Diary: 1c347b2c-07c1-46c1-922e-0179f9e3c47e
Summary
Adds
@themoltnet/issue-lifecycle, a concrete CLI app for driving the GitHub issue workflow from issue triage through planning, human approval, implementation, PR gate retry, release, and notification.The app registers an Absurd durable task named
github_issue_lifecycleand uses MoltNetfreeformtask continuations with correlation ids, references, andcontinueFromso each agent loop can pick up the prior session/worktree context.This also adds:
apps/issue-lifecycle/README.mdcovering the flow, task contract, CLI, retry/recovery model, manual e2e-stack smoke test, tests, and referencesinput.successCriteriafor generated lifecycle tasks, including parent task/attempt assertions for continuation outputsgh:issue:*labelsissue-lifecycle-dbandissue-lifecycle-db-migratecompose services that initialize the Absurd schema/queue for local and e2e testingAGENTS.mdguard requiring activated-agent GitHub tokens for PR/issue/comment writes so future PRs are authored by the active agent instead of a humanghloginTesting
pnpm nx syncpnpm exec nx run @themoltnet/issue-lifecycle:testpnpm exec nx run @themoltnet/issue-lifecycle:typecheckpnpm exec nx run @themoltnet/issue-lifecycle:lintpnpm exec nx run @themoltnet/issue-lifecycle:buildpnpm exec nx run @themoltnet/issue-lifecycle:check:packpnpm exec nx run @moltnet/absurd-migrate-image:docker:builddocker compose -f docker-compose.e2e.yaml config issue-lifecycle-db issue-lifecycle-db-migratedocker compose -f docker-compose.e2e.yaml -f docker-compose.e2e.ci.yaml config issue-lifecycle-db issue-lifecycle-db-migrateCOMPOSE_DISABLE_ENV_FILE=true docker compose -f docker-compose.e2e.yaml up -d --build issue-lifecycle-db-migrateCOMPOSE_DISABLE_ENV_FILE=true docker compose -f docker-compose.e2e.yaml up --build --force-recreate issue-lifecycle-db-migrateABSURD_DATABASE_URL=postgresql://issue_lifecycle:issue_lifecycle_secret@localhost:55434/issue_lifecycle uvx absurdctl list-queuesFollow-up Manual Validation
Full daemon-backed manual smoke testing is still planned. The local stack path now reaches the first durable wait: Absurd owns the workflow run, the app creates the triage task in the local MoltNet task DB, and the run sleeps while waiting for an accepted daemon attempt. The remaining manual step is running
apps/agent-daemonwith model credentials to execute the generated freeform tasks.Closes #1327.