Skip to content

Stage 3.3: the audit trail, rework reconciliation, and the strict release DAG regression #1730

Closed

Description

@Birfy

Written-by: Chief
Part of #1550, third slice of Stage 3. Runs under the owner's 2026-10-29 instruction to carry #1550 through Stages 1-4.

Depends on

3.1 (#1720) for the typed record (taskClass, reworkOf, handoff, evidence, lease) and 3.2 (#1729) for the role queues, worker isolation and lease recovery. This slice makes the result readable and proves the release path still works; it adds no new state.

Why

Stage 3's acceptance is about what a reader can prove after the fact: review rejection sent tracked rework, restart did not duplicate downstream work, the strict release DAG still passes. Those are statements about a history, and today the history is spread across a task note, a PR body and a workflow run.

What to build

  1. One audit trail, built from the rows. A read that answers, for one task: who handed it to whom and why (handoff), what evidence came back (evidence, each with its sha/pr/check), whether it was reworked and by which child (reworkOf), and who held the lease when. No new table, no new writing path — a projection over 3.1's records, rendered as text so a comment or a PR body can hold it.
  2. Rework reconciliation at the pipeline level. A rejection whose child later lands must show as one accepted delivery, not two: the parent is accepted, the child is rework, and the count of accepted deliveries does not double. The test drives a rejection→rework→accept cycle through two separate runs and asserts one accepted delivery and two records.
  3. Restart without duplication, end to end. Run the same graph twice against the same records with a crash between the claim and the result; the second start must not create a second downstream task, and the audit trail must show one chain.
  4. The strict release DAG regression. A test graph shaped like the release path (build → test → publish) marked strict; it must pass unchanged, run in declared order, and refuse a node whose input was not produced. This is the regression that keeps Stage 3.2's pool from changing how releases work.
  5. Readable from the clients. The audit text is reachable from the existing board/project endpoints (one field on the row, not a new endpoint if avoidable); the client shows it in the card's detail, no new page.

Acceptance

  • Tests in core/test/ and plugins/workflow/test/ for items 2, 3, 4; the audit projection has its own test over a fixture chain (handoff → evidence → rework → accept).
  • An accepted-delivery count that a replay cannot double; a chain that renders the same text twice from the same rows.
  • npm run verify green at the tip (TZ=UTC); generated files from source only; subsystem docs updated (core-host.md, workflow.md) or a valid Docs-not-needed: in both the branch commit and the PR body.
  • PR body: Part of #1550, Fixes #<this issue>, Owner: Chief, Reviewer: Reviewer, checkpoint block with claim: Chief.

Out of scope

Stage 4 (Chief meetings, assistants in live collaboration, personalized digests) and Stage 5 (reserved, design pending — do not start it).

Activity

  1. Birfy commented on Oct 29, 2026

    @Birfy
    CollaboratorAuthor

    Written-by: Triage

    agent-ready. Dependencies are landed on main: 3.1 #1720 merged as 29758029c4, 3.2 #1729 merged as 38d70fe305 (PR #1734) with tests-ok green at the tip. No open PR names this issue; no hold; no assignee. The owner's 2026-10-29 approval for Stages 1–4 is recorded on #1550, and this is its third Stage-3 slice.

    Scope (one line): project one audit text per task from the typed rows already on main (handoff, evidence, reworkOf, lease), make rework count as one accepted delivery per chain, and add the restart + strict-release-DAG regressions — no new state, no new endpoint, no new page.

    Where it lands:

    • core/src/host/tasks.js — new rt.taskAudit(id) that renders one text block from the existing fields (handoff from→to/reason/at, evidence entries sha/pr/check, the reworkOf chain, the current lease holder and window); nothing written, nothing stored. Also fix rt.taskCounters (~line 515): it currently increments deliveries for every accepted row, so a rework child plus its accepted parent counts twice — a chain counts one accepted delivery, two records.
    • core/src/host/project-board.js — one audit text field on the row it already builds; no second read path.
    • core/src/client/project-board.js and core/src/client/kanban.js — show audit inside the existing card detail (expandable on BoardCard), no new page; core/client.js regenerated with npm run build.
    • plugins/workflow/src only if the restart regression needs a host-facing hook — lease is read through rt.taskLease, never copied.
    • Docs: docs/subsystems/core-host.md and docs/subsystems/workflow.md, or a Docs-not-needed: line in both the branch commit and the PR body. A user-visible board text needs one changelog.d/<slug>.added.md fragment.

    Red first:

    • core/test/task-audit.test.js — fixture chain handoff→evidence→rework→accept renders identical text twice from the same rows; a pre-slice record (no typed fields) renders as empty, not a throw; the lease holder and window appear.
    • core/test/task-queue-lease.test.js (or a new counting test) — rejection→rework→accept across two runs gives one accepted delivery and two records; replaying the same accept does not increment.
    • plugins/workflow/test/strict-release-dag.test.js — release-shaped strict graph (build→test→publish) passes unchanged, runs in declared order, and refuses a node whose required input was never produced; a second start after a crash between claim and result creates no second downstream task and the audit text shows one chain.

    Acceptance: TZ=UTC npm run verify green at the tip; core/client.js and patches/ds-bot/ regenerated from source only; PR body carries Part of #1550, Fixes #1730, Owner: Chief, Reviewer: Reviewer, and a checkpoint block with claim: Chief.

    Risk basis: host task store + board read model + workflow plugin + client bundle + generated patch set — expect T2/T3 from risk-gate; the tier is computed at merge time, never read from a label.

  2. added
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 29, 2026
  3. self-assigned this
    on Oct 29, 2026
  4. added
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 29, 2026
  5. Birfy commented on Oct 29, 2026

    @Birfy
    CollaboratorAuthor

    Written-by: Dev

    Claimed #1730 — branch dev/1730-audit-trail. First step: the rt.taskAudit(id) projection over the typed records already on main.

  6. removed
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 29, 2026
  7. removed
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:automationScheduled tasks and automationenhancementNew feature or request

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions