Skip to content

Commit 84f02fe

Browse files
committed
feat: manage proposed todo requirements
1 parent f116c82 commit 84f02fe

11 files changed

Lines changed: 408 additions & 24 deletions

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,15 @@ flowchart LR
6969

7070
1. A human creates a Requirement and chooses Codex or Claude Code, optionally pinning a model and reasoning effort. Code Factory creates a dedicated, persistent RD session for it.
7171
2. Agent Manager starts or resumes that agent in the managed workspace. Messages sent during a run are queued; the human may explicitly interrupt when an immediate correction is needed.
72-
3. The RD agent edits and tests the repository, then uses the bundled `code-factory-cli` to register any pull request it creates, propose separate follow-up work (optionally starting it immediately), update its still-TODO proposals, inspect its direct parent and child Requirements, message their RD Agents, or schedule a wake-up while a long external build or command continues. Related-Agent messages are persisted in the target Requirement conversation and start or queue its long-lived RD session.
72+
3. The RD agent edits and tests the repository, then uses the bundled `code-factory-cli` to register any pull request it creates, propose separate follow-up work, update, start, or delete its still-TODO proposals, inspect its direct parent and child Requirements, message their RD Agents, or schedule a wake-up while a long external build or command continues. Related-Agent messages are persisted in the target Requirement conversation and start or queue its long-lived RD session.
7373
4. Agent Triggers route normalized, deduplicated messages into the Requirement conversation. The timer trigger executes configurable one-time or recurring timers and sends their ID and follow-up description when due. The GitHub triggers poll registered PRs whose last stored state is Draft or Open, observing state, comments and reviews, CI failures, and merge conflicts. This lets the reconciler discover when a Draft PR becomes Open. Once a PR transitions to Closed or Merged, it is excluded from later polls. An idle RD session resumes immediately; a running session consumes the new messages after its current run.
7474
5. A human can request a short-lived AI review for an open PR with its own provider, model, and reasoning effort. Review results return to the same conversation and wake the original RD session to continue the loop.
7575

7676
The Agent Trigger boundary is intentionally source-neutral, but its current message contract targets an existing Requirement. Scheduled wake-ups are natively configurable; dynamic discovery and configuration of third-party trigger implementations, Slack and Jira sources, and triggers that create new Requirements are future extensions rather than implemented behavior.
7777

7878
Different Requirements can run concurrently, while each Requirement has at most one active RD run. Requirement state, conversations, runs, sessions, PR metadata, scheduled wake-ups, and Agent Trigger receipts are persisted in SQLite. Cancelled Requirements are retained for 7 days and completed Requirements for 365 days by default; both periods are runtime-configurable, and expiry atomically removes the Requirement and its related domain records while retaining retryable tombstones until attachment files are deleted.
7979

80-
Agent Manager places `code-factory-cli` on every RD process's `PATH` and injects its API URL, Requirement ID, and Session ID through the environment. The RD prompt describes available capabilities and leaves command names and arguments to `code-factory-cli --help`; raw HTTP details remain an internal transport contract. Use `code-factory-cli pr register --from-github <PR-URL>` to read current metadata through `gh`, `requirement propose --description-file <PATH> [--start]` for multiline follow-up descriptions with optional immediate execution, and `requirement update --requirement-id <ID>` to correct a proposal before it starts. Resumed prompts retain the current Requirement context and instruct agents to check for already-completed actions before retrying.
80+
Agent Manager places `code-factory-cli` on every RD process's `PATH` and injects its API URL, Requirement ID, and Session ID through the environment. The RD prompt describes available capabilities and leaves command names and arguments to `code-factory-cli --help`; raw HTTP details remain an internal transport contract. Use `code-factory-cli pr register --from-github <PR-URL>` to read current metadata through `gh`, `requirement propose --description-file <PATH> [--start]` for multiline follow-up descriptions with optional immediate execution, and the `requirement update`, `requirement start`, or `requirement delete` command with `--requirement-id <ID>` to manage a proposal while it remains TODO. Resumed prompts retain the current Requirement context and instruct agents to check for already-completed actions before retrying.
8181

8282
Agent context is scoped to the Requirement rather than copied from whichever interactive agent or terminal started Agent Manager. A Requirement's first RD Run creates a new native Codex thread or Claude Code session; later Runs resume that same native session, preserving its conversation context. Because the child CLI inherits Agent Manager's environment and starts in the managed workspace, it also discovers the provider's configured project/user instructions, Skills, plugins, and local memory features according to the CLI's own rules. Code Factory does not automatically copy another agent's live transcript or merge context from other Requirements. An explicit related-Agent message is new, durable input to the target Requirement rather than shared session context. Code Factory does not guarantee that every provider-managed memory entry is injected.
8383

