Skip to content

Record a shadow pool verdict on each workflow run - #1873

Merged
Birfy merged 5 commits into
mainfrom
i1862-shadow-pass
Oct 30, 2026
Merged

Birfy merged 5 commits into
mainfrom
i1862-shadow-pass

Conversation

@Birfy

@Birfy Birfy commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

Written-by: Dev
Owner: Dev
Reviewer: Reviewer

Fixes #1862

What changed

P1 of the handoff pool (#1862): the P0 contract (#1853) now runs in shadow mode on the run path. A run whose card carries an acceptance gate or evidence — or whose caller passes handoff/handoffContext to assign() — records the contract's answer as shadow: { verdict, code?, reason? } and posts one shadow: <verdict> · <code> · <reason> line in its own stage log.

Record only. Nothing reads the record: the run, the card and the PR fast lane behave exactly as before. No Verdict: header, no PR comment, no enqueue, no merge, no new gate — core/src/host/ and core/client.js are untouched.

Reverting plugins/workflow/src/pool-shadow.js and service.js to main turns the new test file red (2 controls stay green): 6 of 8 fail.

Verification at the tip

Tip SHA: 53eb7b9
tests-ok at this tip: green (test, plugins tree/social/timeline/workflow, package, Node 24), and the workflow suite is the affected one.
Dev's local run — cd plugins/workflow && TZ=UTC node --import ./test/resolve.mjs --test "test/*.test.js", 324/324 — was at the previous tree; Rework did not re-run a local suite at this tip. node --check on the merged plugins/workflow/src/service.js passes here.

Merged main

The branch content carried none of main since 2ffd9fc3: the two "merge main" commits (a47a1afe, 4590c5f5) kept the branch tree, so the tip would have reverted #1870 and #1874 on the way in. Rework rebuilt the tip on the current main (c1ff15c4) with the change applied, three overlaps resolved by keeping both sides: the #1869 brief and the #1862 handoff/handoffContext/acceptance/evidence travel on the same parked row (carriedTask, park), assign() keeps main's ignored wrapper around the handoff facts, and the four names joined ASSIGN_FIELDS. docs/subsystems/workflow.md carries both texts. The pull request now diffs to this change set alone (6 files, no revert).

Written-by: Rework

Checkpoint

{
  "pr": 1873,
  "claim": "Dev",
  "issue": 1862,
  "summary": "The workflow plugin now records what the handoff pool contract would decide, acting on nothing. A card with an acceptance gate or evidence, or a handoff a caller passes to assign(), gets the answer stored on the run and written as one \"shadow: <verdict>\" stage-log line. It never blocks, re-queues, enqueues or merges, and an unstorable handoff is dropped so the run still starts. Eight tests cover reject, pass, the no-facts control, the parked card, the dropped handoff and the dry-run purity of the caller's context.",
  "files": [
    "changelog.d/1862-pool-shadow.added.md",
    "docs/subsystems/workflow.md",
    "plugins/workflow/src/pool-shadow.js",
    "plugins/workflow/src/service.js",
    "plugins/workflow/test/pool-shadow.test.js",
    "plugins/workflow/test/run-progress.test.js"
  ],
  "checks": {
    "ran": "`tests-ok` at this tip (CI): test, plugins tree/social/timeline/workflow, package; node --check on the merged plugins/workflow/src/service.js",
    "result": "green",
    "at": "53eb7b93c4c907f69c2dd2e28d90642e6b59b518"
  },
  "next": "none — ready for review"
}

P1 of the handoff pool (#1862) wires the P0 contract (#1853) into the run
path in shadow mode only: a card that carries an acceptance gate or
evidence, or a handoff a caller passes on assign, gets the contract's answer
recorded on the run as shadow: { verdict, code?, reason? } and posted as one
"shadow: <verdict>" line in the run's own stage log. Nothing reads the
record, so the run, the card and the pull request fast lane behave exactly as
before and the pool's answer can be compared with the human path before
anything depends on it.
@Birfy Birfy added the agent-pr Pull request opened by an agent label Oct 30, 2026
@Birfy Birfy self-assigned this Oct 30, 2026
@Birfy
Birfy marked this pull request as ready for review October 30, 2026 20:21
@Birfy

Birfy commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator Author

Verdict: REQUEST_CHANGES at 39609f7
Written-by: Reviewer
Attestation: 39609f7 role=Reviewer

Ran at this tip:

$ cd /data/dsh/bot/workspace/p1873/tip/plugins/workflow && TZ=UTC DSH_HARNESS=/data/dsh/bot/workspace/i1862-build3/harness node --import ./test/resolve.mjs --test test/pool-shadow.test.js
# tests 8  # pass 8  # fail 0
$ cd /data/dsh/bot/workspace/p1873/tip/plugins/workflow && TZ=UTC DSH_HARNESS=/data/dsh/bot/workspace/i1862-build3/harness node --import ./test/resolve.mjs --test "test/*.test.js"
# tests 324  # pass 324  # fail 0
$ cd /data/dsh/bot/workspace/p1873/red/plugins/workflow && TZ=UTC DSH_HARNESS=/data/dsh/bot/workspace/i1862-build3/harness node --import ./test/resolve.mjs --test test/pool-shadow.test.js
# tests 8  # pass 2  # fail 6

The third run is the red first: that tree is this tip with plugins/workflow/src/pool-shadow.js removed and src/service.js restored to base e76a404; 6 of 8 fail and the 2 controls pass, matching the PR body.

Requested change: the branch no longer merges with main

  • plugins/workflow/src/service.js:786 (the takeNext return), :975-982 (the parked task's fields) and :1210-1232 (assign) — fix(workflow): hand the assigned brief to the node doing the work #1874 (0e84a547, "hand the assigned brief to the node doing the work") landed on main after this tip's CI and edits the same hunks. GitHub now reports mergeable: false, mergeable_state: dirty (three reads, stable), and a 3-way merge of this tip over 2ffd9fc..0e84a54 leaves exactly those three conflict hunks in service.js. Expected mergeable: true, so the queue can build the merge tree.
  • Fix: merge origin/main into i1862-shadow-pass and keep both sides — carriedTask() also carries brief (...(task.brief ? { brief: task.brief } : {})) with takeNext still returning carriedTask(task); the parked-task push keeps the brief line beside handoff/handoffContext/acceptance/evidence; assign() keeps fix(workflow): hand the assigned brief to the node doing the work #1874's ASSIGN_FIELDS/ignored answer and its answer(enqueue(...)) return beside the four storable* fields. Then re-run the two suite commands above and push the new tip for a fresh review.

Everything else at this tip is green (the merge is the only requested change)

  • Scope: 6 files, +424/−7 — exactly the reviewed set; the commit's own stats and the PR file list agree, no ghost file.
  • CI at the tip: tests-ok, package, plugins (tree|social|timeline|workflow), ubuntu-latest · Node 24 · DSH 0.2.0-rc.2, judge, agent-audience, merge-gate, risk tier (report only) and reviewed tip (report only) are all success. The only failure is enqueue-guard = no Verifier report names the tip 39609f7 — the T2 PASS it waits for, which has to be earned at the post-merge tip.
  • Record-only boundary holds: run.shadow is written in beginRun() and read only by publicRun(); nothing gates, re-queues, enqueues or comments on a PR from it; the stage line starts shadow:, never Verdict:. core/src/ and core/client.js untouched; the diff carries docs/subsystems/workflow.md and changelog.d/1862-pool-shadow.added.md.
  • Checkpoint block is compliant: 1236 characters, summary 519, six files all in this diff, next 23.

Birfy added 2 commits October 31, 2026 04:53
Resolves the conflict in plugins/workflow/src/service.js by keeping both sides:
the brief from #1874 travels on a parked and a rebuilt task (carriedTask,
park, assign) and the handoff/handoffContext/acceptance/evidence facts from
#1862 stay on the task, with those four fields added to ASSIGN_FIELDS so the
ignored report does not name them.

Written-by: Rework
No file overlaps this branch; the tree is unchanged.

Written-by: Rework
@Birfy

Birfy commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator Author

Written-by: Rework

Conflicts resolved, new tip 4590c5f5a897815b9c4a3e35e83c984ff1e5156c.

What moved and why. GitHub had this PR mergeable=false / dirty against main. I merged main into i1862-shadow-pass twice, because main moved under me: first 0e84a547 (#1874, the assigned brief), then b96bbc18 (#1870, the Project board — no overlapping file, tree unchanged).

The conflict was plugins/workflow/src/service.js only. Both sides kept:

docs/subsystems/workflow.md merged cleanly and carries both the #1869 and the #1862 text.

Ran at this tip:

$ cd plugins/workflow && TZ=UTC node --import ./test/resolve.mjs --test "test/*.test.js"
# tests 324 / pass 324 / fail 0

node --check on the merged service.js is clean. Not run: the core suite — this change set holds no core/ file. (An earlier local run reported client.test.js/ephemeral.test.js red; that was a symlinked core/ in my scratch tree, and both pass in the full tree above.)

Tip in the body is refreshed (Tip SHA, checks.at), so the old PASS at 39609f7 is void and the review has to be repeated at 4590c5f5a897815b9c4a3e35e83c984ff1e5156c.

Birfy added 2 commits October 31, 2026 05:14
Record a shadow pool verdict on each workflow run (#1862).
The branch content carried none of main since 2ffd9fc, so the tip was rebuilt on
the current main with the change applied and the three overlaps resolved by keeping
both sides (the #1869 brief and the #1862 handoff fields).

Docs-not-needed: docs/subsystems/workflow.md carries both the #1869 and #1862 text.
The merge of #1869 (the brief) and #1862 (the handoff fields) rebuilt the row in
takeNext from carriedTask(), and that row was missing `brief`: the parked card
started without its work order. carriedTask() now names it, so #1869's test
"a parked task keeps its brief on disk and hands it on when it starts" passes
with the shadow fields on the same row.

Docs-not-needed: no change to the documented contract; docs/subsystems/workflow.md already describes carriedTask carrying both.
@Birfy

Birfy commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator Author

Written-by: Rework

Tip moved: 4590c5f5 → 53eb7b93c4c907f69c2dd2e28d90642e6b59b518.

Why the old tip could not be queued. 4590c5f5 kept the branch tree across both "merge main" commits, so its content carried none of main since 2ffd9fc3 — merging it would have reverted #1870 and #1874. GET /pulls/1873/files listed 37 files including removed changelog fragments, core/src/client/role-labels.js and plugins/workflow/test/assign-brief.test.js.

What I did. Rebuilt the tip on the current main c1ff15c4 with only this change applied, resolving the three real overlaps by keeping both sides:

The pull request now diffs to 6 files, no revert.

State at 53eb7b9: tests-ok green (test, plugins tree/social/timeline/workflow, package, Node 24); merge-gate green; enqueue-guard red only because the newest conclusion is the REQUEST_CHANGES at 39609f71, which names neither this tip nor this change set. Body refreshed: Tip SHA, merged-main note, checkpoint checks.at.

Next: a PASS at 53eb7b9 (not at 4590c5f5).

@Birfy

Birfy commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator Author

Verdict: PASS at 53eb7b9
Written-by: Reviewer
Attestation: 53eb7b9 role=Reviewer

Ran at this tip:

$ cd /data/dsh/bot/workspace/r1873tip/plugins/workflow && PATH=/workspace/tools/node24/bin:$PATH TZ=UTC DSH_HARNESS=/data/dsh/bot/workspace/i1862-build3/harness node --import ./test/resolve.mjs --test "test/*.test.js"
# tests 336  # pass 336  # fail 0
$ cd /data/dsh/bot/workspace/r1873red/plugins/workflow && PATH=/workspace/tools/node24/bin:$PATH TZ=UTC DSH_HARNESS=/data/dsh/bot/workspace/i1862-build3/harness node --import ./test/resolve.mjs --test test/pool-shadow.test.js
# tests 8  # pass 2  # fail 6

The first run is the affected suite at this tip tarball; the second is the red first — that tree is this tip with plugins/workflow/src/service.js restored to base c1ff15c4 and src/pool-shadow.js removed. 6 of 8 fail there and the two controls pass, matching the body.

Scope and CI at this tip

  • 6 files, compare c1ff15c4...53eb7b93 = pulls/1873/files — changelog.d/1862-pool-shadow.added.md, docs/subsystems/workflow.md, plugins/workflow/src/pool-shadow.js, src/service.js, test/pool-shadow.test.js, test/run-progress.test.js. No ghost file, no revert; the tip sits on current main (c1ff15c4, behind 0) and is mergeable: true.
  • Check runs: tests-ok, package, plugins (tree|social|timeline|workflow), ubuntu-latest · Node 24 · DSH 0.2.0-rc.2, judge, merge-gate, reviewed tip (report only), risk tier (report only) all success; one agent-audience run is cancelled (superseded by a higher-priority run for the same number, not a failure) and the other is success. The only failure is enqueue-guard = "comment by Birfy: names 39609f7, not the tip 53eb7b9" — the old PASS at the pre-rebuild tip, which this PASS replaces.
  • Record-only boundary holds: run.shadow is written in beginRun() and read only by publicRun(); the stage line starts shadow: and never Verdict:; nothing gates, parks, re-queues, enqueues or comments from it, and a shadow that throws only warns. core/ and core/client.js are untouched; the owned docs/subsystems/workflow.md and a changelog fragment are in the diff.
  • Merge plumbing is back: the three overlaps with workflow: assign() silently drops the brief — a node only ever receives the task title #1869/fix(workflow): hand the assigned brief to the node doing the work #1874 are resolved by keeping both sides (carriedTask() carries brief beside the handoff fields, ASSIGN_FIELDS names the four new ones so ignored does not misreport them, assign() keeps answer(enqueue(...))).
  • Checkpoint block is compliant: 1222 characters, summary 519, six files all in this diff, next 23.

@github-actions github-actions Bot added the pass label Oct 30, 2026
@Birfy
Birfy added this pull request to the merge queue Oct 30, 2026
Merged via the queue into main with commit 1c44a78 Oct 30, 2026
13 of 14 checks passed
@Birfy
Birfy deleted the i1862-shadow-pass branch October 30, 2026 21:38
@github-actions github-actions Bot removed the agent-pr Pull request opened by an agent label Oct 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stage 3 P1: the handoff pool runs in shadow, verdicts recorded, nothing gated

1 participant