Require Controller Handoff plus Thread State Ledger for workflow comments #507

Closed
opened 2026-07-08 02:39:48 -05:00 by jcwalker3 · 3 comments
Owner

Problem

Current PR/issue threads often contain long controller handoffs that are useful for LLM continuation but too dense for humans, reviewers, mergers, reconcilers, and later agents to quickly understand.

They also mix together:

  • local validation
  • intended decisions
  • actual Gitea/server-side mutations
  • failed tool calls
  • blockers
  • next steps
  • proof logs
  • live narration

This makes it hard to know what is actually true now.

Examples of dangerous ambiguity:

  • "approved" without saying whether the APPROVED review was posted to Gitea
  • "merged" without a merge mutation ledger entry
  • "blocked" without the exact failing gate
  • "ready" without a pinned head SHA and validation proof
  • "queued" without naming the next actor/action
  • handoffs that claim one mutation happened while the mutation ledger lists something else

Required behavior

After any LLM/controller performs meaningful workflow work, it must leave two separate comments:

1. [CONTROLLER HANDOFF]

Purpose:
Detailed operational handoff for the next LLM/controller session.

This comment may be long and proof-heavy.

It must include:

  • identity/profile proof
  • repo
  • issue/PR selected
  • role conflict / self-review proof when relevant
  • branch/worktree
  • pinned PR head SHA when relevant
  • files changed or reviewed
  • commands run
  • validation results
  • tool calls
  • server-side mutation ledger
  • local-only changes
  • blockers
  • ready-to-paste next-session prompt

2. [THREAD STATE LEDGER]

Purpose:
Short canonical truth/state message for humans and future agents.

This comment must answer:

  • what is true now
  • what changed
  • what is blocked
  • who/what acts next

It must clearly separate:

  • local verdict/state
  • server-side Gitea state
  • attempted-but-blocked mutations
  • completed mutations

The ledger should be readable in 30 seconds without reading the full handoff or prior thread history.

Canonical templates

Controller Handoff template

[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>
- <step 3>

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

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

Server-side mutation ledger:
- <mutation 1, including tool/action/comment id if available>
- <mutation 2>
- 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 of what changed since the prior ledger>

What is blocked:
- <none>
- Or: <exact blocker and whether it is code, process, environment, permission, conflict, stale head, or tool behavior>

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

Required blocker classifications

The [THREAD STATE LEDGER] must classify blockers as one of:

  • 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

Required state language

The implementation should prefer precise state phrases over ambiguous ones.

Use:

  • APPROVE verdict prepared locally
  • APPROVED review posted to Gitea
  • REQUEST_CHANGES posted to Gitea
  • merge performed
  • merge not performed
  • lease acquired
  • lease attempt blocked
  • tests passed locally
  • full suite not rerun
  • server-side state changed
  • no server-side state changed

Avoid ambiguous standalone claims like:

  • approved
  • ready
  • queued
  • blocked
  • done
  • merged
  • submitted
  • validated

unless the comment includes proof and server-side state.

Acceptance criteria

  1. Add canonical documentation/templates for:

    • [CONTROLLER HANDOFF]
    • [THREAD STATE LEDGER]
  2. Require every meaningful controller handoff/final report to be followed by a thread state ledger.

  3. The thread state ledger must include:

    • PR/issue state
    • current head SHA if a PR is involved
    • server-side mutation state
    • local-only state
    • latest validation summary
    • blocker classification
    • next actor
    • exact next action
    • explicit "do not do" when retrying the wrong action would be harmful
  4. Add validation/checking logic where appropriate to warn or fail closed when:

    • a handoff says "approved" but does not say whether the Gitea review was posted
    • a handoff says "merged" but the mutation ledger lacks merge proof
    • a handoff says "blocked" but does not identify the exact failing gate
    • a handoff lacks a follow-up [THREAD STATE LEDGER]
    • narrative claims conflict with the mutation ledger
    • local verdict is not separated from server-side decision state
  5. Add examples for:

    • approved review posted
    • approve validated locally but blocked before posting
    • request changes posted
    • merge completed
    • merge blocked
    • reconciler closure
    • environment/tooling blocker
    • stale head blocker
    • duplicate/canonicalization blocker
  6. Add tests for the validator/checker covering:

    • missing ledger after controller handoff
    • ambiguous "approved"
    • ambiguous "merged"
    • blocked without gate name
    • mutation ledger contradiction
    • local-only verdict incorrectly described as server-side state
    • valid two-comment report passes
  7. Ensure existing reviewer, merger, author, and reconciler workflows still pass their current tests.

Out of scope

  • Replacing the detailed controller handoff entirely.
  • Removing proof-heavy final reports.
  • Changing role permissions.
  • Weakening mutation gates.
  • Allowing root-checkout mutations.

Desired outcome

Anyone should be able to open a PR or issue thread, read the latest [THREAD STATE LEDGER], and know the real current state without reading the full history.

The [CONTROLLER HANDOFF] remains the detailed continuation artifact.

The [THREAD STATE LEDGER] becomes the concise source of truth.

## Problem Current PR/issue threads often contain long controller handoffs that are useful for LLM continuation but too dense for humans, reviewers, mergers, reconcilers, and later agents to quickly understand. They also mix together: - local validation - intended decisions - actual Gitea/server-side mutations - failed tool calls - blockers - next steps - proof logs - live narration This makes it hard to know what is actually true now. Examples of dangerous ambiguity: - "approved" without saying whether the APPROVED review was posted to Gitea - "merged" without a merge mutation ledger entry - "blocked" without the exact failing gate - "ready" without a pinned head SHA and validation proof - "queued" without naming the next actor/action - handoffs that claim one mutation happened while the mutation ledger lists something else ## Required behavior After any LLM/controller performs meaningful workflow work, it must leave two separate comments: ### 1. `[CONTROLLER HANDOFF]` Purpose: Detailed operational handoff for the next LLM/controller session. This comment may be long and proof-heavy. It must include: - identity/profile proof - repo - issue/PR selected - role conflict / self-review proof when relevant - branch/worktree - pinned PR head SHA when relevant - files changed or reviewed - commands run - validation results - tool calls - server-side mutation ledger - local-only changes - blockers - ready-to-paste next-session prompt ### 2. `[THREAD STATE LEDGER]` Purpose: Short canonical truth/state message for humans and future agents. This comment must answer: - what is true now - what changed - what is blocked - who/what acts next It must clearly separate: - local verdict/state - server-side Gitea state - attempted-but-blocked mutations - completed mutations The ledger should be readable in 30 seconds without reading the full handoff or prior thread history. ## Canonical templates ### 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> - <step 3> Files touched or reviewed: - `<file>` — <why it matters> - `<file>` — <why it matters> Validation: - `<command>` → <result> - `<command>` → <result> - Full suite: <result or not run + reason> Server-side mutation ledger: - <mutation 1, including tool/action/comment id if available> - <mutation 2> - 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 of what changed since the prior ledger> What is blocked: - <none> - Or: <exact blocker and whether it is code, process, environment, permission, conflict, stale head, or tool behavior> Who/what acts next: - Next actor: - Required action: - Do not do: - Resume from: ``` ## Required blocker classifications The `[THREAD STATE LEDGER]` must classify blockers as one of: * 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 ## Required state language The implementation should prefer precise state phrases over ambiguous ones. Use: * `APPROVE verdict prepared locally` * `APPROVED review posted to Gitea` * `REQUEST_CHANGES posted to Gitea` * `merge performed` * `merge not performed` * `lease acquired` * `lease attempt blocked` * `tests passed locally` * `full suite not rerun` * `server-side state changed` * `no server-side state changed` Avoid ambiguous standalone claims like: * approved * ready * queued * blocked * done * merged * submitted * validated unless the comment includes proof and server-side state. ## Acceptance criteria 1. Add canonical documentation/templates for: * `[CONTROLLER HANDOFF]` * `[THREAD STATE LEDGER]` 2. Require every meaningful controller handoff/final report to be followed by a thread state ledger. 3. The thread state ledger must include: * PR/issue state * current head SHA if a PR is involved * server-side mutation state * local-only state * latest validation summary * blocker classification * next actor * exact next action * explicit "do not do" when retrying the wrong action would be harmful 4. Add validation/checking logic where appropriate to warn or fail closed when: * a handoff says "approved" but does not say whether the Gitea review was posted * a handoff says "merged" but the mutation ledger lacks merge proof * a handoff says "blocked" but does not identify the exact failing gate * a handoff lacks a follow-up `[THREAD STATE LEDGER]` * narrative claims conflict with the mutation ledger * local verdict is not separated from server-side decision state 5. Add examples for: * approved review posted * approve validated locally but blocked before posting * request changes posted * merge completed * merge blocked * reconciler closure * environment/tooling blocker * stale head blocker * duplicate/canonicalization blocker 6. Add tests for the validator/checker covering: * missing ledger after controller handoff * ambiguous "approved" * ambiguous "merged" * blocked without gate name * mutation ledger contradiction * local-only verdict incorrectly described as server-side state * valid two-comment report passes 7. Ensure existing reviewer, merger, author, and reconciler workflows still pass their current tests. ## Out of scope * Replacing the detailed controller handoff entirely. * Removing proof-heavy final reports. * Changing role permissions. * Weakening mutation gates. * Allowing root-checkout mutations. ## Desired outcome Anyone should be able to open a PR or issue thread, read the latest `[THREAD STATE LEDGER]`, and know the real current state without reading the full history. The `[CONTROLLER HANDOFF]` remains the detailed continuation artifact. The `[THREAD STATE LEDGER]` becomes the concise source of truth.
jcwalker3 added the status:in-progress label 2026-07-08 02:42:56 -05:00
Author
Owner

Issue claim heartbeat

<!-- gitea-issue-claim-heartbeat:v1 --> **Issue claim heartbeat** - kind: claim - issue: #507 - branch: pending - phase: claimed - profile: prgs-author - pr: none - blocker: none - next_action: create worktree and begin implementation
Author
Owner

Issue claim heartbeat

<!-- gitea-issue-claim-heartbeat:v1 --> **Issue claim heartbeat** - kind: progress - issue: #507 - branch: feat/issue-507-controller-thread-ledger - phase: pr-ready - profile: prgs-author - pr: none - blocker: none - next_action: create PR
Author
Owner

Issue claim heartbeat

<!-- gitea-issue-claim-heartbeat:v1 --> **Issue claim heartbeat** - kind: progress - issue: #507 - branch: feat/issue-507-controller-thread-ledger - phase: pr-opened - profile: prgs-author - pr: #511 - blocker: none - next_action: await review
sysadmin removed the status:in-progress label 2026-07-09 08:27:48 -05:00
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Scaled-Tech-Consulting/Gitea-Tools#507