docs/agent-manager-api.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ The service listens only on the loopback interface by default and currently has
6767
| POST | /api/agent/pull-requests | Register or update a PR from an RD Agent |
6868
| POST | /api/agent/requirements | Propose a follow-up Requirement from an RD Agent |
6969
| PATCH | /api/agent/requirements/:id | Update a TODO Requirement proposed by the current RD Agent |
70+
| DELETE | /api/agent/requirements/:id | Delete a TODO Requirement proposed by the current RD Agent |
71+
| POST | /api/agent/requirements/:id/start | Start a TODO Requirement proposed by the current RD Agent |
7072
| GET | /api/agent/requirements/:id/related | List a source Requirement's direct parent and children |
7173
| POST | /api/agent/requirements/:id/related/:targetId/messages | Message a directly related Requirement's RD Agent |
7274

@@ -705,6 +707,8 @@ These endpoints are the transport used by `code-factory-cli` and other trusted l
705707
code-factory-cli pr register --help
706708
code-factory-cli requirement propose --help
707709
code-factory-cli requirement update --help
710+
code-factory-cli requirement start --help
711+
code-factory-cli requirement delete --help
708712
code-factory-cli requirement related --help
709713
code-factory-cli requirement message --help
710714
code-factory-cli timer register --help
@@ -818,6 +822,39 @@ code-factory-cli requirement update --requirement-id req_child --title 'Correcte
818822
code-factory-cli requirement update --requirement-id req_child --description-file ./corrected-scope.md
819823
~~~
820824

825+
### POST /api/agent/requirements/:targetRequirementId/start
826+
827+
Starts a proposed child Requirement while it remains TODO. The JSON request body requires `sourceRequirementId` and `sourceSessionId`; they must identify the RD Session that originally proposed the target.
828+
829+
~~~bash
830+
curl -X POST http://127.0.0.1:4310/api/agent/requirements/req_child/start \
831+
-H 'Content-Type: application/json' \
832+
-d '{
833+
"sourceRequirementId": "req_parent",
834+
"sourceSessionId": "ses_parent"
835+
}'
836+
~~~
837+
838+
Success: 202 Accepted with `accepted`, `action=start`, the started Requirement/session snapshot, and its running RD Run. Returns 404 for an unknown source or target, 400 for a mismatched source Session, and 409 when the target was not proposed by the source or is no longer TODO.
839+
840+
~~~bash
841+
code-factory-cli requirement start --requirement-id req_child
842+
~~~
843+
844+
### DELETE /api/agent/requirements/:targetRequirementId
845+
846+
Deletes a proposed child Requirement while it remains TODO. The required `sourceRequirementId` and `sourceSessionId` query parameters must identify the RD Session that originally proposed the target. Deletion follows the normal Requirement lifecycle: the Requirement becomes CANCELLED and is retained according to workspace policy.
847+
848+
~~~bash
849+
curl -X DELETE 'http://127.0.0.1:4310/api/agent/requirements/req_child?sourceRequirementId=req_parent&sourceSessionId=ses_parent'
850+
~~~
851+
852+
Success: 200 OK with `{ "deleted": true, "requirement": ... }`. Returns 404 for an unknown source or target, 400 for missing or mismatched source context, and 409 when the target was not proposed by the source or is no longer TODO.
853+
854+
~~~bash
855+
code-factory-cli requirement delete --requirement-id req_child
856+
~~~
857+
821858
### GET /api/agent/requirements/:sourceRequirementId/related
822859

823860
Returns the source Requirement's direct parent and children as `{ "parent": Requirement | null, "children": Requirement[] }`, including terminal records that have not yet expired. The required `sourceSessionId` query parameter must identify the source Requirement's RD Session.

