opencode-swarm 7.156.0 → 7.157.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/dist/background/workspace-snapshot.d.ts +28 -0
  2. package/dist/cli/{coder-settlement-jm7024zm.js → coder-settlement-dz2x352d.js} +9 -9
  3. package/dist/cli/{config-doctor-q9v8yscr.js → config-doctor-4jxf9w9e.js} +3 -3
  4. package/dist/cli/{core-ev3bn503.js → core-xf2f087t.js} +2 -2
  5. package/dist/cli/{curation-policy-jabphe51.js → curation-policy-72qx868r.js} +4 -4
  6. package/dist/cli/{curator-llm-factory-cnatbky1.js → curator-llm-factory-7mfvey3x.js} +30 -30
  7. package/dist/cli/{curator-dnjf9ser.js → curator-pjjw3ja4.js} +30 -30
  8. package/dist/cli/{evidence-summary-service-5drv65qh.js → evidence-summary-service-5ffkbs50.js} +11 -11
  9. package/dist/cli/{gate-evidence-dcyvst7g.js → gate-evidence-ne9rbdtb.js} +5 -5
  10. package/dist/cli/{guardrail-explain-z8f6qhz2.js → guardrail-explain-b9vr4ta3.js} +31 -31
  11. package/dist/cli/{guardrail-log-zwec6ann.js → guardrail-log-hrt36jz5.js} +5 -5
  12. package/dist/cli/{guardrail-reset-ga6e11r9.js → guardrail-reset-pggm9hx4.js} +30 -30
  13. package/dist/cli/{hive-promoter-mpez5tqh.js → hive-promoter-7vxm11sm.js} +30 -30
  14. package/dist/cli/{index-fpg4tzf7.js → index-12e2hztp.js} +1 -1
  15. package/dist/cli/{index-sm2t1awr.js → index-1dzy1j4v.js} +2 -2
  16. package/dist/cli/{index-b91qwpms.js → index-2e60kmzg.js} +1 -1
  17. package/dist/cli/{index-vnn7qq8c.js → index-3f7hqtgg.js} +62 -1
  18. package/dist/cli/{index-17h6ewqp.js → index-3qpr16k2.js} +32 -32
  19. package/dist/cli/{index-98j6z038.js → index-3vqdt1sx.js} +5 -5
  20. package/dist/cli/{index-wn0xm2e8.js → index-4kd1nqd2.js} +8 -3
  21. package/dist/cli/{index-5w87j6j4.js → index-4w20thrc.js} +2 -2
  22. package/dist/cli/{index-5r3zrw81.js → index-61nkp124.js} +2 -2
  23. package/dist/cli/{index-6bqqzfbe.js → index-6sbx96v6.js} +2 -2
  24. package/dist/cli/{index-mdypz60w.js → index-79k7p589.js} +1 -1
  25. package/dist/cli/{index-00hyhg47.js → index-8n602qc2.js} +4 -4
  26. package/dist/cli/{index-fjcm6wwf.js → index-91ybfvy2.js} +1 -1
  27. package/dist/cli/{index-q2khkey7.js → index-93ymj3j5.js} +5 -5
  28. package/dist/cli/{index-myt57pht.js → index-9r7gp6cp.js} +5 -1
  29. package/dist/cli/{index-85p1850w.js → index-b5xm177r.js} +1 -1
  30. package/dist/cli/{index-0q8kywcf.js → index-dwkrdpz2.js} +1 -1
  31. package/dist/cli/{index-g37454vj.js → index-ebratyzr.js} +1 -1
  32. package/dist/cli/{index-6g6qwr8z.js → index-g0j2hnse.js} +5 -5
  33. package/dist/cli/{index-ppx8bnzd.js → index-gk6wpq41.js} +1463 -402
  34. package/dist/cli/{index-aqg7c1z9.js → index-gpf3cjre.js} +1 -1
  35. package/dist/cli/{index-dfmr6pj5.js → index-j3egsxa1.js} +6 -6
  36. package/dist/cli/{index-sfdg1xg5.js → index-n6ayyadp.js} +4 -4
  37. package/dist/cli/{index-fd7wj6fy.js → index-n7gv8m7v.js} +4 -4
  38. package/dist/cli/{index-68098cfj.js → index-nd22bsnt.js} +2 -2
  39. package/dist/cli/{index-gthnsbzf.js → index-ngn6jmad.js} +1 -1
  40. package/dist/cli/{index-xdy28ngt.js → index-nwkr6tvv.js} +17 -1
  41. package/dist/cli/{index-za6bb2fd.js → index-p0by16z8.js} +2 -2
  42. package/dist/cli/{index-164c64z8.js → index-q94gt4n9.js} +3 -3
  43. package/dist/cli/{index-4m3j9q9z.js → index-t0kxka8n.js} +1 -1
  44. package/dist/cli/{index-9n555qz4.js → index-tvtvhjh0.js} +4 -4
  45. package/dist/cli/{index-zdgdf0e9.js → index-vbqssmbs.js} +6 -6
  46. package/dist/cli/{index-ew6fykvv.js → index-xe6zbfps.js} +1 -1
  47. package/dist/cli/{index-kxk8cnx7.js → index-zq7pw6qg.js} +2 -2
  48. package/dist/cli/index.js +30 -30
  49. package/dist/cli/{knowledge-escalator-cq4e6v2j.js → knowledge-escalator-d65mctqy.js} +10 -10
  50. package/dist/cli/{knowledge-events-sr5fqqaq.js → knowledge-events-6aet71sp.js} +8 -8
  51. package/dist/cli/{knowledge-link-4frk38w8.js → knowledge-link-z9cchqdj.js} +3 -3
  52. package/dist/cli/{knowledge-store-2dww3dqz.js → knowledge-store-vvgxbakx.js} +4 -4
  53. package/dist/cli/{knowledge-validator-yprsj4ye.js → knowledge-validator-4fb6pbpn.js} +6 -6
  54. package/dist/cli/{model-preflight-b95w8wxy.js → model-preflight-cv9kvw8h.js} +1 -1
  55. package/dist/cli/{pending-delegations-7qvag076.js → pending-delegations-f52jtanf.js} +1 -1
  56. package/dist/cli/{pr-subscriptions-00evnffe.js → pr-subscriptions-76vg2xya.js} +2 -2
  57. package/dist/cli/{runner-gheaxd5r.js → runner-eagt6gf8.js} +4 -4
  58. package/dist/cli/{scan-cursor-6awybk8b.js → scan-cursor-q3530gc8.js} +5 -5
  59. package/dist/cli/{schema-bf3smw7k.js → schema-5zc62306.js} +2 -2
  60. package/dist/cli/{scope-persistence-kc42c6ph.js → scope-persistence-fzqf115q.js} +7 -7
  61. package/dist/cli/{skill-generator-9k1ztt7c.js → skill-generator-kh1z90tm.js} +12 -12
  62. package/dist/cli/{workspace-snapshot-8269e1p9.js → workspace-snapshot-yq0tc49d.js} +9 -1
  63. package/dist/cli/{worktree-collision-ownership-ej10dhwe.js → worktree-collision-ownership-2qxjtxt6.js} +3 -3
  64. package/dist/cli/{worktree-isolation-r7qqy6ca.js → worktree-isolation-40v34p0s.js} +30 -30
  65. package/dist/commands/registry.d.ts +1 -1
  66. package/dist/hooks/pr-workflow-gate.d.ts +291 -3
  67. package/dist/index.js +72 -70
  68. package/dist/tools/index.d.ts +1 -0
  69. package/dist/tools/invalidate-pr-feedback-publication.d.ts +20 -0
  70. package/dist/tools/manifest.d.ts +1 -0
  71. package/dist/tools/tool-metadata.d.ts +4 -0
  72. package/package.json +1 -1
