opencode-swarm 7.163.1 → 7.164.1

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 (105) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/{coder-settlement-f1gtvcy8.js → coder-settlement-w4qk90kh.js} +12 -13
  3. package/dist/cli/{config-doctor-0fnqzqz1.js → config-doctor-r81bp1nd.js} +3 -3
  4. package/dist/cli/{core-w81fk5sc.js → core-xfw4s9b9.js} +2 -2
  5. package/dist/cli/{curation-policy-j12j2gvc.js → curation-policy-2h37sd6p.js} +6 -7
  6. package/dist/cli/{curator-as495r18.js → curator-7zy6bdmw.js} +36 -39
  7. package/dist/cli/{curator-drift-g6w4ga1q.js → curator-drift-ykrdf08r.js} +105 -38
  8. package/dist/cli/curator-llm-factory-7gjvm4ds.js +66 -0
  9. package/dist/cli/{evidence-summary-service-51dxfcn5.js → evidence-summary-service-519ny6b1.js} +17 -18
  10. package/dist/cli/{gate-evidence-nb1e8hz0.js → gate-evidence-a7st3vbc.js} +8 -9
  11. package/dist/cli/guardrail-explain-ewcm37em.js +67 -0
  12. package/dist/cli/{guardrail-log-2kwntcqw.js → guardrail-log-kp51by1v.js} +8 -9
  13. package/dist/cli/{guardrail-reset-mrxrc56j.js → guardrail-reset-reyfwtwn.js} +36 -39
  14. package/dist/cli/hive-promoter-zf2vf5sw.js +81 -0
  15. package/dist/cli/{index-4p0wyz5p.js → index-1af3rb5n.js} +9 -9
  16. package/dist/cli/{index-2zgjcmmc.js → index-1b1h770t.js} +3 -3
  17. package/dist/cli/{index-0tervb1m.js → index-2ee2g27m.js} +7795 -2724
  18. package/dist/cli/{index-x2f1f011.js → index-2s40e3b0.js} +4 -3
  19. package/dist/cli/{index-9xd073d4.js → index-2yd732fd.js} +7 -1
  20. package/dist/cli/{index-9crtmnqg.js → index-36nt17m8.js} +1 -1
  21. package/dist/cli/{index-d3azve4r.js → index-5084szce.js} +122 -300
  22. package/dist/cli/{index-d9gdwh34.js → index-5bza8nxz.js} +2 -2
  23. package/dist/cli/{index-xyhmt813.js → index-6097tx05.js} +1 -1
  24. package/dist/cli/{index-5056zmpt.js → index-644t46hr.js} +1 -1
  25. package/dist/cli/{index-2v06a1yh.js → index-6ay5zp1v.js} +5 -5
  26. package/dist/cli/{index-n2mhyect.js → index-6kd3jnaf.js} +1 -1
  27. package/dist/cli/{index-n67vx5zw.js → index-6t35714n.js} +2 -2
  28. package/dist/cli/{index-tnpf9wwv.js → index-862c0xhc.js} +1 -1
  29. package/dist/cli/{index-2n1ym7jb.js → index-b98r3pyv.js} +5 -5
  30. package/dist/cli/{index-8ada7ag7.js → index-dhzsvmx6.js} +2 -2
  31. package/dist/cli/{index-n985274d.js → index-e630pvvw.js} +4 -4
  32. package/dist/cli/{index-3b762978.js → index-f9nfknjg.js} +182 -37
  33. package/dist/cli/{index-m1fvbah1.js → index-fwfhbs27.js} +2 -2
  34. package/dist/cli/{index-t34daffb.js → index-h2f21caa.js} +2 -2
  35. package/dist/cli/{index-9ss2m4rs.js → index-hcn69kp0.js} +410 -1
  36. package/dist/cli/{index-g3znh2yd.js → index-hzaw10zh.js} +7 -7
  37. package/dist/cli/{index-cqgpvx2d.js → index-j0ajeary.js} +2 -2
  38. package/dist/cli/{index-f923njwh.js → index-jczbtx2x.js} +7 -7
  39. package/dist/cli/{index-hm239n1p.js → index-k8j7m0e2.js} +1 -1
  40. package/dist/cli/{index-zjme8atd.js → index-n1wcq816.js} +5 -5
  41. package/dist/cli/{index-66073kej.js → index-pmmfhzsp.js} +3 -3
  42. package/dist/cli/{index-fckfgptr.js → index-qbr05tbw.js} +2 -2
  43. package/dist/cli/{index-r56f3f81.js → index-r5jn0ah5.js} +2 -2
  44. package/dist/cli/{index-dtn0pne5.js → index-v56mhyhs.js} +1 -1
  45. package/dist/cli/{index-etvq73mp.js → index-vc3zmtxb.js} +38 -41
  46. package/dist/cli/{index-kvra3nv1.js → index-vdgw2k4c.js} +3 -3
  47. package/dist/cli/{index-0103w5pf.js → index-vkckf2ch.js} +2 -2
  48. package/dist/cli/{index-swgy9xvk.js → index-vrxx0ea4.js} +4 -4
  49. package/dist/cli/{index-08y8pccg.js → index-wnf1ej2q.js} +4 -4
  50. package/dist/cli/{index-qynqyfgj.js → index-wv4b01ex.js} +32 -34
  51. package/dist/cli/{index-7n9jznv0.js → index-x2qmpkth.js} +5 -5
  52. package/dist/cli/index-y2f5s2cf.js +403 -0
  53. package/dist/cli/{index-ma52g2pq.js → index-yc415pzf.js} +655 -16
  54. package/dist/cli/{index-n249fbw7.js → index-zaab1wz9.js} +5 -0
  55. package/dist/cli/index.js +36 -39
  56. package/dist/cli/{knowledge-escalator-fq7dm2g4.js → knowledge-escalator-wwkbsgvw.js} +14 -15
  57. package/dist/cli/{knowledge-events-3zanyfkr.js → knowledge-events-vmmgwfmc.js} +12 -13
  58. package/dist/cli/{knowledge-link-vmdj5e5d.js → knowledge-link-bvra01zv.js} +5 -6
  59. package/dist/cli/{knowledge-store-vhehnw52.js → knowledge-store-6wbagbqm.js} +6 -7
  60. package/dist/cli/{knowledge-validator-0tt0pe6b.js → knowledge-validator-q1z4fmeg.js} +8 -9
  61. package/dist/cli/{model-preflight-c3mc8njg.js → model-preflight-1ecjbg73.js} +1 -1
  62. package/dist/cli/{pending-delegations-b92pecbj.js → pending-delegations-cq5g4rr4.js} +6 -8
  63. package/dist/cli/{pr-subscriptions-2mkdt0ak.js → pr-subscriptions-m0z5wxkb.js} +6 -7
  64. package/dist/cli/pr-workflow-gate-0zvp0qs9.js +221 -0
  65. package/dist/cli/{runner-3gw2njnx.js → runner-s55g5233.js} +6 -7
  66. package/dist/cli/{scan-cursor-1c8a3b0m.js → scan-cursor-z6zepy3r.js} +7 -8
  67. package/dist/cli/{schema-c554j5c8.js → schema-skf0ckh4.js} +2 -2
  68. package/dist/cli/{scope-persistence-vtbcszvv.js → scope-persistence-f6davq7x.js} +10 -11
  69. package/dist/cli/{skill-generator-0es21fck.js → skill-generator-wqbazppk.js} +16 -17
  70. package/dist/cli/{sqlite-loader-c92413n7.js → sqlite-loader-8zefc142.js} +1 -1
  71. package/dist/cli/{telemetry-x4zggfd7.js → telemetry-q51s6tyt.js} +1 -1
  72. package/dist/cli/{worktree-collision-ownership-043dg8gg.js → worktree-collision-ownership-c0030qbm.js} +7 -9
  73. package/dist/cli/{worktree-isolation-hk42yxw7.js → worktree-isolation-09qq8066.js} +36 -39
  74. package/dist/db/canonical-project.d.ts +31 -0
  75. package/dist/db/db-errors.d.ts +24 -0
  76. package/dist/db/driver-parity.d.ts +31 -0
  77. package/dist/db/durability.d.ts +40 -0
  78. package/dist/db/group-commit-writer.d.ts +117 -0
  79. package/dist/db/health.d.ts +35 -0
  80. package/dist/db/insight-candidate-store.d.ts +61 -0
  81. package/dist/db/legacy-import.d.ts +77 -0
  82. package/dist/db/phase-report-store.d.ts +45 -0
  83. package/dist/db/project-db.d.ts +35 -8
  84. package/dist/db/qa-gate-profile.d.ts +2 -0
  85. package/dist/hooks/curator-drift.d.ts +9 -5
  86. package/dist/hooks/curator-types.d.ts +1 -0
  87. package/dist/hooks/delegation-gate.d.ts +1 -0
  88. package/dist/hooks/knowledge-curator.d.ts +5 -3
  89. package/dist/hooks/micro-reflector.d.ts +12 -7
  90. package/dist/hooks/pr-workflow-gate.d.ts +14 -8
  91. package/dist/hooks/pr-workflow-response-gate.d.ts +9 -12
  92. package/dist/index.js +627 -574
  93. package/dist/memory/schema.d.ts +4 -4
  94. package/dist/pr-review/authorization.d.ts +18 -12
  95. package/dist/prm/index.d.ts +3 -1
  96. package/dist/tools/authorize-pr-review-reentry.d.ts +12 -8
  97. package/package.json +3 -2
  98. package/dist/cli/authorization-vstrh7ra.js +0 -23
  99. package/dist/cli/curator-llm-factory-v8vwz20c.js +0 -69
  100. package/dist/cli/guardrail-explain-z2qb6v67.js +0 -70
  101. package/dist/cli/hive-promoter-c62x2ncb.js +0 -84
  102. package/dist/cli/index-c8s9a3zh.js +0 -73
  103. package/dist/cli/index-ed5ykebp.js +0 -151
  104. package/dist/cli/index-mmngnxev.js +0 -883
  105. package/dist/cli/index-w7ekntej.js +0 -643
@@ -0,0 +1,45 @@
1
+ /**
2
+ * swarm.db store for per-phase reports (issue #2480 D1 migration).
3
+ *
4
+ * Replaces two legacy file families with the entity/KV pattern — one row per
5
+ * (kind, phase), last-write-wins on a same-phase re-run:
6
+ * - `.swarm/drift-report-phase-{N}.json` (curator drift, kind
7
+ * `curator_drift`) — written by `src/hooks/curator-drift.ts`, read back by
8
+ * `readPriorDriftReports` and the curator postmortem.
9
+ * - `.swarm/doc-drift-phase-{N}.json` (design-doc drift, kind
10
+ * `design_doc_drift`) — written by `src/hooks/design-doc-drift.ts` (whose
11
+ * legacy bare `writeFile` was non-atomic; the store fixes that).
12
+ *
13
+ * Payloads are opaque serialized JSON strings; readers own validation
14
+ * (skip-corrupt on read, mirroring the legacy readers).
15
+ */
16
+ export type PhaseReportKind = 'curator_drift' | 'design_doc_drift';
17
+ /** Legacy filename prefixes, one per report kind. */
18
+ export declare const PHASE_REPORT_LEGACY_PREFIXES: Readonly<Record<PhaseReportKind, string>>;
19
+ /**
20
+ * One-time (per process, per canonical root) lazy import of both legacy
21
+ * report families. Never runs at plugin init.
22
+ */
23
+ export declare function ensurePhaseReportsImported(directory: string): void;
24
+ /**
25
+ * Upsert one phase report via the group-commit writer and await the flush.
26
+ * A same-phase re-run overwrites the row (the legacy file rewrite semantic)
27
+ * and `updated_at` moves.
28
+ */
29
+ export declare function upsertPhaseReportDb(directory: string, kind: PhaseReportKind, phase: number, payload: string): Promise<void>;
30
+ /**
31
+ * Read all reports of one kind, ascending by phase. Returns the raw payload
32
+ * strings; the caller validates (the curator drift reader keeps its
33
+ * skip-corrupt schema check).
34
+ */
35
+ export declare function readPhaseReportsDb(directory: string, kind: PhaseReportKind): Array<{
36
+ phase: number;
37
+ payload: string;
38
+ }>;
39
+ /**
40
+ * Stable, human-readable locator for a stored report (event payloads and
41
+ * advisory text reference the DB-backed store instead of a file path).
42
+ */
43
+ export declare function phaseReportLocator(kind: PhaseReportKind, phase: number): string;
44
+ /** Test hook: reset the per-process import guards. */
45
+ export declare function _resetPhaseReportImportGuards(): void;
@@ -1,16 +1,32 @@
1
1
  /**
2
2
  * Per-project SQLite database for opencode-swarm.
3
3
  *
4
- * Owns `.swarm/swarm.db` in each project directory. Stores per-project
5
- * constraints and QA gate profiles. One cached instance per normalized
6
- * directory path.
4
+ * Owns `.swarm/swarm.db` in each project directory: the single durable
5
+ * substrate of Workstream D (issue #2480). One cached instance per CANONICAL
6
+ * project identity (`canonical-project.ts`): case-varied Windows spellings,
7
+ * trailing separators, and symlinked roots of the same project share one
8
+ * connection. Open failures are typed (`db-errors.ts`), failed migrations are
9
+ * recorded for diagnosis and retried on the next open, and close runs a
10
+ * best-effort WAL checkpoint. The durability-class policy for every table
11
+ * lives in `durability.ts`.
7
12
  */