docs/agent-runners.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,24 +42,28 @@ RD Agents use self-describing commands instead of constructing Agent API request
4242
code-factory-cli pr register --help
4343
code-factory-cli requirement propose --help
4444
code-factory-cli requirement update --help
45+
code-factory-cli requirement start --help
46+
code-factory-cli requirement delete --help
4547
code-factory-cli timer register --help
4648
code-factory-cli timer show --help
4749
code-factory-cli timer cancel --help
4850
```
4951

50-
`pr register` registers a newly created PR or refreshes metadata changed by the RD Agent. `requirement propose` records separate follow-up work as a linked TODO Requirement, and `requirement update` corrects the title or description of a proposal before it starts. `requirement related` lists direct parent and child Requirements; `requirement message` coordinates with their RD Agents. `timer register` registers a one-time wake-up by default or a recurring one with `--repeat`; `timer show` recovers timer IDs and statuses for the current Requirement; `timer cancel` stops an active timer. The commands print the Agent API JSON response on stdout. Exit code `0` means success, `2` means invalid input or missing context, and `1` means an execution, network, HTTP, or response-format failure. Errors go to stderr. API requests and GitHub lookups time out after 30 seconds; writes are never automatically retried. A timeout or invalid response can occur after the server commits a write: inspect the Requirement before retrying, especially when proposing or updating follow-up work.
52+
`pr register` registers a newly created PR or refreshes metadata changed by the RD Agent. `requirement propose` records separate follow-up work as a linked TODO Requirement; `requirement update`, `requirement start`, and `requirement delete` manage that proposal before it starts. `requirement related` lists direct parent and child Requirements; `requirement message` coordinates with their RD Agents. `timer register` registers a one-time wake-up by default or a recurring one with `--repeat`; `timer show` recovers timer IDs and statuses for the current Requirement; `timer cancel` stops an active timer. The commands print the Agent API JSON response on stdout. Exit code `0` means success, `2` means invalid input or missing context, and `1` means an execution, network, HTTP, or response-format failure. Errors go to stderr. API requests and GitHub lookups time out after 30 seconds; writes are never automatically retried. A timeout or invalid response can occur after the server commits a write: inspect the Requirement before retrying, especially when proposing or managing follow-up work.
5153

5254
Prefer registration from an explicit PR URL, using the authenticated local `gh` CLI:
5355

5456
```bash
5557
code-factory-cli pr register --from-github https://github.com/OWNER/REPO/pull/123
5658
code-factory-cli requirement propose --title 'Follow-up task' --description-file ./follow-up.md --start
5759
code-factory-cli requirement update --requirement-id req_... --description-file ./corrected-follow-up.md
60+
code-factory-cli requirement start --requirement-id req_...
61+
code-factory-cli requirement delete --requirement-id req_...
5862
```
5963

6064
`--from-github` reads the PR number, title, URL, branches, head SHA, and state from GitHub and validates the returned identity before registration. The repository key comes from the returned URL and is normalized to lowercase, matching Manager and Store identity checks. GitHub Enterprise URLs are supported and retain the hostname in the repository identifier. It cannot be mixed with manual metadata flags. The existing full manual registration form remains supported for callers that already have a snapshot; an existing PR's lifecycle is still owned by the reconciler, even when `--status` is supplied. The CLI does not create or edit GitHub PRs.
6165

62-
`--description-file` reads a UTF-8 file relative to the CLI's working directory and is mutually exclusive with `--description`. This avoids shell quoting problems for multiline descriptions. Proposed Requirements remain TODO by default; `--start` starts the new Requirement's RD Session immediately. Only the same source RD Session can update its directly proposed child, and only while that child remains TODO.
66+
`--description-file` reads a UTF-8 file relative to the CLI's working directory and is mutually exclusive with `--description`. This avoids shell quoting problems for multiline descriptions. Proposed Requirements remain TODO by default; `--start` starts the new Requirement's RD Session immediately. Only the same source RD Session can update, start, or delete its directly proposed child, and only while that child remains TODO.
6367

6468
The RD behavioral prompt is supplied on both initial and resumed invocations. It describes CLI capabilities and behavioral constraints, leaving command names and arguments to `code-factory-cli --help`. It covers Requirement scope, worktree isolation, recovery without duplicate actions, control-plane commands, lifecycle ownership, evaluating external feedback, and evidence-based handoff. Task-specific content stays in the stdin prompt; every invocation includes the current Requirement ID, title, and description, with only new external conversation messages on resume. Questions and investigations do not inherently require code changes, and the RD Agent must not substitute follow-up proposals for work required by the current Requirement. A successful GitHub PR creation and a successful Code Factory registration are separate outcomes; a failed registration must be reported without recreating the PR. Human confirmation owns Requirement completion.
6569

docs/architecture.en.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ Every headless RD and Reviewer invocation skips interactive approval and CLI san
8080
- optional `model` and `reasoningEffort` pin the CLI configuration for every RD Run in the Session;
8181
- `createdBy`: `human | rd_agent`;
8282
- an agent-proposed Requirement records `parentRequirementId` and `sourceSessionId`;
83-
- the source RD Session may update that proposed child's title or description only while it remains TODO;
84-
- an agent proposal is created as TODO by default, preventing uncontrolled recursive work; an explicit CLI `--start` opt-in starts its RD Session immediately.
83+
- the source RD Session may update, start, or delete that proposed child only while it remains TODO;
84+
- an agent proposal is created as TODO by default, preventing uncontrolled recursive work; an explicit CLI `--start` opt-in starts its RD Session immediately, while `requirement start` can start it later.
8585
- the proposing Requirement and its direct child can discover each other and exchange explicit, durable RD messages without sharing native agent-session context.
8686

8787
### AgentSession

docs/protocol.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,24 @@ Content-Type: application/json
137137

138138
`title` and `description` are partial updates, with at least one required. The target must be a direct child created by the same source RD Session and must still be TODO. `code-factory-cli requirement update --requirement-id req_child` supplies the source identifiers from the injected context.
139139

140+
Start or delete a still-TODO proposal later:
141+
142+
~~~http
143+
POST /api/agent/requirements/req_child/start
144+
Content-Type: application/json
145+
146+
{
147+
"sourceRequirementId": "req_parent",
148+
"sourceSessionId": "ses_parent"
149+
}
150+
~~~
151+
152+
~~~http
153+
DELETE /api/agent/requirements/req_child?sourceRequirementId=req_parent&sourceSessionId=ses_parent
154+
~~~
155+
156+
The corresponding CLI commands are `requirement start --requirement-id req_child` and `requirement delete --requirement-id req_child`. Both enforce the same source-Session ownership and TODO-only rules as updates. Starting enters the normal RD Run lifecycle; deleting enters the normal cancelled-retention lifecycle.
157+
140158
Inspect and message directly related Requirements:
141159

142160
~~~bash

0 commit comments

Comments
 (0)