@@ -33,30 +33,30 @@ import {
33
33
  sanitizeSlug,
34
34
  selectCandidateEntries,
35
35
  writeEvalStub
36
- } from "./index-sfdg1xg5.js";
37
- import"./index-9n555qz4.js";
38
- import"./index-aqg7c1z9.js";
36
+ } from "./index-n6ayyadp.js";
37
+ import"./index-tvtvhjh0.js";
38
+ import"./index-gpf3cjre.js";
39
39
  import"./index-rtry5xyf.js";
40
40
  import"./index-q7sjgr1y.js";
41
- import"./index-dfmr6pj5.js";
42
- import"./index-98j6z038.js";
43
- import"./index-164c64z8.js";
41
+ import"./index-j3egsxa1.js";
42
+ import"./index-3vqdt1sx.js";
43
+ import"./index-q94gt4n9.js";
44
44
  import"./index-gprxjmm7.js";
45
45
  import"./index-n832052r.js";
46
46
  import"./index-dtn0pne5.js";
47
47
  import"./index-z6xqpmqg.js";
48
48
  import"./index-r3mvsbtq.js";
49
- import"./index-b91qwpms.js";
50
- import"./index-5w87j6j4.js";
51
- import"./index-myt57pht.js";
49
+ import"./index-2e60kmzg.js";
50
+ import"./index-4w20thrc.js";
51
+ import"./index-9r7gp6cp.js";
52
52
  import"./index-zjygnfay.js";
53
53
  import"./index-9e6fdz2h.js";
54
54
  import"./index-4rhhvd1a.js";
55
55
  import"./index-ae75rja9.js";
56
- import"./index-85p1850w.js";
57
- import"./index-ew6fykvv.js";
56
+ import"./index-b5xm177r.js";
57
+ import"./index-xe6zbfps.js";
58
58
  import"./index-bk5tah7q.js";
59
- import"./index-6bqqzfbe.js";
59
+ import"./index-6sbx96v6.js";
60
60
  import"./index-xagq35tf.js";
61
61
  import"./index-ed5ykebp.js";
62
62
  import"./index-h1g8w4v0.js";
@@ -10,10 +10,12 @@ import {
10
10
  parsePorcelainPaths,
11
11
  parsePorcelainV2Snapshot,
12
12
  readGitTextAtRevision,
13
+ redactRemoteUrlIdentity,
13
14
  resolveCommitCountSince,
14
15
  resolveCommitCountSinceAsync,
15
16
  resolveCurrentGitHead,
16
17
  resolveCurrentGitHeadAsync,
18
+ resolveCurrentLocalHeadRefAsync,
17
19
  resolveCurrentUpstreamPushTarget,
18
20
  resolveCurrentUpstreamPushTargetAsync,
19
21
  resolveCurrentUpstreamRemoteRef,
@@ -36,9 +38,11 @@ import {
36
38
  resolvePrWorkflowRevisionDigestDetailedAsync,
37
39
  resolveRemoteRefsContainingHead,
38
40
  resolveRemoteRefsContainingHeadAsync,
41
+ resolveRemoteUrlIdentity,
42
+ resolveRemoteUrlIdentityAsync,
39
43
  switchPrFeedbackTrackingCandidateAsync,
40
44
  workspaceSnapshotMatches
41
- } from "./index-vnn7qq8c.js";
45
+ } from "./index-3f7hqtgg.js";
42
46
  import"./index-r3mvsbtq.js";
43
47
  import"./index-9e6fdz2h.js";
44
48
  import"./index-4rhhvd1a.js";
@@ -47,6 +51,8 @@ import"./index-a76rekgs.js";
47
51
  export {
48
52
  workspaceSnapshotMatches,
49
53
  switchPrFeedbackTrackingCandidateAsync,
54
+ resolveRemoteUrlIdentityAsync,
55
+ resolveRemoteUrlIdentity,
50
56
  resolveRemoteRefsContainingHeadAsync,
51
57
  resolveRemoteRefsContainingHead,
52
58
  resolvePrWorkflowRevisionDigestDetailedAsync,
@@ -69,10 +75,12 @@ export {
69
75
  resolveCurrentUpstreamRemoteRef,
70
76
  resolveCurrentUpstreamPushTargetAsync,
71
77
  resolveCurrentUpstreamPushTarget,
78
+ resolveCurrentLocalHeadRefAsync,
72
79
  resolveCurrentGitHeadAsync,
73
80
  resolveCurrentGitHead,
74
81
  resolveCommitCountSinceAsync,
75
82
  resolveCommitCountSince,
83
+ redactRemoteUrlIdentity,
76
84
  readGitTextAtRevision,
77
85
  parsePorcelainV2Snapshot,
78
86
  parsePorcelainPaths,
@@ -6,11 +6,11 @@ import {
6
6
  WORKTREE_PROVISIONING_OWNER_LEASE_MS,
7
7
  removeWorktreeProvisioningOwner,
8
8
  scanWorktreeProvisioningOwnersForRecovery
9
- } from "./index-0q8kywcf.js";
9
+ } from "./index-dwkrdpz2.js";
10
10
  import {
11
11
  scanDelegationFallbacksForRecovery,
12
12
  scanDelegationsForRecovery
13
- } from "./index-fpg4tzf7.js";
13
+ } from "./index-12e2hztp.js";
14
14
  import"./index-ddszzne4.js";
15
15
  import"./index-dtn0pne5.js";
16
16
  import"./index-z6xqpmqg.js";
@@ -23,7 +23,7 @@ import {
23
23
  resolveGitExecutable
24
24
  } from "./index-9e6fdz2h.js";
25
25
  import"./index-4rhhvd1a.js";
26
- import"./index-6bqqzfbe.js";
26
+ import"./index-6sbx96v6.js";
27
27
  import"./index-xagq35tf.js";
28
28
  import"./index-ed5ykebp.js";
29
29
  import"./index-h1g8w4v0.js";
@@ -21,61 +21,61 @@ import {
21
21
  sanitizeWorktreeTaskId,
22
22
  standardWorktreeByCallID,
23
23
  standardWorktreeSerializationSessions
24
- } from "./index-ppx8bnzd.js";
25
- import"./index-4m3j9q9z.js";
26
- import"./index-wn0xm2e8.js";
27
- import"./index-68098cfj.js";
28
- import"./index-q2khkey7.js";
29
- import"./index-gthnsbzf.js";
24
+ } from "./index-gk6wpq41.js";
25
+ import"./index-t0kxka8n.js";
26
+ import"./index-4kd1nqd2.js";
27
+ import"./index-nd22bsnt.js";
28
+ import"./index-93ymj3j5.js";
29
+ import"./index-ngn6jmad.js";
30
30
  import"./index-134d35c1.js";
31
31
  import"./index-nj6rmyeh.js";
32
32
  import"./index-txdagbh7.js";
33
- import"./index-6g6qwr8z.js";
34
- import"./index-sm2t1awr.js";
33
+ import"./index-g0j2hnse.js";
34
+ import"./index-1dzy1j4v.js";
35
35
  import"./index-70ha9e09.js";
36
36
  import"./index-c8s9a3zh.js";
37
37
  import"./index-9ss2m4rs.js";
38
- import"./index-fjcm6wwf.js";
38
+ import"./index-91ybfvy2.js";
39
39
  import"./index-zsrtt42s.js";
40
- import"./index-zdgdf0e9.js";
41
- import"./index-0q8kywcf.js";
42
- import"./index-sfdg1xg5.js";
43
- import"./index-9n555qz4.js";
44
- import"./index-aqg7c1z9.js";
40
+ import"./index-vbqssmbs.js";
41
+ import"./index-dwkrdpz2.js";
42
+ import"./index-n6ayyadp.js";
43
+ import"./index-tvtvhjh0.js";
44
+ import"./index-gpf3cjre.js";
45
45
  import"./index-rtry5xyf.js";
46
- import"./index-5r3zrw81.js";
47
- import"./index-za6bb2fd.js";
48
- import"./index-fpg4tzf7.js";
46
+ import"./index-61nkp124.js";
47
+ import"./index-p0by16z8.js";
48
+ import"./index-12e2hztp.js";
49
49
  import"./index-ddszzne4.js";
50
- import"./index-vnn7qq8c.js";
51
- import"./index-fd7wj6fy.js";
52
- import"./index-mdypz60w.js";
53
- import"./index-xdy28ngt.js";
50
+ import"./index-3f7hqtgg.js";
51
+ import"./index-n7gv8m7v.js";
52
+ import"./index-79k7p589.js";
53
+ import"./index-nwkr6tvv.js";
54
54
  import"./index-556ja8an.js";
55
55
  import"./index-4fwbbad3.js";
56
56
  import"./index-b43rt5ph.js";
57
57
  import"./index-q7sjgr1y.js";
58
- import"./index-dfmr6pj5.js";
59
- import"./index-98j6z038.js";
58
+ import"./index-j3egsxa1.js";
59
+ import"./index-3vqdt1sx.js";
60
60
  import {
61
61
  resolveWorktreeIsolationConfig
62
- } from "./index-164c64z8.js";
62
+ } from "./index-q94gt4n9.js";
63
63
  import"./index-gprxjmm7.js";
64
64
  import"./index-n832052r.js";
65
65
  import"./index-dtn0pne5.js";
66
66
  import"./index-z6xqpmqg.js";
67
67
  import"./index-r3mvsbtq.js";
68
- import"./index-b91qwpms.js";
69
- import"./index-5w87j6j4.js";
70
- import"./index-myt57pht.js";
68
+ import"./index-2e60kmzg.js";
69
+ import"./index-4w20thrc.js";
70
+ import"./index-9r7gp6cp.js";
71
71
  import"./index-zjygnfay.js";
72
72
  import"./index-9e6fdz2h.js";
73
73
  import"./index-4rhhvd1a.js";
74
74
  import"./index-ae75rja9.js";
75
- import"./index-85p1850w.js";
76
- import"./index-ew6fykvv.js";
75
+ import"./index-b5xm177r.js";
76
+ import"./index-xe6zbfps.js";
77
77
  import"./index-bk5tah7q.js";
78
- import"./index-6bqqzfbe.js";
78
+ import"./index-6sbx96v6.js";
79
79
  import"./index-xagq35tf.js";
80
80
  import"./index-ed5ykebp.js";
81
81
  import"./index-h1g8w4v0.js";
@@ -752,7 +752,7 @@ export declare const COMMAND_REGISTRY: {
752
752
  readonly handler: (ctx: CommandContext) => Promise<string>;
753
753
  readonly description: "Clear a stuck PR_REVIEW/PR_FEEDBACK mechanical gate and stop the auto-resume loop [mode] [reason]";
754
754
  readonly args: "[PR_REVIEW|PR_FEEDBACK] [reason...]";
755
- readonly details: "Human-only escape hatch for an unrecoverable PR_REVIEW or PR_FEEDBACK mechanical gate. When the architect cannot reach complete_pr_workflow — for example a compound `git fetch && git checkout` was rejected as read-only shell syntax, the PR head cannot be fetched, or the working tree is on the wrong branch — running this clears the durable gate state for the current session and stops the auto-resume loop without depending on the trapped model. The agent itself cannot run this command; it must call the abort_pr_workflow tool (or ask you to run this command). Both paths funnel into the same fail-closed abortPrWorkflow hook, which refuses while the workflow is armed for publication or while PR workflow lanes are still in flight. This human-only force path has exactly one exception to that second refusal (issue #2251): when the ONLY lanes still blocking are ones past the 30-minute staleness horizon that the liveness probe reports as still running — a lane nothing will ever settle on a schedule — it clears the gate anyway, names exactly which lanes it overrode, and finalizes their delegation records so the session can start a new PR workflow. Those sessions are NOT stopped and their output is NOT collected. A lane with a fresh updatedAt still blocks even under force, and any delegation record that still keeps the session blocked is named in the warning. When checkout preparation preserved a stash, the result instructs the caller to run prepare_pr_workflow_checkout operation=restore after the clear. An audit event is appended to .swarm/events.jsonl.";
755
+ readonly details: "Human-only escape hatch for an unrecoverable PR_REVIEW or PR_FEEDBACK mechanical gate. When the architect cannot reach complete_pr_workflow — for example a compound `git fetch && git checkout` was rejected as read-only shell syntax, the PR head cannot be fetched, or the working tree is on the wrong branch — running this clears the durable gate state for the current session and stops the auto-resume loop without depending on the trapped model. The agent itself cannot run this command; it must call the abort_pr_workflow tool (or ask you to run this command). Both paths funnel into the same fail-closed abortPrWorkflow hook, which refuses while the workflow is armed for publication or while PR workflow lanes are still in flight. Issue #2108 adds the two audited exits from an armed publication window: the invalidate_pr_feedback_publication tool (change approved content — every approval of the generation is superseded and the full ladder re-runs) and the abort_pr_workflow tool kind \"cancel-publication\" with cancel_publication: true and a reason (terminal no-publish cancellation; never grants push authority). A plain recovery or force abort never clears an armed window. This human-only force path has exactly one exception to the lane refusal (issue #2251): when the ONLY lanes still blocking are ones past the 30-minute staleness horizon that the liveness probe reports as still running — a lane nothing will ever settle on a schedule — it clears the gate anyway, names exactly which lanes it overrode, and finalizes their delegation records so the session can start a new PR workflow. Those sessions are NOT stopped and their output is NOT collected. A lane with a fresh updatedAt still blocks even under force, and any delegation record that still keeps the session blocked is named in the warning. When checkout preparation preserved a stash, the result instructs the caller to run prepare_pr_workflow_checkout operation=restore after the clear. An audit event is appended to .swarm/events.jsonl.";
756
756
  readonly category: "utility";
757
757
  readonly toolPolicy: "restricted";
758
758
  };
@@ -4,7 +4,7 @@ import { type CandidateSeverity, type FindingsSeverity, type RowFormatFamily } f
4
4
  import { type LaneOutputArtifact } from '../background/lane-output-store.js';
5
5
  import { type BackgroundDelegationRecord, type BackgroundDelegationResult, type BackgroundDelegationWorkflowLaneFailureClass, type BackgroundDelegationWorkflowLaneRecovery, findByBatchId, sweepStaleDelegations } from '../background/pending-delegations.js';
6
6
  import { type PrReviewInlineTriggerRow } from '../background/pr-review-trigger-contract.js';
