# Issue Workflow Issues are work entries. The workflow is mostly human-driven at creation: create an issue, label it for risk and routing, optionally embed `/commands` to signal intent, and let PM (or yourself, in manual mode) handle the rest. Once an agent picks up the issue, the issue itself becomes the single thread of record — all agent ledgers live here. ## Creating an issue 1. **Title and body** — describe the _what_ and the _why_. Mark unknowns as `???`. 2. **Apply labels:** - `agent/new` — the only `agent/*` label you apply at creation. Issues without this label will not be triaged by the PM. - `risk/*` — flags the blast radius, influencing how the PM should brief the working agents. - `complexity/*` — influences how the PM should brief the working agents. - `priority/*` — helps agents choose next best issue to work on. - Domain labels as appropriate (`area/*`, `kind/bug`, etc.) 3. **Embed `/commands`** for intent you already know: - `/needs-spec` — you know this warrants a spec proposal as the first cycle - others per the [command vocabulary](./slash-commands.md) 4. Submit. Walk away. ## What PM does on `agent/new` 1. Reads the body and executes any `/commands`. 2. Curates an initial brief reflecting the requested phase (e.g. `/needs-spec` → brief asks the Developer to produce a spec proposal first; otherwise the brief frames the work as direct implementation) 3. Strips `agent/new`; the issue is now visible to you for dispatching the Developer 4. Records the activity in its per-issue ledger If you don't apply `agent/new`, PM ignores the issue. That's the opt-in: not every issue needs PM attention. ## Manual mode PM offline, or you don't want PM in the loop: - Apply the labels yourself in the UI - Skip `/commands` entirely and transition labels directly - Write a brief by hand using `` if you want one, or skip it The `agent/new` signal is inert when PM is off — it sits as a label until processed. Nothing breaks. ## Issue vs. PR - **Issue:** the _what_, the _why_, and the _record of work_ — problem statement, acceptance criteria, risk notes, all agent ledgers, the conversation - **PR:** the _how_ — implementation, evidence, validation output. Assume PR comments carry nothing of import Link both ways: PR body MUST reference the issue (`Refs #N`); issue gets the cross-link automatically from Forgejo. See [PR conventions](./pr.md). ## Closing PR merges do **not** auto-close the issue — the PR body uses `Refs #N`, not `Closes #N`. The issue stays open through dev → qa → PM finalization; `fjx pm close ` is the canonical close path. This avoids the "closed but not yet finalized" window where a closed issue would re-surface on every `pm next`. --- ## Ledger Model Each agent (PM, Developer, QA, Builder) maintains **one canonical ledger comment per issue**, which it **edits in place**. Ledger records what the assigned agent has done or still needs to do. The ledger is a small, issue-local task database implemented as one editable comment. It gives agents a durable memory surface without adding infrastructure. | Ledger | Marker | Owner | Lifetime | | --------- | ----------------------------- | ----------- | -------------------- | | Developer | `` | agent-dev | the issue's lifetime | | QA | `` | agent-qa | the issue's lifetime | | Builder | `` | agent-build | the issue's lifetime | | PM | `` | agent-pm | the issue's lifetime | All ledgers live on the issue. The PM ledger has a distinct role (assistant's record of `/commands` processed, briefs curated); see [PM role](../agents/pm.md). Working-agent ledgers track the assigned agent's tasks. - Issue comments: incoming requests - Ledger: normalized task queue for agent, progress tracker for reviewers - Commits: execution **Constraints:** - Uses Forgejo REST API (via `fjx`) - No external database - Human-readable - Idempotent across runs - Safe to resume after interruption - Durable in issue history **Non-Goals:** - Perfect natural-language comment parsing - Full conversation understanding - Complex task dependency tracking - Replacing Forgejo labels - Replacing human review **Multi-Agent Support:** Each agent manages its own work ledger. Agents MUST NOT modify other agents' ledgers. Assume only one active agent for each role (Developer, QA, Builder). **Interaction With Labels:** The ledger tracks per-issue agent work. Labels drive the broader workflow (see [primitives overview](./)). --- ## Agent Cycle Each agent invocation is a one-shot cycle. The executor schedules invocations; the agent itself does not loop in-process. One cycle: 1. Claim the issue: transition `agent/` → `agent/working` (`fjx claim `) 1. Fetch issue comments 1. Locate ledger (on the issue) by marker 1. Parse existing tasks 1. Extract new directives/questions/suggestions 1. Append new tasks 1. Execute open tasks 1. Update task statuses 1. Update checkpoint 1. Edit ledger comment 1. Hand off: transition `agent/working` → `agent/review` (`fjx issue label --add agent/review --remove agent/working`) --- ## Forgejo Integration Agents MUST go through `fjx`. Do not hand-roll `https`/`curl` against the Forgejo REST API — the CLI handles auth, repo identity, caching, and label resolution. If a needed operation is missing from the CLI, that is a gap to file as an issue, not a license to bypass the CLI. Run `fjx --help` for the current command surface. Commands used in the ledger flow: ``` fjx comment list [--since ] # fetch issue comments (optionally since checkpoint) fjx comment create --issue --body-file ./tmp/body.md fjx comment edit --body-file ./tmp/body.md fjx dev ledger --body-file ./tmp/ledger.md # upsert agent-dev:ledger on the current issue fjx qa ledger --body-file ./tmp/ledger.md # upsert agent-qa:ledger on the current issue fjx dev next [] # start the next dev cycle: pick or load , set up worktree, claim (label + assignee + ledger), emit pm:brief:dev fjx qa claim # assign agent-qa; create QA ledger if absent fjx dev done # → agent/review on issue; reassign issue to agent-pm; assign linked PR to $FJX_OWNER fjx qa checks # list Forgejo Actions runs for PR 's head SHA ``` **Known CLI gaps** (surface the gap in your ledger rather than bypass): - No `fjx build ledger` — the builder currently upserts its ledger via the generic `comment create` / `comment edit` primitives combined with a marker lookup. Mirroring `dev ledger` / `qa ledger` for the builder would round out the set. Implementation details live in `src/`; the Forgejo REST surface is documented at https://git.tfks.net/swagger.v1.json for CLI authors, not for agents. --- ## Ledger Lifecycle The ledger comment MUST include a unique marker: ```html ``` Every agent cycle MUST leave a ledger entry and a PR — even outcomes like "won't fix" or "not reproducible" warrant a `./wiki/findings/-.md` recording the justification. The work is invisible without evidence; "I looked and decided no" is a finding. Fetch existing comments with `fjx comment list ` (optionally `--since `). Upsert the ledger comment with the marker-aware helper: `fjx ledger --body-file ./tmp/ledger.md` for dev and qa; the builder uses `fjx comment create` / `comment edit` with its marker until its dedicated subcommand ships (see "Known CLI gaps" above). **Update Cursor:** An ISO-formatted timestamp `checkpoint` records when the agent's work was last reflected in the ledger. It signals "I have addressed all comments made to this point". Once the agent's ledger comment has been identified, save its `checkpoint` timestamp to local cache. This timestamp can be passed as `--since ` to `fjx comment list` to fetch only new comments. **NOTE:** Before submitting an updated ledger, look for any new comments that arrived since the last checkpoint. Avoid missing work for comment 2 in this scenario: - Issue opened - ledger created - comment 1 - implementing work from comment 1 - comment 2 - ledger checkpointed comment 1 - comment 3 - implementing work from comment 3 To avoid this, read the current ledger checkpoint time and use that to find all comments since then. Ensure that all tasks from those comments are included in the ledger when checkpointing. There is still a possible race condition, but the window is small enough to be acceptable at this point. --- ## Ledger Structure ```markdown ## Ledger for: agent- Status: {working,blocked,review,complete} @ --- ### Tasks - [ ] D001 — DESCRIPTION - Source: - Status: pending | in-progress | blocked - [x] D002 — DESCRIPTION - ✔ commit or explanation ### Notes - Freeform observations ``` --- ## Task Management Rules ### Task Creation Agent MUST: - Extract actionable items from issue comments after `checkpoint` - Treat lines that begin with `/` as inert text — `/` syntax handled by the fjx tooling. Agents MUST NOT create tasks from them, even if the surrounding prose is directive-like. - Classify the remaining comment content: - `directive` → MUST create task - `question` → MUST create task - `suggestion` → MAY create task - `approval` → no task required - `noise` → ignore - Assign unique task IDs using the format `D###` ### Task Completion Agent MUST only mark a task complete when: - work is implemented, OR - the task is explicitly resolved with an explanation Completed tasks MUST include evidence: - commit SHA, OR - explanation if no code change was needed Example: ```markdown - [x] D002 — Add validation for missing config - Evidence: commit abc123 ``` Alternative resolution: ```markdown - [x] D003 — Consider switching parser library - Resolution: Not implemented; existing parser already supports required behavior. ``` ### Task Safety Agent MUST NOT: - mark unclear items as complete - silently ignore directives - delete unresolved tasks If a task is unclear, mark it blocked: ```markdown - [ ] D004 — Clarify expected behavior for empty input - Status: blocked - Needs: human clarification ``` --- ## Addressing Review Feedback When a reviewer requests changes (at `agent/review`), the agent MUST: 1. Read all issue comments since the ledger checkpoint 2. Extract tasks per the Task Management Rules above 3. Implement the requested changes 4. Push the changes 5. Post an issue comment summarizing what changed and referencing each addressed comment 6. Update the ledger (new tasks marked complete, checkpoint advanced) 7. Re-signal readiness: `fjx issue label --add agent/review --remove agent/working` Do not stop after pushing. A silent push leaves the work in an ambiguous state — the reviewer has no signal that their feedback was addressed. --- ## Failure Handling **Missing Ledger:** If no ledger exists, the agent MUST create one. **Corrupted or Duplicate Ledgers:** Comment at the top of the ledger on the condition with any diagnostic info (e.g. error messages). Label as `agent/review`.