# Two-comment workflow: Controller Handoff + Thread State Ledger

After meaningful controller/workflow work, post **two separate Gitea comments**:

1. **`[CONTROLLER HANDOFF]`** — detailed operational handoff for the next
   LLM/controller session (proof-heavy; may be long).
2. **`[THREAD STATE LEDGER]`** — short canonical truth readable in ~30 seconds.

The ledger is the concise source of truth. The handoff is the detailed
continuation artifact. This complements CTH (#505) and lifecycle state
comments (#494/#495) without replacing them.

## Controller Handoff template

```markdown
[CONTROLLER HANDOFF] PR #___ / Issue #___ — <short title>

Purpose:
This comment is the operational handoff for the next controller/LLM session.

Identity/profile:
- Active profile:
- Authenticated identity:
- Role:
- Self-review / role-conflict proof:

Target:
- Repo:
- Issue:
- PR:
- Branch:
- Pinned head SHA:
- Worktree:

Work performed:
- <step 1>
- <step 2>

Files touched or reviewed:
- `<file>` — <why it matters>

Validation:
- `<command>` → <result>
- Full suite: <result or not run + reason>

Server-side mutation ledger:
- <mutation 1, including tool/action/comment id if available>
- Or: none — no server-side state changed

Local-only changes:
- <worktree created, files edited locally, etc.>
- Or: none

Blockers:
- <none>
- Or: <exact blocker, exact gate, exact reason>

Controller prompt for next session:
```markdown
<ready-to-paste prompt>
```
```

## Thread State Ledger template

```markdown
[THREAD STATE LEDGER] PR #___ / Issue #___ — <current state in one line>

What is true now:
- PR state:
- Issue state:
- Current head SHA:
- Server-side decision state:
- Local verdict/state:
- Latest known validation:

What changed:
- <short summary since prior ledger>

What is blocked:
- Blocker classification: <see list below>

Who/what acts next:
- Next actor:
- Required action:
- Do not do:
- Resume from:
```

### Blocker classifications

- code blocker
- test blocker
- merge conflict
- stale head
- permission/capability blocker
- environment/tooling blocker
- process/rule blocker
- queue/lease blocker
- duplicate/canonicalization blocker
- no blocker

### Precise state language

Prefer:

- `APPROVE verdict prepared locally`
- `APPROVED review posted to Gitea`
- `REQUEST_CHANGES posted to Gitea`
- `merge performed` / `merge not performed`
- `lease acquired` / `lease attempt blocked`
- `server-side state changed` / `no server-side state changed`

Avoid ambiguous standalone claims (`approved`, `ready`, `merged`, `blocked`,
`done`) without proof and server-side state separation.

## Validation

- `thread_state_ledger_validator.py` — comment and final-report checks
- `gitea_create_issue_comment` — fail-closed gate on tagged comments
- `assess_final_report_validator` — `shared.two_comment_workflow` rule

Examples: [`examples/two-comment-workflow-examples.md`](examples/two-comment-workflow-examples.md)