7
- import { type RevisionDigestResult, resolveCommitCountSince, resolveCommitCountSinceAsync, resolveCurrentGitHead, resolveCurrentGitHeadAsync, resolveCurrentUpstreamPushTarget, resolveCurrentUpstreamPushTargetAsync, resolveCurrentUpstreamRemoteRef, resolveExactRemoteBranchHead, resolveExactRemoteBranchHeadAsync, resolveIsExactSingleChildCommit, resolveIsExactSingleChildCommitAsync, resolveIsWorkingTreeClean, resolveIsWorkingTreeCleanAsync, resolvePrReviewDiffStats, resolvePrReviewDiffStatsAsync, resolvePrWorkflowRevisionDigest, resolvePrWorkflowRevisionDigestDetailed, resolveRemoteRefsContainingHead, resolveRemoteRefsContainingHeadAsync } from '../background/workspace-snapshot.js';
7
+ import { type RevisionDigestResult, resolveCommitCountSince, resolveCommitCountSinceAsync, resolveCurrentGitHead, resolveCurrentGitHeadAsync, resolveCurrentLocalHeadRefAsync, resolveCurrentUpstreamPushTarget, resolveCurrentUpstreamPushTargetAsync, resolveCurrentUpstreamRemoteRef, resolveExactRemoteBranchHead, resolveExactRemoteBranchHeadAsync, resolveIsExactSingleChildCommit, resolveIsExactSingleChildCommitAsync, resolveIsWorkingTreeClean, resolveIsWorkingTreeCleanAsync, resolvePrReviewDiffStats, resolvePrReviewDiffStatsAsync, resolvePrWorkflowRevisionDigest, resolvePrWorkflowRevisionDigestDetailed, resolveRemoteRefsContainingHead, resolveRemoteRefsContainingHeadAsync, resolveRemoteUrlIdentity, resolveRemoteUrlIdentityAsync } from '../background/workspace-snapshot.js';
8
8
  import { type PrReviewResilienceConfig } from '../config/schema.js';
9
9
  import { classifyPrWorkflowGitState, type PrWorkflowGitState } from '../git/pr-workflow-state.js';
10
10
  import { classifyPrReviewCircuitSignal, type PrReviewCircuitLegacyRecord, type PrReviewCircuitRecordV2 } from './pr-review-resilience-circuit.js';
@@ -259,6 +259,94 @@ interface PrFeedbackReadyToPublishRecord {
259
259
  remoteRef: string;
260
260
  validatedAt: string;
261
261
  }
262
+ /**
263
+ * Issue #2108: durable publication-generation state machine. The legacy
264
+ * {@link PrFeedbackReadyToPublishRecord} above becomes a derived mirror that
265
+ * is present exactly while the active generation is `{armed, push_in_flight}`
266
+ * (or a legacy record awaits migration), so a rolled-back binary keeps
267
+ * enforcing the armed window instead of turning permissive.
268
+ */
269
+ export type PrFeedbackPublicationGenerationState = 'reviewing' | 'armed' | 'invalidated' | 'push_in_flight' | 'published' | 'cancelled_without_publication';
270
+ export interface PrFeedbackPublicationEvidenceJoin {
271
+ stageAValidatedAt: string;
272
+ batches: Array<{
273
+ phase: PrFeedbackGatePhase;
274
+ batchId: string;
275
+ laneId: string;
276
+ }>;
277
+ }
278
+ export interface PrFeedbackPublicationGeneration {
279
+ schemaVersion: 1;
280
+ generation: number;
281
+ state: PrFeedbackPublicationGenerationState;
282
+ /** Canonical workspace identity at arming (`canonicalWorkspaceIdentity`). */
283
+ workspaceIdentity: string;
284
+ sessionID: string;
285
+ /** HTTPS PR URL bound at arming (PR identity disclosure), when present. */
286
+ prTargetUrl?: string;
287
+ /** Immutable intake head the approved commit descends from. */
288
+ intakeHeadSha: string;
289
+ /** Local branch ref resolved at arming. */
290
+ localHeadRef: string;
291
+ /** Exact approved local head commit. */
292
+ localHead: string;
293
+ remoteName: string;
294
+ /** Credential-redacted remote URL identity (`git remote get-url`). */
295
+ remoteUrlIdentity?: string;
296
+ remoteBranchRef: string;
297
+ remoteRef: string;
298
+ revisionDigest: string;
299
+ /** The exact receipt set that authorized this generation. */
300
+ evidence: PrFeedbackPublicationEvidenceJoin;
301
+ invalidationReason?: string;
302
+ supersededByGeneration?: number;
303
+ createdAt: string;
304
+ armedAt?: string;
305
+ invalidatedAt?: string;
306
+ publishedAt?: string;
307
+ cancelledAt?: string;
308
+ }
309
+ export type PrFeedbackPushAttemptOutcome = 'completed' | 'rejected' | 'uncertain' | 'cancelled';
310
+ export interface PrFeedbackPushAttempt {
311
+ attemptId: string;
312
+ generation: number;
313
+ sessionID: string;
314
+ callID?: string;
315
+ /** SHA-256 over the canonical intent JSON. */
316
+ intentDigest: string;
317
+ intent: {
318
+ remote: string;
319
+ sourceSha: string;
320
+ destRef: string;
321
+ };
322
+ prePush: {
323
+ localHead: string;
324
+ worktreeClean: boolean;
325
+ remoteName: string;
326
+ remoteBranchRef: string;
327
+ observedRemoteHead: string | null;
328
+ };
329
+ startedAt: string;
330
+ result?: {
331
+ outcome: PrFeedbackPushAttemptOutcome;
332
+ exitStatus: number | 'not-observed';
333
+ /** Bounded (<=500 chars) and secret-redacted. */
334
+ diagnostic: string;
335
+ postPush: {
336
+ localHead: string | null;
337
+ observedRemoteHead: string | null;
338
+ };
339
+ completedAt: string;
340
+ };
341
+ }
342
+ export interface PrFeedbackPublicationState {
343
+ schemaVersion: 1;
344
+ active?: PrFeedbackPublicationGeneration;
345
+ /** Bounded superseded-generation summaries (last 4). */
346
+ history: PrFeedbackPublicationGeneration[];
347
+ /** Bounded attempt records for the active generation (last 8). */
348
+ attempts: PrFeedbackPushAttempt[];
349
+ }
262
350
  export type PrWorkflowCompletionStatus = 'completed' | 'ready-to-publish' | 'verified-no-change';