8
13
  import type { Database } from 'bun:sqlite';
14
+ /** Number of currently cached project DB handles (tests / observability). */
15
+ export declare function getOpenProjectDbCount(): number;
16
+ /**
17
+ * Detect "another process applied this migration concurrently" failures:
18
+ * a UNIQUE constraint violation on schema_migrations.version, or an
19
+ * "already exists" DDL error (table/index/trigger created by the winner).
20
+ */
21
+ export declare function isConcurrentMigrationApply(err: unknown): boolean;
9
22
  /**
10
23
  * Run all pending migrations on the provided database.
11
- * Idempotent: existing migrations are not re-applied.
24
+ * Idempotent: existing migrations are not re-applied. Each migration applies
25
+ * in its own transaction; a failure rolls back, is recorded for diagnosis
26
+ * (table row, or the marker fallback), and leaves the version un-bumped so
27
+ * the next open retries it.
12
28
  */
13
- export declare function runProjectMigrations(db: Database): void;
29
+ export declare function runProjectMigrations(db: Database, markerDir?: string): void;
14
30
  /**
15
31
  * Return the absolute path to `.swarm/swarm.db` for the given directory.
16
32
  * Does not create the file or any parent directory.
@@ -26,13 +42,24 @@ export declare function projectDbExists(directory: string): boolean;
26
42
  /**
27
43
  * Return the cached project database for the given directory, opening it
28
44
  * if needed. Creates `.swarm/` if absent and enables WAL + foreign keys.
45
+ * The cache is keyed by canonical project identity, so case-varied Windows
46
+ * spellings, trailing separators, and symlinked roots share ONE handle.
47
+ * Open failures throw a typed `ProjectDbError` and never leave a
48
+ * half-open handle cached.
29
49
  */
30
50
  export declare function getProjectDb(directory: string): Database;
31
51
  /**
32
52
  * Close and remove the cached project database for the given directory.
33
- * Called by the `/swarm close` clean stage before unlinking `swarm.db` (so a
34
- * long-lived WAL-mode connection releases its file lock and Windows `unlink`
35
- * does not fail with EBUSY), and from tests.
53
+ * Runs a best-effort WAL checkpoint (TRUNCATE, PASSIVE fallback) first so the
54
+ * close leaves a self-contained DB file where possible. Called by the
55
+ * `/swarm close` clean stage before unlinking `swarm.db` (so a long-lived
56
+ * WAL-mode connection releases its file lock and Windows `unlink` does not
57
+ * fail with EBUSY), by the plugin dispose/exit close paths, and from tests.
58
+ *
59
+ * Callers that passed a different spelling of the same root (case variant on
60
+ * Windows, symlink) share the canonical handle: closing it invalidates every
61
+ * alias — which is the point (those aliases were previously silent duplicate
62
+ * writers on one file). Reopening via `getProjectDb` always works.
36
63
  */
37
64
  export declare function closeProjectDb(directory: string): void;
38
65
  /**
@@ -31,6 +31,8 @@ export declare const _internals: {
31
31
  profileId: number;
32
32
  storagePlanId: string;
33
33
  }) => void) | undefined;
34
+ /** #2480 test probe: synchronous level observed during the last write txn. */
35
+ lastTxnSynchronous: number;
34
36
  };
35
37
  /**
36
38
  * QA gate flags. All eleven gates are tracked explicitly.
@@ -1,14 +1,18 @@
1
1
  import type { CriticDriftResult, CuratorConfig, CuratorPhaseResult, DriftReport } from './curator-types.js';
2
2
  /**
3
- * Read all prior drift reports from .swarm/drift-report-phase-*.json files.
3
+ * Read all prior drift reports (#2480: from the `phase_report` entity table
4
+ * in `.swarm/swarm.db`, kind `curator_drift`; the legacy
5
+ * `.swarm/drift-report-phase-*.json` files are imported once — idempotent,
6
+ * one-txn — and cold-archived `.json.imported`).
4
7
  * Returns reports sorted ascending by phase number.
5
- * Skips corrupt/unreadable files with a console.warn.
8
+ * Skips corrupt/unreadable payloads with a console.warn.
6
9
  */
7
10
  export declare function readPriorDriftReports(directory: string): Promise<DriftReport[]>;
8
11
  /**
9
- * Write a drift report to .swarm/drift-report-phase-{N}.json.
10
- * Creates .swarm/ if it doesn't exist.
11
- * Returns the absolute path of the written file.
12
+ * Write a drift report to the `phase_report` entity table (#2480: upsert via
13
+ * the group-commit writer one txn per flush, atomic, replacing the legacy
14
+ * non-batched file rewrite). A same-phase re-run overwrites the row.
15
+ * Returns the DB-backed report locator.
12
16
  */
13
17
  export declare function writeDriftReport(directory: string, report: DriftReport): Promise<string>;
14
18
  export declare const _internals: {
@@ -155,6 +155,7 @@ export interface SkillCandidate {
155
155
  export interface CriticDriftResult {
156
156
  phase: number;
157
157
  report: DriftReport;
158
+ /** #2480: DB-backed locator, e.g. `swarm.db:phase_report(curator_drift,3)`. */
158
159
  report_path: string;
159
160
  injection_text: string;
160
161
  }
@@ -494,6 +494,7 @@ export declare const _internals: {
494
494
  PLAN_CRITIC_TASK_SIGNALS: readonly ["critic-gate", "plan critic", "review plan", "review the plan", "plan.md", "approve the plan", "plan approval", "pre-implementation review", "evaluate this plan", "evaluate the plan", "assess this plan", "assess the plan", "plan soundness", "before implementation", "review the plan below"];
495
495
  extractPlanCriticVerdict: typeof extractPlanCriticVerdict;
496
496
  forceRecordPlanCriticApproval: typeof forceRecordPlanCriticApproval;
497
+ beforePrFeedbackScopeConsume: (() => Promise<void>) | undefined;
497
498
  provisionWorktree: typeof _wtiInternals.provisionWorktree;
498
499
  removeWorktree: typeof _wtiInternals.removeWorktree;
499
500
  attemptMergeBackFromDirty: typeof _wtiInternals.attemptMergeBackFromDirty;
@@ -69,9 +69,11 @@ export declare function enrichLessonToV3(params: {
69
69
  /** Max insight candidates folded into the store per phase boundary. */
70
70
  export declare const MESO_INSIGHT_BATCH_LIMIT = 20;
71
71
  /**
72
- * Atomically consume up to `batchLimit` insight candidates from
73
- * `.swarm/insight-candidates.jsonl`, writing back the unconsumed tail under the
74
- * same lock so concurrent micro-reflection appends are never lost. Fail-open.
72
+ * Atomically consume up to `batchLimit` insight candidates from the durable
73
+ * `insight_candidate` stream in `.swarm/swarm.db` (issue #2480). The SELECT
74
+ * and the consumed_at UPDATE happen in ONE immediate transaction, so
75
+ * concurrent appends are never lost and a batch is never double-taken.
76
+ * Fail-open: returns [] on any DB error.
75
77
  */
76
78
  export declare function consumeInsightCandidates(directory: string, batchLimit?: number): Promise<InsightCandidate[]>;
77
79
  /** Build a SwarmKnowledgeEntry from an already-v3-actionable insight candidate. */
@@ -123,14 +123,19 @@ export declare function classifyOutcome(transcript: string, trajectory: Trajecto
123
123
  /** Read a task's trajectory slice. Fail-open: [] when absent/corrupt. */
124
124
  export declare function readTaskTrajectory(directory: string, taskId: string): Promise<TrajectoryEntry[]>;
125
125
  export declare const INSIGHT_CANDIDATES_MAX_ENTRIES = 500;
126
- /** Append validated candidates to the insight queue (best-effort, fail-open).
127
- * Uses transactFile for consistency with consumeInsightCandidates and enforces
128
- * a FIFO cap to prevent unbounded growth between phase completions.
126
+ /**
127
+ * Append validated candidates to the insight queue (best-effort, fail-open).
128
+ *
129
+ * #2480: the durable queue is the `insight_candidate` stream table in
130
+ * `.swarm/swarm.db` (group-commit writer, one txn per flush; FIFO cap 500 on
131
+ * the pending queue — same bound as before). The legacy
132
+ * `.swarm/insight-candidates.jsonl` is imported once (idempotent, one-txn)
133
+ * and cold-archived `.jsonl.imported`.
129
134
  *
130
- * EXPORTED (#1821) so the PRM pattern producer can write the SAME durable
131
- * crash backstop the micro-reflector writes. Any producer that only enqueues
132
- * in memory loses its candidate on process death, on queue overflow, and on a
133
- * drain failure — with no phase-boundary fold-in to recover it. */
135
+ * EXPORTED (#1821) so the PRM pattern producer can write the SAME durable
136
+ * crash backstop the micro-reflector writes. Any producer that only enqueues
137
+ * in memory loses its candidate on process death, on queue overflow, and on a
138
+ * drain failure — with no phase-boundary fold-in to recover it. */
134
139
  export declare function appendInsightCandidates(directory: string, candidates: InsightCandidate[]): Promise<void>;
135
140
  /** Build the bounded micro-reflection prompt (≤ MICRO_PROMPT_INPUT_CAP chars). */
136
141
  export declare function buildMicroPrompt(params: {
@@ -8,6 +8,7 @@ import { type PrReviewInlineTriggerRow } from '../background/pr-review-trigger-c
8
8
  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';
9
9
  import { type PrReviewResilienceConfig } from '../config/schema.js';
10
10
  import { classifyPrWorkflowGitState, type PrWorkflowGitState } from '../git/pr-workflow-state.js';
11
+ import { type PrReviewReentryAuthorizationRecord, type PrReviewReentryBindingContext, type PrReviewReentryRole } from '../pr-review/authorization.js';
11
12
  import { classifyPrReviewCircuitSignal, type PrReviewCircuitLegacyRecord, type PrReviewCircuitRecordV2, type PrReviewResiliencePolicyRecord, resolvePrReviewResiliencePolicy } from '../pr-review/circuit.js';
12
13
  import { type PrReviewDimensionCancellationRecord, type PrReviewPartialBaseCoverageRecord, type PrReviewReportVerdict, type PrReviewTerminalCoverageSettlement } from '../pr-review/completion.js';
13
14
  import { type PrReviewComposablePhase, type PrReviewPhaseComposition, parseCriticVerdict } from '../pr-review/legacy-transcript-adapter.js';
@@ -1252,7 +1253,7 @@ export declare function transitionPrReviewToFeedback(directory: string, sessionI
1252
1253
  }): Promise<PrWorkflowGateState>;
1253
1254
  export declare function declarePrFeedbackScope(directory: string, sessionID: string, taskId: string, files: string[]): Promise<PrWorkflowGateState>;
1254
1255
  export declare function resolvePrFeedbackScopeDeclaration(directory: string, sessionID: string, taskId: string): Promise<PrFeedbackScopeDeclarationRecord | null>;
1255
- export declare function consumePrFeedbackScopeDeclaration(directory: string, sessionID: string, taskId: string, callID: string): Promise<PrFeedbackScopeDeclarationRecord | null>;
1256
+ export declare function consumePrFeedbackScopeDeclaration(directory: string, sessionID: string, taskId: string, callID: string, expected: Pick<PrFeedbackScopeDeclarationRecord, 'declaredAt' | 'revisionDigest' | 'files'>): Promise<PrFeedbackScopeDeclarationRecord | null>;
1256
1257
  export declare function validatePrFeedbackScopeBinding(directory: string, binding: {
1257
1258
  taskId: string;
1258
1259
  files: string[];
@@ -1270,13 +1271,16 @@ export declare function enforcePrWorkflowToolBefore(directory: string, sessionID
1270
1271
  * revision), workflow instance id, and the active run id. Null when no active
1271
1272
  * head-bound PR_REVIEW gate exists for the session.
1272
1273
  */
1273
- export declare function readPrReviewReentryBindingContext(directory: string, sessionID: string): Promise<{
1274
- prHeadSha: string;
1275
- revisionDigest: string;
1276
- generation: number;
1277
- workflowInstanceId?: string;
1278
- runId?: string;
1279
- } | null>;
1274
+ export declare function readPrReviewReentryBindingContext(directory: string, sessionID: string): Promise<PrReviewReentryBindingContext | null>;
1275
+ /**
1276
+ * Sole production reservation/verification path for direct PR-review re-entry.
1277
+ * Lock order is fixed: workflow-session first, authorization store second. The
1278
+ * active binding cannot change between its locked reread and reservation commit.
1279
+ */
1280
+ export declare function reserveActivePrReviewReentryAuthorization(directory: string, sessionID: string, request: {
1281
+ role: PrReviewReentryRole;
1282
+ callID: string;
1283
+ }): Promise<PrReviewReentryAuthorizationRecord | null>;
1280
1284
  export declare function completePrWorkflow(directory: string, sessionID: string, expectedMode: PrWorkflowMode, prHeadSha: string, options?: {
1281
1285
  reportVerdict?: PrReviewReportVerdict;
1282
1286
  }): Promise<PrWorkflowCompletionStatus>;
@@ -1305,6 +1309,8 @@ export declare const _test_exports: {
1305
1309
  beforePrFeedbackTrackingSwitch: (() => Promise<void>) | undefined;
1306
1310
  afterPrFeedbackTrackingSwitch: (() => Promise<void>) | undefined;
1307
1311
  beforePrFeedbackTrackingPersist: (() => Promise<void>) | undefined;
1312
+ /** Interleave point held inside the workflow-session lock before auth commit. */
1313
+ beforePrReviewReentryReservation: (() => Promise<void>) | undefined;
1308
1314
  beforeBoundedSwarmFileOpen: (() => Promise<void>) | undefined;
1309
1315
  beforeSessionStateLockWrite: (() => Promise<void>) | undefined;
1310
1316
  beforeCheckoutLockWrite: (() => Promise<void>) | undefined;
@@ -1,3 +1,4 @@
1
+ import { scanDelegationsForRecovery } from '../background/pending-delegations.js';
1
2
  import { claimPrFeedbackMonitorEvents, readPrFeedbackMonitorQueue } from '../background/pr-feedback-event-queue.js';
2
3
  import { observePrWorkflowAutoWakeEvent } from './pr-workflow-auto-wake.js';
3
4
  import { type PrReviewDepthTier, readPrWorkflowGateState } from './pr-workflow-gate.js';
@@ -10,22 +11,16 @@ export declare const _internals: {
10
11
  claimPrFeedbackMonitorEvents: typeof claimPrFeedbackMonitorEvents;
11
12
  readPrFeedbackMonitorQueue: typeof readPrFeedbackMonitorQueue;
12
13
  observePrWorkflowAutoWakeEvent: typeof observePrWorkflowAutoWakeEvent;
14
+ scanDelegationsForRecovery: typeof scanDelegationsForRecovery;
13
15
  };
14
16
  /**
15
17
  * Maximum number of consecutive unproductive auto-resumes per gated session
16
18
  * before the response gate suspends further wakes. "Unproductive" means the
17
- * durable gate's `revision` did not advance between wakes i.e. no
18
- * state-mutating controller tool (dispatch_lanes_async,
19
- * write_pr_review_trigger_eval, complete_pr_workflow, recordPrReview*,
20
- * bindPrReviewBase, …) made durable progress. A healthy review bumps
21
- * `revision` on every successful state-mutating controller call, so the
22
- * consecutive counter resets on progress and never exhausts the budget.
23
- * Read-only tools (collect_lane_results polling, grep, read) intentionally do
24
- * NOT bump `revision` — an architect that only polls without ever dispatching
25
- * new lanes or recording trigger evaluations IS making progress on the
26
- * runtime's bookkeeping but is not advancing the durable gate, so the budget
27
- * treats long polling-only stretches conservatively. Only a genuinely stuck
28
- * session holds `revision` constant across many idle cycles.
19
+ * fixed-size digest of the durable gate plus its exact active delegation lanes
20
+ * did not change. Controller revisions, lane status transitions, terminal
21
+ * events, and structured receipt digests count as progress; repeated
22
+ * collect_lane_results polls do not. Strict-ledger uncertainty is sticky and
23
+ * never earns progress credit, including the first recovered snapshot.
29
24
  */
30
25
  export declare const DEFAULT_MAX_CONSECUTIVE_UNPRODUCTIVE_WAKES = 5;
31
26
  /**
@@ -102,6 +97,8 @@ interface WakeBudget {
102
97
  consecutiveUnproductive: number;
103
98
  lastWakeAt: number;
104
99
  lastSeenRevision?: number;
100
+ lastSeenProgressToken?: string;
101
+ progressUncertain: boolean;
105
102
  suspended: boolean;
106
103
  /** Total number of wake attempts recorded for this budget. NEVER reset by
107
104
  * revision progress — only the consecutive counter resets on progress; that