263
351
  export type PrReviewValidationPhase = 'council' | 'reviewer' | 'critic';
264
352
  export type PrReviewArtifactBoundary = 'post_explorer' | 'post_reviewer' | 'post_critic';
@@ -427,6 +515,13 @@ export interface PrWorkflowGateState {
427
515
  prFeedbackStageA?: PrFeedbackStageARecord;
428
516
  prFeedbackGateBatches?: PrFeedbackGateBatchRecord[];
429
517
  prFeedbackReadyToPublish?: PrFeedbackReadyToPublishRecord;
518
+ /**
519
+ * Issue #2108: audited publication generations + push attempts. The
520
+ * authoritative publication state machine; `prFeedbackReadyToPublish`
521
+ * above is its derived rollback mirror. Optional so pre-#2108 state (and
522
+ * older binaries, via the root `.passthrough()`) loads unchanged.
523
+ */
524
+ prFeedbackPublication?: PrFeedbackPublicationState;
430
525
  /**
431
526
  * Issue #2131 criterion C2: count of controlled base-sync/rebind transitions.
432
527
  * Each rebind moves the immutable intake head to a new verified remote PR
@@ -707,8 +802,18 @@ export declare function settlePresumedStalePrWorkflowLanes(directory: string, se
707
802
  */
708
803
  export declare function abortPrWorkflow(directory: string, sessionID: string, options?: {
709
804
  expectedMode?: PrWorkflowMode;
710
- kind: 'recovery' | 'force';
805
+ kind: 'recovery' | 'force' | 'cancel-publication';
711
806
  reason: string;
807
+ /**
808
+ * Issue #2108: the explicit cancellation-without-publication arm. While
809
+ * an armed/push_in_flight/invalidated publication generation exists,
810
+ * this arm (and ONLY this arm — mutually exclusive with `force`) may
811
+ * clear the workflow: it records the generation as
812
+ * `cancelled_without_publication` with the observed remote head and a
813
+ * REQUIRED reason, and never manufactures push authority. Plain
814
+ * `recovery`/`force` aborts remain refused while armed.
815
+ */
816
+ cancelPublication?: boolean;
712
817
  }): Promise<{
713
818
  mode: PrWorkflowMode;
714
819
  prHeadSha?: string;
@@ -860,6 +965,174 @@ export declare function recordPrFeedbackGateBatch(directory: string, sessionID:
860
965
  export declare function assertPrFeedbackGatePhaseSettled(directory: string, sessionID: string, phase: PrFeedbackGatePhase): Promise<PrWorkflowGateState>;
861
966
  /** Require every ordered feedback gate on one unchanged revision. */
862
967
  export declare function assertPrFeedbackReadyToPublish(directory: string, sessionID: string): Promise<PrWorkflowGateState>;
968
+ /** Build the evidence join for a freshly armed generation. */
969
+ declare function buildPublicationEvidenceJoin(state: PrWorkflowGateState, currentDigest: string): PrFeedbackPublicationEvidenceJoin | null;
970
+ /**
971
+ * Snapshot of the publication container with bounded history trimming.
972
+ * History keeps the last {@link MAX_PUBLICATION_HISTORY_GENERATIONS}
973
+ * superseded generations; attempts belong to the active generation only.
974
+ */
975
+ declare function nextPublicationContainer(previous: PrFeedbackPublicationState | undefined, active: PrFeedbackPublicationGeneration | undefined, historyAppends?: PrFeedbackPublicationGeneration[], attempts?: PrFeedbackPushAttempt[]): PrFeedbackPublicationState;
976
+ /**
977
+ * The audited invalidation transition (issue #2108 §4/§5). Supersedes every
978
+ * content-dependent approval of the active generation — Stage A result,
979
+ * verification batches, ordered-gate batches, scope declarations — by
980
+ * removing them from ACTIVE state (the underlying lane artifacts remain in
981
+ * their own stores; the superseded join is pinned in the generation record),
982
+ * marks the generation `invalidated`, clears the rollback mirror, and appends
983
+ * the audit event. Never deletes the generation itself or its history.
984
+ *
985
+ * `driftReverification` (auto-detected drift) re-proves the drifted component
986
+ * under the session lock before writing, so a TOCTOU between the unlocked
987
+ * snapshot and this write cannot invalidate on stale evidence.
988
+ */
989
+ declare function invalidatePublicationGeneration(directory: string, sessionID: string, reason: string, options?: {
990
+ drift?: {
991
+ component: string;
992
+ detail: string;
993
+ };
994
+ driftReverification?: boolean;
995
+ finalizeInFlightAs?: PrFeedbackPushAttemptOutcome;
996
+ }): Promise<PrWorkflowPublicationTransitionResult>;
997
+ interface PrWorkflowPublicationTransitionResult {
998
+ generation: PrFeedbackPublicationGeneration;
999
+ state: PrWorkflowGateState;
1000
+ }
1001
+ /**
1002
+ * Migrate a legacy armed record (pre-#2108 state) into the generation state
1003
+ * machine, conservatively: every identity component must recompute and match
1004
+ * under the session lock, and the active receipts must be present and bound
1005
+ * to the mirror's digest. Any mismatch or failure persists generation 1 as
1006
+ * `invalidated` with a `legacy-migration-*` reason — never silently armed.
1007
+ * No-op when no legacy record exists (returns the current state unchanged).
1008
+ */
1009
+ declare function ensurePublicationGenerationCurrent(directory: string, sessionID: string): Promise<PrWorkflowGateState | null>;
1010
+ /**
1011
+ * The reaper (issue #2108 §3): finalize any result-less push attempt before
1012
+ * another armed-window interaction proceeds. Recovers restarts and missed
1013
+ * `tool.execute.after` observations as `uncertain` and re-observes the remote
1014
+ * head, so `push_in_flight` can never wedge a generation.
1015
+ */
1016
+ declare function reconcileForeignInFlightAttempt(directory: string, sessionID: string, currentCallId?: string): Promise<PrWorkflowGateState | null>;
1017
+ /**
1018
+ * Controller-facing invalidation/rework transition (issue #2108 §4): the
1019
+ * explicit declaration that approved content must change, which opens the
1020
+ * mutation path by superseding every content-dependent approval of the
1021
+ * current armed generation. Requires a non-empty reason. Refuses when no
1022
+ * live window exists and reports already-invalidated as an informative
1023
+ * diagnostic (idempotent no-op is NOT silently accepted — the caller should
1024
+ * see the current state).
1025
+ */
1026
+ export declare function invalidatePrFeedbackPublication(directory: string, sessionID: string, reason: string): Promise<PrFeedbackPublicationGeneration>;
1027
+ /**
1028
+ * Operator-facing publication summary for `pr_workflow_status` (issue #2108):
1029
+ * generation, state, target, attempts, invalidation reason, and the
1030
+ * state-appropriate recovery instruction. Returns null when the workflow has
1031
+ * no publication state to describe.
1032
+ */
1033
+ export declare function describePrWorkflowPublicationSection(state: PrWorkflowGateState): string | null;
1034
+ /**
1035
+ * Issue #2108 safety boundary — "fail closed on corrupt, MISSING, ambiguous,
1036
+ * copied, cross-workspace, or conflicting generation state" and "a manual
1037
+ * state-file edit … cannot clear the authorization requirement": when the
1038
+ * gate state file for a session is absent (e.g. deleted by hand while a
1039
+ * generation was live) but the retained events window shows a LIVE
1040
+ * publication generation for that session — an `armed` or
1041
+ * `push_attempt_started` event with no later terminal (`published`,
1042
+ * `cancelled`, `invalidated`) — publication-capable commands fail closed
1043
+ * until an audited terminal lands. The events store is the append-only audit
1044
+ * authority the state-file deletion cannot touch; when the trail is empty or
1045
+ * compacted past the event the guard is silent (it never invents a dangling
1046
+ * generation from absent evidence).
1047
+ */
1048
+ export declare function findDanglingLivePublicationGeneration(directory: string, sessionID: string): {
1049
+ generation: number;
1050
+ } | null;
1051
+ /** Typed rejection taxonomy for a standalone `git push` command. */
1052
+ export type ExactPushIntentRejection = 'shell-syntax' | 'token-shape' | 'flag-or-option' | 'credential-bearing-remote' | 'invalid-source-sha' | 'invalid-dest-ref' | 'delete-refspec' | 'wildcard-refspec' | 'remote-mismatch' | 'branch-mismatch' | 'source-mismatch' | 'unbound-target';
1053
+ export interface ExactPushIntent {
1054
+ remote: string;
1055
+ sourceSha: string;
1056
+ destRef: string;
1057
+ }
1058
+ export interface ExactPushIntentParseResult {
1059
+ ok: boolean;
1060
+ intent?: ExactPushIntent;
1061
+ /** SHA-256 over the canonical intent JSON (persisted in attempt records). */
1062
+ digest?: string;
1063
+ reason?: ExactPushIntentRejection;
1064
+ }
1065
+ /**
1066
+ * Fold an audited invalidation into a PENDING single-write state transition
1067
+ * (the Stage A re-record and inventory-amendment disarm sites, issue #2108
1068
+ * R3.3): when the pending state still carries a live publication window, the
1069
+ * generation is marked `invalidated` with the given reason, the rollback
1070
+ * mirror and the remaining ancestry-bound receipts (verifications, gate
1071
+ * batches, scope declarations) are superseded in the SAME atomic write, and
1072
+ * any result-less attempt is finalized `uncertain`. A fresh `prFeedbackStageA`
1073
+ * the pending write itself is recording survives — it is evidence recorded
1074
+ * after the invalidation moment. No-op when no live window exists (the
1075
+ * normal unarmed flow keeps its existing behavior).
1076
+ *
1077
+ * Returns the pending state plus the audit-event payload; the CALLER appends
1078
+ * the event only AFTER its persistState succeeds (PR #2422 review PRR-023:
1079
+ * an event must never claim an invalidation whose state write failed — the
1080
+ * abort path's retraction discipline, applied here at the source).
1081
+ */
1082
+ declare function supersedeLivePublicationInPendingState(pending: PrWorkflowGateState, reason: string): {
1083
+ state: PrWorkflowGateState;
1084
+ invalidationEvent: Record<string, unknown> | null;
1085
+ };
1086
+ /**
1087
+ * Parse a standalone push command into a typed intent BEFORE any shell
1088
+ * execution. The only publish-capable intent is the exact armed tuple —
1089
+ * `git push <remote> <localHead>:refs/heads/<branch>` — with NO flags, NO
1090
+ * extra refspecs, NO wildcard/delete/mirror/tag forms, and NO
1091
+ * credential-bearing remote token. This is a structural refactor of the
1092
+ * previous single-regex defense with the SAME accepted grammar (nothing that
1093
+ * the regex rejected is accepted here); every rejection is now explicit,
1094
+ * typed, and auditable. Remote and branch compare case-SENSITIVELY (git ref
1095
+ * semantics); the source SHA compares exactly, as before.
1096
+ */
1097
+ declare function parseExactBoundPushIntent(command: string, armed: {
1098
+ remoteName: string;
1099
+ remoteBranchRef: string;
1100
+ localHead: string;
1101
+ }): ExactPushIntentParseResult;
1102
+ /**
1103
+ * Durable attempt-start before the exact bound push is permitted to execute
1104
+ * (issue #2108 §3), all under ONE session-lock acquisition: re-verify the
1105
+ * armed identity, observe the remote head, and either (a) record an
1106
+ * attempt whose result is already `completed` because the remote is observed
1107
+ * at the approved head (no-op push; the observation — not an exit code — is
1108
+ * the truth), or (b) persist the attempt-start and move the generation to
1109
+ * `push_in_flight` BEFORE the push can run.
1110
+ */
1111
+ declare function admitPrFeedbackPushAttempt(directory: string, sessionID: string, callID: string | undefined, intent: ExactPushIntent, intentDigest: string): Promise<{
1112
+ kind: 'started' | 'already-published-remotely';
1113
+ }>;
1114
+ /**
1115
+ * Record the result of an admitted push from the `tool.execute.after` chain
1116
+ * (issue #2108 §3). Fail-open by design: a missed observation is recovered by
1117
+ * the reaper as `uncertain`; publication truth always comes from
1118
+ * complete_pr_workflow's direct remote verification, never from an exit code
1119
+ * alone. Exported for the single `tool.execute.after` guard in `src/index.ts`.
1120
+ */
1121
+ export declare function recordPrFeedbackPushAttemptResult(directory: string, input: {
1122
+ sessionID: string;
1123
+ callID?: string;
1124
+ tool: string;
1125
+ }, command: string, output: unknown): Promise<void>;
1126
+ /**
1127
+ * Cancellation without publication (issue #2108 §6): a terminal no-publish
1128
+ * transition. Finalizes any in-flight attempt as `cancelled`, discloses the
1129
+ * observed remote head, marks the generation `cancelled_without_publication`,
1130
+ * appends the audit event, and NEVER manufactures push authority. Used only
1131
+ * by `abortPrWorkflow`'s explicit `cancelPublication` arm. Returns the NEW
1132
+ * state revision when a state write landed (the abort clear must CAS against
1133
+ * it), or null when the generation state was absent/unreadable.
1134
+ */
1135
+ declare function cancelPrFeedbackPublication(directory: string, sessionID: string, reason: string): Promise<number | null>;
863
1136
  export declare function resolvePrReviewWriterRunId(directory: string, sessionID: string, requestedRunId?: string): Promise<string>;
864
1137
  export declare function markPrReviewTriggerEvaluationComplete(directory: string, sessionID: string, runId: string, artifactPath: string): Promise<PrWorkflowGateState>;
865
1138
  /** Freeze one exact inline trigger ledger across every micro dispatch. */
@@ -898,7 +1171,7 @@ export declare function validatePrFeedbackScopeBinding(directory: string, bindin
898
1171
  workflowSessionId?: string;
899
1172
  workflowRevisionDigest?: string;
900
1173
  }): Promise<boolean>;
901
- export declare function enforcePrWorkflowToolBefore(directory: string, sessionID: string, toolName: string, args: Record<string, unknown> | undefined, generatedAgentNames?: readonly string[]): Promise<void>;
1174
+ export declare function enforcePrWorkflowToolBefore(directory: string, sessionID: string, toolName: string, args: Record<string, unknown> | undefined, generatedAgentNames?: readonly string[], callID?: string): Promise<void>;
902
1175
  /** Validate the terminal PR workflow contract before removing its durable gate. */
903
1176
  export declare function completePrWorkflow(directory: string, sessionID: string, expectedMode: PrWorkflowMode, prHeadSha: string): Promise<PrWorkflowCompletionStatus>;
904
1177
  export declare const _test_exports: {
@@ -985,6 +1258,21 @@ export declare const _test_exports: {
985
1258
  resolveCurrentUpstreamPushTarget: typeof resolveCurrentUpstreamPushTarget;
986
1259
  resolveCurrentUpstreamPushTargetAsync: typeof resolveCurrentUpstreamPushTargetAsync;
987
1260
  resolveCurrentUpstreamRemoteRef: typeof resolveCurrentUpstreamRemoteRef;
1261
+ resolveCurrentLocalHeadRefAsync: typeof resolveCurrentLocalHeadRefAsync;
1262
+ resolveRemoteUrlIdentity: typeof resolveRemoteUrlIdentity;
1263
+ resolveRemoteUrlIdentityAsync: typeof resolveRemoteUrlIdentityAsync;
1264
+ parseExactBoundPushIntent: typeof parseExactBoundPushIntent;
1265
+ admitPrFeedbackPushAttempt: typeof admitPrFeedbackPushAttempt;
1266
+ recordPrFeedbackPushAttemptResult: typeof recordPrFeedbackPushAttemptResult;
1267
+ reconcileForeignInFlightAttempt: typeof reconcileForeignInFlightAttempt;
1268
+ ensurePublicationGenerationCurrent: typeof ensurePublicationGenerationCurrent;
1269
+ invalidatePublicationGeneration: typeof invalidatePublicationGeneration;
1270
+ invalidatePrFeedbackPublication: typeof invalidatePrFeedbackPublication;
1271
+ cancelPrFeedbackPublication: typeof cancelPrFeedbackPublication;
1272
+ buildPublicationEvidenceJoin: typeof buildPublicationEvidenceJoin;
1273
+ nextPublicationContainer: typeof nextPublicationContainer;
1274
+ supersedeLivePublicationInPendingState: typeof supersedeLivePublicationInPendingState;
1275
+ describePrWorkflowPublicationSection: typeof describePrWorkflowPublicationSection;
988
1276
  resolveExactRemoteBranchHead: typeof resolveExactRemoteBranchHead;
989
1277
  resolveExactRemoteBranchHeadAsync: typeof resolveExactRemoteBranchHeadAsync;
990
1278
  resolveCommitCountSince: typeof resolveCommitCountSince;