@quantiya/codevibe-core 2.0.7 → 2.0.9

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 (128) hide show
  1. package/dist/appsync/__tests__/dispose-watcher-socket.test.d.ts +1 -0
  2. package/dist/appsync/__tests__/refresh-open-prompt-ttl-chunk.test.d.ts +1 -0
  3. package/dist/appsync/appsync-client.d.ts +232 -30
  4. package/dist/appsync/queries.d.ts +2 -0
  5. package/dist/auth/__tests__/keychain-cli-nudge.test.d.ts +1 -0
  6. package/dist/auth/__tests__/keychain-cli.test.d.ts +1 -0
  7. package/dist/auth/keychain-cli.d.ts +14 -0
  8. package/dist/companion-mode/index.d.ts +14 -0
  9. package/dist/credential-broker/oauth-account-lock.d.ts +47 -1
  10. package/dist/crypto/__tests__/open-prompt-id.test.d.ts +1 -0
  11. package/dist/crypto/index.d.ts +1 -0
  12. package/dist/crypto/open-prompt-id.d.ts +36 -0
  13. package/dist/e1/__tests__/prompt-raise.test.d.ts +1 -0
  14. package/dist/e1/index.d.ts +2 -0
  15. package/dist/e1/prompt-raise.d.ts +65 -0
  16. package/dist/index.d.ts +4 -1
  17. package/dist/index.js +4652 -252
  18. package/dist/keychain/__tests__/keychain-manager.test.d.ts +1 -0
  19. package/dist/keychain/__tests__/keychain-migrate.test.d.ts +1 -0
  20. package/dist/keychain/__tests__/migrate-nudge.test.d.ts +1 -0
  21. package/dist/keychain/keychain-backend.d.ts +105 -0
  22. package/dist/keychain/keychain-manager.d.ts +17 -3
  23. package/dist/keychain/keychain-migrate.d.ts +63 -0
  24. package/dist/keychain/migrate-nudge.d.ts +38 -0
  25. package/dist/local-executor/__tests__/anchored-fs.test.d.ts +1 -0
  26. package/dist/local-executor/__tests__/bounded-directory.test.d.ts +1 -0
  27. package/dist/local-executor/__tests__/bounded-output.test.d.ts +1 -0
  28. package/dist/local-executor/__tests__/durable-directory.test.d.ts +1 -0
  29. package/dist/local-executor/__tests__/hosted-class-a-sink.test.d.ts +1 -0
  30. package/dist/local-executor/__tests__/process-identity.test.d.ts +1 -0
  31. package/dist/local-executor/__tests__/process-tree.test.d.ts +1 -0
  32. package/dist/local-executor/__tests__/protocol-backlog-wiring.test.d.ts +1 -0
  33. package/dist/local-executor/__tests__/protocol-backlog.test.d.ts +1 -0
  34. package/dist/local-executor/__tests__/publication-authority-capability.test.d.ts +1 -0
  35. package/dist/local-executor/__tests__/snapshot-merge.test.d.ts +1 -0
  36. package/dist/local-executor/__tests__/workspace-authority-fixture.d.ts +3 -0
  37. package/dist/local-executor/__tests__/workspace-authority.test.d.ts +1 -0
  38. package/dist/local-executor/__tests__/workspace-cleanup-audit.test.d.ts +1 -0
  39. package/dist/local-executor/__tests__/workspace-materializer.test.d.ts +1 -0
  40. package/dist/local-executor/agentic-disposable-repo.d.ts +23 -6
  41. package/dist/local-executor/agentic-resolve.d.ts +16 -0
  42. package/dist/local-executor/anchored-fs.d.ts +250 -0
  43. package/dist/local-executor/bounded-directory.d.ts +78 -0
  44. package/dist/local-executor/bounded-helper.d.ts +22 -0
  45. package/dist/local-executor/bounded-output.d.ts +11 -0
  46. package/dist/local-executor/class-a-emit.d.ts +13 -1
  47. package/dist/local-executor/durable-directory.d.ts +25 -0
  48. package/dist/local-executor/durable-store.d.ts +217 -25
  49. package/dist/local-executor/hosted-class-a-sink.d.ts +27 -0
  50. package/dist/local-executor/index.d.ts +3 -2
  51. package/dist/local-executor/local-executor-impl.d.ts +159 -69
  52. package/dist/local-executor/process-identity.d.ts +46 -0
  53. package/dist/local-executor/process-tree.d.ts +123 -0
  54. package/dist/local-executor/protocol-backlog.d.ts +62 -0
  55. package/dist/local-executor/revert-reconcile.d.ts +4 -0
  56. package/dist/local-executor/revert-runner.d.ts +14 -1
  57. package/dist/local-executor/snapshot-merge.d.ts +124 -0
  58. package/dist/local-executor/task-group-types.d.ts +7 -6
  59. package/dist/local-executor/team-execution-flag.d.ts +2 -2
  60. package/dist/local-executor/track-registry.d.ts +2 -0
  61. package/dist/local-executor/types.d.ts +33 -2
  62. package/dist/local-executor/verification-gates/build.d.ts +5 -0
  63. package/dist/local-executor/verification-gates/deploy-preflight.d.ts +2 -0
  64. package/dist/local-executor/verification-gates/diff-sanity.d.ts +12 -0
  65. package/dist/local-executor/verification-gates/hostile-grep.d.ts +2 -0
  66. package/dist/local-executor/verification-gates/lint.d.ts +2 -0
  67. package/dist/local-executor/verification-gates/shell-runner.d.ts +5 -0
  68. package/dist/local-executor/verification-gates/source-traceability.d.ts +2 -0
  69. package/dist/local-executor/verification-gates/tests.d.ts +3 -0
  70. package/dist/local-executor/verification-gates/typecheck.d.ts +3 -0
  71. package/dist/local-executor/verification-runner.d.ts +6 -0
  72. package/dist/local-executor/workspace-authority.d.ts +45 -0
  73. package/dist/local-executor/workspace-cleanup-audit.d.ts +3 -0
  74. package/dist/local-executor/workspace-materializer.d.ts +48 -0
  75. package/dist/local-executor/workspace-shadow.d.ts +380 -85
  76. package/dist/orchestration-shell/__tests__/advisory-attachment-journal.test.d.ts +1 -0
  77. package/dist/orchestration-shell/__tests__/direct-file-delete.test.d.ts +1 -0
  78. package/dist/orchestration-shell/__tests__/flag-command.test.d.ts +1 -0
  79. package/dist/orchestration-shell/__tests__/halt-message-wire-content.test.d.ts +1 -0
  80. package/dist/orchestration-shell/__tests__/planner-offer-e1.test.d.ts +1 -0
  81. package/dist/orchestration-shell/__tests__/workspace-shutdown.test.d.ts +1 -0
  82. package/dist/orchestration-shell/advisory-attachment-journal.d.ts +165 -0
  83. package/dist/orchestration-shell/attachments.d.ts +47 -58
  84. package/dist/orchestration-shell/audit-browser.d.ts +54 -1
  85. package/dist/orchestration-shell/bounded-shutdown.d.ts +6 -0
  86. package/dist/orchestration-shell/cli.d.ts +10 -0
  87. package/dist/orchestration-shell/cli.js +38355 -27300
  88. package/dist/orchestration-shell/context-items.d.ts +3 -0
  89. package/dist/orchestration-shell/declared-test-runner.d.ts +21 -2
  90. package/dist/orchestration-shell/direct-file-delete.d.ts +22 -0
  91. package/dist/orchestration-shell/emit-shell-event.d.ts +7 -0
  92. package/dist/orchestration-shell/explicit-tty-exit.d.ts +1 -2
  93. package/dist/orchestration-shell/flag-command.d.ts +81 -0
  94. package/dist/orchestration-shell/gate-decision-submit.d.ts +11 -0
  95. package/dist/orchestration-shell/gate-prompts.d.ts +116 -0
  96. package/dist/orchestration-shell/index.d.ts +34 -6
  97. package/dist/orchestration-shell/planner-offer-e1.d.ts +97 -0
  98. package/dist/orchestration-shell/quorum-loop.d.ts +312 -61
  99. package/dist/orchestration-shell/reducer.d.ts +9 -0
  100. package/dist/orchestration-shell/task-progress.d.ts +18 -4
  101. package/dist/orchestration-shell/team-decompose.d.ts +10 -10
  102. package/dist/orchestration-shell/types.d.ts +90 -2
  103. package/dist/orchestration-shell/workspace-shutdown.d.ts +47 -0
  104. package/dist/reviewer/output-parser.d.ts +19 -0
  105. package/dist/reviewer/providers/codex.d.ts +5 -3
  106. package/dist/reviewer/token-usage.d.ts +41 -12
  107. package/dist/reviewer/types.d.ts +6 -0
  108. package/dist/reviewer/verdict-classifier.d.ts +1 -0
  109. package/dist/session/session-rekey.d.ts +4 -3
  110. package/dist/substrate/__tests__/command-runner.test.d.ts +1 -0
  111. package/dist/substrate/command-runner.d.ts +2 -0
  112. package/dist/substrate/docker.d.ts +7 -32
  113. package/dist/substrate/index.d.ts +0 -1
  114. package/dist/substrate/sandbox-exec.d.ts +0 -13
  115. package/dist/substrate/types.d.ts +15 -2
  116. package/dist/substrate-launch/__tests__/reviewer-credential-preflight.test.d.ts +1 -0
  117. package/dist/substrate-launch/engage-substrate.d.ts +3 -0
  118. package/dist/substrate-launch/index.d.ts +2 -0
  119. package/dist/substrate-launch/reviewer-credential-preflight.d.ts +50 -0
  120. package/dist/test-publication-authority-setup.d.ts +1 -0
  121. package/dist/tool-activity/replay-cursor.d.ts +42 -8
  122. package/dist/track-presentation.d.ts +2 -0
  123. package/dist/track-presentation.test.d.ts +1 -0
  124. package/dist/types/encryption.d.ts +5 -0
  125. package/dist/types/events.d.ts +5 -0
  126. package/package.json +3 -3
  127. package/dist/substrate/git-proxy.d.ts +0 -35
  128. /package/dist/{substrate/__tests__/git-proxy.test.d.ts → appsync/__tests__/appsync-client-flag-locator.test.d.ts} +0 -0
@@ -1,6 +1,7 @@
1
1
  import type { AppSyncClient, TeamTrackRecoveryRow } from '../appsync/appsync-client';
2
2
  import type { Session } from '../types';
3
3
  import type { LocalExecutor } from '../local-executor';
4
+ import type { ClassBInbound } from '../local-executor/types';
4
5
  import type { ImageAttachment } from './types';
5
6
  import { type ImplementorMode } from '../local-executor/implementor-argv';
6
7
  import { type FallbackLadderDeps } from '../substrate-launch/fallback-ladder';
@@ -9,8 +10,9 @@ import type { ConflictResolverContext } from '../local-executor/merge-conflict-r
9
10
  import type { AgentKind } from '../local-executor/types';
10
11
  import type { GateDispatchPayload, ReviewerDispatchPayload, ReviseFeedbackPayload } from '../local-executor/types';
11
12
  import type { TeamTrackFailureReason } from '../local-executor/task-group-types';
12
- import { WorkspaceShadow, type ShadowEnv } from '../local-executor/workspace-shadow';
13
+ import { WorkspaceShadow, type RecoveredShadow, type ShadowCleanupResidue, type ShadowEnv } from '../local-executor/workspace-shadow';
13
14
  import type { RevertManifestStore } from '../local-executor/durable-store';
15
+ import { captureWorkspaceRootAuthority } from '../local-executor/workspace-authority';
14
16
  import { type TeamExecution } from '../local-executor/team-execution-flag';
15
17
  import { type RenderedConflict, type TrackIntentDiff } from '../local-executor/wb2-review-bundle';
16
18
  import { ReviewerRegistry } from '../reviewer/registry';
@@ -322,12 +324,10 @@ export interface QuorumLoopDeps {
322
324
  * agent reviewer runs INSIDE the sandbox with no ambient vendor creds and a
323
325
  * broker-routed model call — closing the CP-14 §8/§13 reviewer-sandbox gap.
324
326
  * ABSENT (legacy / companion / tests) → reviewers take the legacy unsandboxed
325
- * path BYTE-IDENTICAL (§7 non-regression). Reviewer-sandboxing is ALSO gated
326
- * behind an opt-in env flag (`CODEVIBE_SANDBOX_REVIEWERS=1`, read in
327
- * `engageSeatSubstrate` on the `spawnOneSeat` path) that DEFAULTS OFF — so
328
- * even when this engager is wired,
329
- * reviewers stay on the legacy path until the broker round-trip is observed
330
- * green in a configured env (see `reviewerSandboxingEnabled`). The flag is
327
+ * path BYTE-IDENTICAL (§7 non-regression). Reviewer-sandboxing DEFAULTS ON
328
+ * when this engager is wired (R7 A4), with an operator opt-out env flag
329
+ * (`CODEVIBE_SANDBOX_REVIEWERS=0`, read in `engageSeatSubstrate` on the
330
+ * `spawnOneSeat` path — see `reviewerSandboxingEnabled`). The flag is
331
331
  * independent of implementor sandboxing (which has its own engager).
332
332
  */
333
333
  engageReviewerSubstrate?: ReviewerSubstrateEngager;
@@ -386,6 +386,22 @@ export interface QuorumLoopDeps {
386
386
  * production uses the defaults (`~/.codevibe/shadow-state`, `os.tmpdir()`).
387
387
  */
388
388
  shadowEnv?: ShadowEnv;
389
+ /**
390
+ * Deterministic recovery seams. Production omits this object and uses the
391
+ * imported filesystem implementations. Tests may park an exact recovery
392
+ * await to prove the session-disposal admission/drain boundary without
393
+ * weakening any production timeout or filesystem check.
394
+ */
395
+ shadowRecoveryOps?: {
396
+ listRecoverableShadows?: (env: ShadowEnv) => Promise<RecoveredShadow[]>;
397
+ listShadowCleanupResidue?: (taskIds: ReadonlySet<string>, env: ShadowEnv) => Promise<ShadowCleanupResidue[]>;
398
+ captureWorkspaceRootAuthority?: typeof captureWorkspaceRootAuthority;
399
+ reopenShadow?: (recovered: RecoveredShadow, env: ShadowEnv) => Promise<WorkspaceShadow | null>;
400
+ reapOrphanShadows?: (keepTaskIds: ReadonlySet<string>, env: ShadowEnv) => Promise<{
401
+ reaped: string[];
402
+ retained: string[];
403
+ }>;
404
+ };
389
405
  /**
390
406
  * CP-1.f execute-first (#EF-1 / #SR-2) — surface a user-visible halt /
391
407
  * fail-closed message to the orchestration timeline. Wired by the shell to an
@@ -463,8 +479,10 @@ export interface QuorumLoopDeps {
463
479
  *
464
480
  * SECURITY INVARIANT: events carry ONLY counts/labels/paths/elapsed — never
465
481
  * diff content, file contents, reviewer reasoning, prompts, or any decrypted
466
- * plaintext (the `TaskProgressEvent` union is the allowlist). The loop wraps
467
- * every emit so a throwing listener can NEVER break the loop.
482
+ * plaintext (the `TaskProgressEvent` union is the allowlist, with its ONE
483
+ * documented exception: `halt_notice.message`, controlled operational notice
484
+ * text from `surfaceHalt` — see task-progress.ts's header carve-out). The
485
+ * loop wraps every emit so a throwing listener can NEVER break the loop.
468
486
  */
469
487
  onProgress?: OnProgress;
470
488
  /**
@@ -516,6 +534,21 @@ declare function reviewerAgentToLeAgent(agent: ReviewerAgentKind): AgentKind;
516
534
  * leading token isn't a non-negative integer.
517
535
  */
518
536
  export declare function numericSeatId(resolvedSeatId: string): number | null;
537
+ interface TeamRunAuthority {
538
+ taskGroupId: string;
539
+ trackIndex: number;
540
+ dispatchGeneration: number;
541
+ }
542
+ /**
543
+ * Byte-equivalent to the engine's
544
+ * `round0_gate_id_for_track(task, group, track, generation)`.
545
+ *
546
+ * Live GateDispatch packets intentionally carry no mutable "current" pointer.
547
+ * Their deterministic id is the authenticated correlation between the signed
548
+ * TrackAssigned generation and the signed GateDispatch. Keeping the formula
549
+ * here closes packet-order races without extending or weakening the wire.
550
+ */
551
+ export declare function teamRound0GateId(taskId: string, taskGroupId: string, trackIndex: number, dispatchGeneration: number): string;
519
552
  export declare class QuorumLoop {
520
553
  private readonly deps;
521
554
  private readonly sleep;
@@ -585,6 +618,8 @@ export declare class QuorumLoop {
585
618
  * share a `trackIndex` overwrite each other's brief.
586
619
  */
587
620
  private teamBriefsByKey;
621
+ /** Recovery-authored briefs keyed by task/group/index/generation authority. */
622
+ private readonly recoveredBriefsByAuthority;
588
623
  private readonly activeBriefByTask;
589
624
  /**
590
625
  * CP-1.f revise-context fix (dogfood task 2ac68708, 2026-06-11) — the BINDING
@@ -674,6 +709,60 @@ export declare class QuorumLoop {
674
709
  * desktop suppression closes the late-LOCAL-submit race. Keyed by taskId.
675
710
  */
676
711
  private readonly activeImplementorByTask;
712
+ /** Spawn requests that own a shadow but have not yet returned a killable handle. */
713
+ private readonly pendingImplementorByTask;
714
+ /**
715
+ * Exact lifecycle ownership keyed by gate, including an older generation
716
+ * displaced from the per-task "current" maps above. Group halt and session
717
+ * teardown enumerate these registries so every real pending/active process
718
+ * remains abortable until its own round releases ownership.
719
+ */
720
+ private readonly activeImplementorByGate;
721
+ private readonly pendingImplementorByGate;
722
+ /**
723
+ * Full implementor-round coroutines owned by this session. Process handles
724
+ * cover only the agent subprocess; capture, validation, submission, and
725
+ * failure cleanup continue after that leader exits. Session teardown must
726
+ * await this set before deleting any workspace those continuations can use.
727
+ */
728
+ private readonly implementorRoundPromises;
729
+ /** Exact task ownership for group-local cancellation/drain (no unrelated wait). */
730
+ private readonly implementorRoundPromisesByTask;
731
+ /**
732
+ * Team GateDispatch callbacks admitted before their first await. Supersede,
733
+ * terminal group halt, and session teardown drain this exact registry before
734
+ * retiring snapshots, closing the pre-round ownership gap.
735
+ */
736
+ private readonly teamDispatchAdmissionsByTask;
737
+ /**
738
+ * Per-task registration tail. Every caller publishes its immutable gate /
739
+ * generation intent before joining this queue, so a successor gate received
740
+ * while an earlier registration drains is still correlated exactly.
741
+ */
742
+ private readonly teamTaskRegistrationByTask;
743
+ /** Exact deterministic gate authority, retained through retirement for stale replay refusal. */
744
+ private readonly teamGateBindingByRunId;
745
+ /** All queued/active registration intents, used to publish successor fences synchronously. */
746
+ private readonly teamRegistrationIntentsByTask;
747
+ /** Terminal group ids: set synchronously before any halt await or side effect. */
748
+ private readonly haltedTeamGroups;
749
+ /** Exact non-terminal generation fences retained after a newer dispatch wins. */
750
+ private readonly supersededTeamRuns;
751
+ /**
752
+ * Task ids whose old generation is being aborted/drained before its newer
753
+ * brief is installed. GateDispatch buffers behind this synchronous barrier.
754
+ */
755
+ private readonly supersedingTeamTaskIds;
756
+ /**
757
+ * Child task ids observed for a terminal group. GateDispatch carries only the
758
+ * child task id, so this closes the post-halt/no-brief replay path: after the
759
+ * brief is retired, a late dispatch is rejected instead of being buffered as
760
+ * an apparently early packet. A successful registration for a different,
761
+ * non-halted group clears the tombstone, which keeps task-id reuse safe.
762
+ */
763
+ private readonly haltedTeamTaskIds;
764
+ /** Serializes exact group bundle publication against the terminal halt fence. */
765
+ private readonly teamBundleOpsByGroup;
677
766
  /**
678
767
  * PHASE-CP-10-MIN (#585) §2.3 / #C10M-16 — offers already resumed (the
679
768
  * dedupe set; keyed on `offer_id`, the same axis as the audit slot #C10M-4).
@@ -724,6 +813,8 @@ export declare class QuorumLoop {
724
813
  * cardinality is bounded by those same dedup sets).
725
814
  */
726
815
  private readonly taskByGateId;
816
+ /** Exact immutable team generation that authored each team gate. */
817
+ private readonly teamAuthorityByGateId;
727
818
  /**
728
819
  * GATE_DISPATCH `gateRunId`s already consumed (idempotent re-delivery dedup).
729
820
  * A sweeper / WS re-deliver of the SAME round-0 dispatch must NOT double-spawn
@@ -747,18 +838,25 @@ export declare class QuorumLoop {
747
838
  */
748
839
  private readonly recoveredGateRunIds;
749
840
  /**
750
- * §4.1 — DURABLE per-track tombstone for a present-but-CORRUPT brief
841
+ * §4.1 — in-session per-authority tombstone for a present-but-CORRUPT brief
751
842
  * ciphertext (decrypt threw during recovery PASS 1). Blocks BOTH recovery
752
843
  * relaunch (PASS 2) AND any future LIVE `TrackAssigned`/drain for that track
753
844
  * (§4.3) — a corrupt brief must NEVER spawn an empty-brief implementor on
754
845
  * EITHER path. The track times out via the engine sweeper (bounded). Distinct
755
846
  * from a `null` `encryptedBrief` (a legit empty brief).
756
847
  *
757
- * CP-12 W4 (#593 Stage-2 r2): keyed by the COMPOSITE `teamBriefKey(taskGroupId,
758
- * trackIndex)`, NOT bare `trackIndex` — B.2 aggregates across groups, so a
759
- * tombstone on group A's track 0 must not block group B's (valid) track 0.
848
+ * Round 46: keyed by complete `(taskGroupId, trackIndex, taskId,
849
+ * dispatchGeneration)` authority, so a corrupt predecessor cannot block a
850
+ * clean successor that reuses the slot.
760
851
  */
761
852
  private readonly corruptBriefTracks;
853
+ /**
854
+ * The newest fully validated recovery authority seeded for each group/index
855
+ * slot. It prevents an asynchronously late, older recovery response (or stale
856
+ * live TrackAssigned) from replacing the brief selected for a newer
857
+ * generation. The actual tombstone remains keyed by the complete authority.
858
+ */
859
+ private readonly recoveryAuthorityBySlot;
762
860
  /**
763
861
  * #592 PROVENANCE GUARD (2026-06-26) — the task-group ids THIS desktop
764
862
  * ORIGINATED (recorded in `armB1Recovery`, right after a successful
@@ -775,11 +873,12 @@ export declare class QuorumLoop {
775
873
  */
776
874
  private readonly ownedGroupIds;
777
875
  /**
778
- * CP-12 W4 (#593 Stage-2 r2) — the composite key for `teamBriefsByKey` +
779
- * `corruptBriefTracks`. `(taskGroupId, trackIndex)` so two in-flight groups
780
- * that share a `trackIndex` (B.2 aggregates session-wide) never collide.
876
+ * Slot key for parse-time briefs and the selected recovery projection.
877
+ * Deletion/launch authority never uses this key alone.
781
878
  */
782
879
  private teamBriefKey;
880
+ private recoveryAuthorityKey;
881
+ private isCorruptBriefAuthority;
783
882
  /**
784
883
  * PHASE-589/469 W3.1 (C1) — the GROUP-WIDE monotonic promote-order counter,
785
884
  * keyed by `taskGroupId`. Each team track promote reserves
@@ -864,6 +963,33 @@ export declare class QuorumLoop {
864
963
  * This also makes concurrent B.1+B.2 safe (no per-op toggle race).
865
964
  */
866
965
  private recoverySeedingDepth;
966
+ /**
967
+ * Recovery B.1 and B.2 can overlap. A per-call two-row batch is therefore
968
+ * insufficient: two concurrent calls could each launch two implementors.
969
+ * These permits are owned by the QuorumLoop/session and cover the complete
970
+ * `launchRecoveredTrack` operation across every recovery entry path.
971
+ */
972
+ private activeRecoveryRelaunches;
973
+ private readonly recoveryRelaunchWaiters;
974
+ /**
975
+ * Every asynchronously delivered session coroutine that can reach a task
976
+ * workspace: Class-B consumption, shadow recovery, and B.1/B.2 team
977
+ * recovery. Admission is synchronous and closes when `shuttingDown` flips.
978
+ * Disposal drains this set before it enumerates task resources, so no
979
+ * accepted callback can mutate a map or filesystem after the boundary.
980
+ */
981
+ private readonly sessionWorkPromises;
982
+ private readonly sessionWorkAdmissions;
983
+ /** TaskAuthorized callbacks accepted before shutdown may finish promotion. */
984
+ private readonly terminalClassBAdmissionsByTask;
985
+ private trackExistingSessionWork;
986
+ private startSessionWork;
987
+ private admittedSessionWorkMayContinue;
988
+ private trackTeamRecovery;
989
+ private acquireRecoveryRelaunchPermit;
990
+ private releaseRecoveryRelaunchPermit;
991
+ private cancelRecoveryRelaunchWaiters;
992
+ private withRecoveryRelaunchPermit;
867
993
  /**
868
994
  * §4.3 — TEAM Class B packets buffered while the recovery seed barrier is up
869
995
  * (`recoverySeedingDepth > 0`). Drained through the normal live handlers AFTER
@@ -927,25 +1053,28 @@ export declare class QuorumLoop {
927
1053
  */
928
1054
  private readonly shadowsByTask;
929
1055
  /**
930
- * PHASE-598 (Codex impl-r5 / LOCK #598-11) — the REVIEWED diff snapshot per TEAM
931
- * task, stored when a round's gate goes live (reviewers dispatched). `promoteShadow`
932
- * fails-closed if the live shadow drifts from it before promote — the airtight
933
- * backstop for a declared test that spawns a DETACHED writer (the test runner waits
934
- * only on the direct child, so such a writer can mutate the shadow AFTER the
935
- * post-test re-capture passes but BEFORE promote). Presence ⇔ team task: single-impl
936
- * never stores, so its promote path is unchanged. Cleared on promote/discard.
1056
+ * Session-sticky task ids whose snapshots this loop may retire. The set does
1057
+ * not shrink when an in-memory map entry is cleared: normal teardown performs
1058
+ * a fresh durable enumeration and must still recognize an interrupted exact
1059
+ * marker. It also prevents one embedded shell from adopting another shell's
1060
+ * same-workspace snapshot merely because both share a state root.
1061
+ */
1062
+ private readonly workspaceTaskIdsOwned;
1063
+ /**
1064
+ * In-session terminal retirement tombstones. A recovery scan that started
1065
+ * before a terminal discard/promote must not reinstall its stale instance
1066
+ * after that terminal operation wins the task mutex.
1067
+ */
1068
+ private readonly terminallyRetiredWorkspaceTasks;
1069
+ /**
1070
+ * In-memory cache of the crash-durable reviewed artifact for every task. The
1071
+ * authoritative copy lives in the private snapshot marker and is persisted
1072
+ * before submission; promotion always re-reads that copy. Cleared with the
1073
+ * instance on promote/discard.
937
1074
  */
938
1075
  private readonly reviewedSnapshotByTask;
939
1076
  /** Guards concurrent shadow-create for the same task (round-0 + an early re-deliver). */
940
1077
  private readonly shadowCreateInFlight;
941
- /**
942
- * CP-14 Wave A — the ONE pinned base SHA per task group (`worktree_merge`),
943
- * captured (memoized) at the first track of the group BEFORE any shadow is
944
- * created, so EVERY track branches from the same base → a deterministic
945
- * merge-train input (Stage-1 plan-review MED-3). Promise-memoized so concurrent
946
- * track registrations share a single `git rev-parse HEAD`.
947
- */
948
- private readonly groupBaseShaInFlight;
949
1078
  /**
950
1079
  * Per-task async MUTEX for shadow LIFECYCLE mutations (restart-race fix,
951
1080
  * 2026-06-11 Stage-2 Codex r2). A promise-chain serializes EVERY map/stateDir-
@@ -962,10 +1091,12 @@ export declare class QuorumLoop {
962
1091
  * sequencing layer (errors propagate to the OWNING caller, never poison the
963
1092
  * chain for the next op), and clears the entry once the tail it stored is the
964
1093
  * one that settled (so an idle task leaks no entry). The serialized region is
965
- * fs/git-only with NO nested `runExclusiveShadowOp` call (the wrapped methods
1094
+ * filesystem-only with NO nested `runExclusiveShadowOp` call (the wrapped methods
966
1095
  * never call each other), so it cannot self-deadlock.
967
1096
  */
968
1097
  private readonly shadowOpsByTask;
1098
+ /** Once set, no new implementor workspace may be created for this session. */
1099
+ private shuttingDown;
969
1100
  /**
970
1101
  * Serialize one shadow lifecycle op for `taskId` behind any in-flight op for
971
1102
  * the same task. The op's result/rejection is returned to ITS caller; a
@@ -974,6 +1105,30 @@ export declare class QuorumLoop {
974
1105
  * appended is still the current tail (no later op queued behind us).
975
1106
  */
976
1107
  private runExclusiveShadowOp;
1108
+ private static sameTeamAuthority;
1109
+ private static teamAuthorityKey;
1110
+ private static teamAuthorityForEntry;
1111
+ private static immutableTeamTaskEntry;
1112
+ private static sameTeamTaskEntry;
1113
+ private publishTeamRegistrationIntent;
1114
+ private releaseTeamRegistrationIntent;
1115
+ private refreshTeamSupersedingFence;
1116
+ private hasQueuedNewerTeamRegistration;
1117
+ private retireTeamGateBindings;
1118
+ private teamAuthorityForTask;
1119
+ private teamRunIsHalted;
1120
+ private teamEntryMayContinue;
1121
+ private admitTeamDispatch;
1122
+ private drainTeamDispatchAdmissions;
1123
+ private runTeamBundlePublication;
1124
+ /**
1125
+ * Retire one older team dispatch generation before installing its successor.
1126
+ * The exact authority fence is published synchronously, then every pending /
1127
+ * active real handle and the complete round continuation is drained. The old
1128
+ * snapshot is removed only after process ownership is proven empty.
1129
+ */
1130
+ private retireSupersededTeamRun;
1131
+ private rememberWorkspaceLifecycleFailure;
977
1132
  /**
978
1133
  * The last terminal workspace outcome (promote / discard) this loop applied,
979
1134
  * for the `summarize_current_status` shell answer (Fix 2). RELATIVE file paths
@@ -1048,6 +1203,15 @@ export declare class QuorumLoop {
1048
1203
  } | {
1049
1204
  kind: 'discarded';
1050
1205
  } | null;
1206
+ /**
1207
+ * Session-owned Class-B ingress. The subscription calls this wrapper instead
1208
+ * of invoking the LocalExecutor directly, making delivery admission atomic
1209
+ * with the teardown fence. A packet accepted before shutdown is drained;
1210
+ * packets delivered after shutdown are ignored before verification or side
1211
+ * effects. TaskAuthorized gets a narrow terminal admission so its already-
1212
+ * delivered promote can finish before disposal enumerates the task.
1213
+ */
1214
+ consumeClassB(packet: ClassBInbound, envelopeTaskId?: string): Promise<void>;
1051
1215
  /** The DI callbacks the shell wires into its ClassBConsumer. */
1052
1216
  classBConsumerDeps(): {
1053
1217
  classBSignatureVerifier: (packet: import('../local-executor/types').ClassBInbound) => Promise<boolean>;
@@ -1144,14 +1308,15 @@ export declare class QuorumLoop {
1144
1308
  */
1145
1309
  setTeamAttachments(taskGroupId: string, attachments: ImageAttachment[]): void;
1146
1310
  /**
1147
- * CP-12 W2.b (§3.C.3) — read the brief for `(taskGroupId, trackIndex)`. The
1311
+ * CP-12 W2.b (§3.C.3) — read the brief for a team track. The
1148
1312
  * `registerTeamTask` bridge (wired in the shell) reads this when `TrackAssigned`
1149
1313
  * correlates a track to its child `task_id`; recovery PASS 2 reads it for a
1150
1314
  * relaunched track. Empty string when the user issued no `description` for the
1151
1315
  * track (a track with no brief runs an empty-brief round-0; the engine's #EF-1
1152
- * born-halt surfaces it). Composite-keyed (#593 Stage-2 r2) — see `teamBriefKey`.
1316
+ * born-halt surfaces it). Recovery callers pass task/generation so the
1317
+ * complete-authority store is consulted; two-argument calls are diagnostic.
1153
1318
  */
1154
- getTeamBrief(taskGroupId: string, trackIndex: number): string;
1319
+ getTeamBrief(taskGroupId: string, trackIndex: number, taskId?: string, dispatchGeneration?: number): string;
1155
1320
  /**
1156
1321
  * CP-12 W2.b (§3.C.3 / M5) — the brief→task_id bridge. `launchTrack` calls this
1157
1322
  * at `TrackAssigned` (the FIRST surface carrying both `track_index` AND the
@@ -1168,10 +1333,19 @@ export declare class QuorumLoop {
1168
1333
  agent: AgentKind;
1169
1334
  taskGroupId: string;
1170
1335
  trackIndex: number;
1336
+ /** Optional only for direct legacy test/recovery callers. */
1337
+ dispatchGeneration?: number;
1338
+ /**
1339
+ * Recovery/direct-call correlation when the caller already has the
1340
+ * engine gate id. Live TrackAssigned callers omit it and use the exact
1341
+ * deterministic engine formula.
1342
+ */
1343
+ gateRunId?: string;
1171
1344
  writePaths: string[];
1172
1345
  autoModifiedFiles: string[];
1173
1346
  testSurfaces: string[];
1174
- }): Promise<void>;
1347
+ }): Promise<'accepted' | 'refused'>;
1348
+ private registerTeamTaskBriefOwned;
1175
1349
  /**
1176
1350
  * CP-12 W2.b (§3.C.2) — the TEAM analogue of the single-impl round-0 spawn.
1177
1351
  * Routes by the OUTER envelope's `task_id` (the payload has none): resolves
@@ -1203,19 +1377,11 @@ export declare class QuorumLoop {
1203
1377
  private replaceShadowForRound0Locked;
1204
1378
  /**
1205
1379
  * CP-14 P1 — the team execution model this session SIGNALS on
1206
- * `createTaskGroup` (`executionModel`). Always `worktree_merge` since the
1207
- * §10 retirement (2026-07-03): overlapping-track dispatch with the
1208
- * merge-train + the server contract gate as the authority.
1380
+ * `createTaskGroup` (`executionModel`). `worktree_merge` is retained as the
1381
+ * wire label; locally it means reviewed bundles integrated in a disposable
1382
+ * filesystem snapshot, with no Git requirement.
1209
1383
  */
1210
1384
  teamExecutionModel(): TeamExecution;
1211
- /**
1212
- * CP-14 Wave A — the ONE pinned group base SHA (memoized): `git rev-parse HEAD`
1213
- * in the workspace, captured at the FIRST track of the group, BEFORE any track
1214
- * shadow/branch is created, so every track roots at the same base (Stage-1
1215
- * MED-3). Concurrent callers share one rev-parse via the in-flight promise.
1216
- * Throws if HEAD can't be resolved (a non-git workspace is ineligible upstream).
1217
- */
1218
- private ensureGroupBaseSha;
1219
1385
  /**
1220
1386
  * CP-1.f execute-first (§4) — ensure the per-task SHADOW exists, creating it
1221
1387
  * BEFORE the round-0 spawn. Idempotent: round-0 + an early GATE_DISPATCH
@@ -1245,6 +1411,8 @@ export declare class QuorumLoop {
1245
1411
  agent: AgentKind;
1246
1412
  sessionKey: string;
1247
1413
  mode?: ImplementorMode;
1414
+ /** Immutable team-generation authority captured at packet admission. */
1415
+ teamAuthority?: TeamRunAuthority;
1248
1416
  /**
1249
1417
  * CP-12 W2.b (§3.C.2b option a / H3) — TEAM only. After `captureDiff` and
1250
1418
  * BEFORE submit, validate every changed file against the track's declared
@@ -1273,6 +1441,7 @@ export declare class QuorumLoop {
1273
1441
  text: string;
1274
1442
  };
1275
1443
  }): Promise<void>;
1444
+ private runImplementorRoundOwned;
1276
1445
  /**
1277
1446
  * Extract the agent's informational stdout summary (audit-only; reviewers
1278
1447
  * never see it — they review the captured diff). Best-effort: a failure to
@@ -1290,7 +1459,7 @@ export declare class QuorumLoop {
1290
1459
  * Gemini/Antigravity are out of scope (undefined). NEVER throws — a read/parse
1291
1460
  * failure yields `undefined` (segment simply omitted), never breaks the round.
1292
1461
  */
1293
- private extractImplementorTokens;
1462
+ private extractImplementorUsage;
1294
1463
  /**
1295
1464
  * PHASE-589/469 W1+W2 (LOCK #589-E/F/H) — on a TEAM track local hard-fail (any
1296
1465
  * of the 4 closed reasons: `verification_failure` / `out_of_scope_write` /
@@ -1372,6 +1541,50 @@ export declare class QuorumLoop {
1372
1541
  * `TaskGroupHalted` convergence is the authoritative group resolution).
1373
1542
  */
1374
1543
  reportTeamTrackUserResolved(taskId: string, postAction: PostDecisionAction): void;
1544
+ /**
1545
+ * H3 / Option B (#657) — emit the POSITIVE cancel-confirmation milestone on the
1546
+ * final-approval CANCEL path. Final-approval "Do not apply. Leave the task in its
1547
+ * current state" RETAINS the shadow and mutates nothing, so it triggers NEITHER
1548
+ * the promote (`promoted`) NOR the discard (`discarded`) milestone — the decision
1549
+ * was previously SILENT in non-TTY (a canceling user got no confirmation, and the
1550
+ * E2E harness had no positive signal to assert, so an unwired/hung Cancel was
1551
+ * indistinguishable from a correct one). This emits `not_applied` ("Not applied —
1552
+ * your tree is unchanged") so the user AND the harness get a positive terminal
1553
+ * that the Cancel actually resolved.
1554
+ *
1555
+ * SELF-GUARDING single source of truth: fires ONLY for a `final_approval_resolved`
1556
+ * postAction whose `decision` is NOT `approve` (Approve promotes via the
1557
+ * TaskAuthorized edge → `promoted`; Abort/Reject-restart discard → `discarded`; an
1558
+ * `open_new_round`/`continuation_switch_*` postAction keeps working, no terminal).
1559
+ * Reuses the SAME `approve`-vs-else discriminator the engine's
1560
+ * `handle_final_approval` + `postActionTeamTrackState` use
1561
+ * (`decision.trim().toLowerCase()`), so it can never diverge from the
1562
+ * Passed/Failed track classification.
1563
+ *
1564
+ * Fires for BOTH single-impl and team tracks (unlike the team-only
1565
+ * `reportTeamTrackUserResolved`) — every Cancel deserves the confirmation. Called
1566
+ * by the shell's `onTerminalDecision` (the shared TTY + non-TTY gate-resolution
1567
+ * chokepoint) after a successful `applyUserDecision`. `emitProgress` already wraps
1568
+ * the listener so a throwing consumer can NEVER break the decision path. NO
1569
+ * wire/schema change (progress is desktop-LOCAL) — `not_applied` carries ONLY the
1570
+ * taskId (SECURITY INVARIANT: no user content, mirrors `discarded`).
1571
+ */
1572
+ reportFinalApprovalCancelled(taskId: string, postAction: PostDecisionAction): void;
1573
+ /**
1574
+ * Authoritative TaskGroupHalted bridge from LocalExecutor. Calling this async
1575
+ * method publishes the terminal group fence synchronously (before its first
1576
+ * await), then stops the actual QuorumLoop-owned pending/active implementors,
1577
+ * drains their complete round coroutines and bundle publications, and retires
1578
+ * every exact snapshot for the halted generation.
1579
+ */
1580
+ haltTeamTaskGroup(input: {
1581
+ taskGroupId: string;
1582
+ members: readonly {
1583
+ taskId: string;
1584
+ trackIndex: number;
1585
+ dispatchGeneration: number;
1586
+ }[];
1587
+ }): Promise<void>;
1375
1588
  /**
1376
1589
  * CP-1.f execute-first — discard the task's shadow (a non-TaskAuthorized
1377
1590
  * terminal). Best-effort: a teardown failure is logged + leaves the durable
@@ -1420,6 +1633,18 @@ export declare class QuorumLoop {
1420
1633
  * process end — an accepted, documented residual.
1421
1634
  */
1422
1635
  preserveReviseContext?: boolean;
1636
+ /**
1637
+ * P10 E3 r4 (Stage-1 r4 M-1) — set by `onTerminalDecision` for the
1638
+ * `restart_proposal` discard ONLY: the restart reuses the SAME taskId
1639
+ * and runs a fresh round-0, so the `discarded` closer must NOT carry
1640
+ * the taskId (a stamped closer would flip the session-listing record
1641
+ * to 'cancelled' and the M3 no-resurrect guard would lock it there —
1642
+ * even after the restarted task promotes). Deliberately does NOT touch
1643
+ * the revise-context clear or `terminallyRetiredWorkspaceTasks` — a
1644
+ * restart is a fresh round-0 (context cleared as before); ONLY the
1645
+ * listing stamp is suppressed.
1646
+ */
1647
+ taskContinues?: boolean;
1423
1648
  }): Promise<void>;
1424
1649
  private discardShadowLocked;
1425
1650
  /**
@@ -1561,9 +1786,8 @@ export declare class QuorumLoop {
1561
1786
  * path (that defeats the moat).
1562
1787
  *
1563
1788
  * TRI-STATE (decided here, mirroring the implementor LE):
1564
- * 1. No engager wired OR `CODEVIBE_SANDBOX_REVIEWERS` not opted in (DEFAULT
1565
- * OFF; opt in with `=1`/`=true`) → LEGACY (byte-identical non-regression).
1566
- * No badge.
1789
+ * 1. No engager wired OR `CODEVIBE_SANDBOX_REVIEWERS=0` opted out (the gate
1790
+ * DEFAULTS ON — R7 A4) → LEGACY (byte-identical non-regression). No badge.
1567
1791
  * 1b. No resolvable taskId (cannot scope a per-task broker) → LEGACY + a
1568
1792
  * reduced-trust badge (Stage-2 r1 Codex LOW — a trust-downgrade must be
1569
1793
  * VISIBLE, never a silent ambient-cred fallback; see
@@ -1596,8 +1820,8 @@ export declare class QuorumLoop {
1596
1820
  private surfaceReviewerReducedTrust;
1597
1821
  /**
1598
1822
  * Wave B §2.1 confinement TRI-STATE for a merge-gate model/reviewer invocation
1599
- * (LOCK #C14-MOAT). Path A: the CP-7 substrate/broker (opted in + a Trusted agent
1600
- * + engage succeeds → a handle; no ambient vendor cred in the child). Path B: a
1823
+ * (LOCK #C14-MOAT). Path A: the CP-7 substrate/broker (not opted out + a Trusted
1824
+ * agent + engage succeeds → a handle; no ambient vendor cred in the child). Path B: a
1601
1825
  * trusted-container boundary (legacy spawn confined by the OUTER container — the
1602
1826
  * dogfood/E2E path). Path C: neither → NOT confined. A path-A engage that
1603
1827
  * throws/reduced-trusts falls through to B/C (both safe: B confined, C refuses),
@@ -1641,8 +1865,9 @@ export declare class QuorumLoop {
1641
1865
  * converting it into a per-slot spawn-time fail-close.
1642
1866
  *
1643
1867
  * Deliberately DECOUPLED from `engageWaveBConfinement` and its
1644
- * `CODEVIBE_SANDBOX_REVIEWERS` opt-in: that flag gates REVIEWER sandboxing
1645
- * (per-seat, `makeConflictModelCaller`, Tier-2) exactly as before — riding
1868
+ * `CODEVIBE_SANDBOX_REVIEWERS` gate (default-ON, `=0` opts out — R7 A4):
1869
+ * that flag gates REVIEWER sandboxing (per-seat, `makeConflictModelCaller`,
1870
+ * Tier-2) exactly as before — riding
1646
1871
  * it here made the A1d resolver row unreachable on the default bare host.
1647
1872
  * The ladder select is side-effect-free (no launch, no broker); test seams
1648
1873
  * via `deps.resolverProbeDeps`.
@@ -1660,7 +1885,8 @@ export declare class QuorumLoop {
1660
1885
  * DISPATCH-time engage could establish a confining substrate on this
1661
1886
  * host (a real §6 Q2 ladder tier, or the preserved trusted-container
1662
1887
  * posture). Deliberately DECOUPLED from `engageWaveBConfinement`'s
1663
- * `CODEVIBE_SANDBOX_REVIEWERS` opt-in — that flag gates REVIEWER
1888
+ * `CODEVIBE_SANDBOX_REVIEWERS` gate (default-ON post-R7-A4) — that flag
1889
+ * gates REVIEWER
1664
1890
  * sandboxing (seat/`makeConflictModelCaller`/Tier-2, unchanged), and
1665
1891
  * riding it here made the A1d write-confined resolver row unreachable
1666
1892
  * on the default bare-host path. Unwired → return `null` →
@@ -1760,6 +1986,26 @@ export declare class QuorumLoop {
1760
1986
  * re-delivered packet (or the next live edge) promotes it.
1761
1987
  */
1762
1988
  recoverShadows(): Promise<void>;
1989
+ private recoverShadowsOwned;
1990
+ /**
1991
+ * Session-exit ownership boundary. Stop future creates, wait behind every
1992
+ * in-flight per-task lifecycle operation, then synchronously reclaim each
1993
+ * live snapshot. Startup TTL cleanup remains only the SIGKILL/power-loss
1994
+ * fallback, not normal lifecycle management.
1995
+ */
1996
+ private reconcileUnresolvedBundleRetention;
1997
+ private retireExactShadow;
1998
+ /**
1999
+ * Strict, exhaustive cleanup for task ids this loop owns. It first attempts
2000
+ * every mapped exact instance, then performs a fresh authenticated marker
2001
+ * enumeration and reopens/retire any same-task instance absent from memory.
2002
+ * A final fresh enumeration is the convergence proof. Live foreign owners and
2003
+ * unresolved authority are preserved, but returned as explicit failures.
2004
+ */
2005
+ private cleanupOwnedTaskSnapshots;
2006
+ disposeWorkspaces(opts?: {
2007
+ strict?: boolean;
2008
+ }): Promise<void>;
1763
2009
  /**
1764
2010
  * §4.3 — true while a team recovery is seeding briefs (the startup barrier is
1765
2011
  * down). The Class B consume path checks this to BUFFER a live TEAM packet
@@ -1769,17 +2015,18 @@ export declare class QuorumLoop {
1769
2015
  */
1770
2016
  isRecoverySeeding(): boolean;
1771
2017
  /**
1772
- * §4.3 (Stage-2 r1 Codex MED) — true if `(taskGroupId, trackIndex)` carries a
1773
- * corrupt-brief TOMBSTONE. The LE consults this at the TOP of `launchTrack`
2018
+ * §4.3 (Stage-2 r1 Codex MED) — true if the complete team generation carries
2019
+ * a corrupt tombstone or is stale relative to recovered authority. The LE
2020
+ * consults this at the TOP of `launchTrack`
1774
2021
  * (before any register / spawn / lease-renewing progress emit) so a tombstoned
1775
2022
  * track is refused on the LIVE path as early as on the recovery path — never
1776
2023
  * spawning an empty-brief implementor or mutating registry state for it. The
1777
2024
  * engine sweeper times the un-launched track out (bounded).
1778
2025
  *
1779
- * CP-12 W4 (#593 Stage-2 r2): keyed by `(taskGroupId, trackIndex)` so a corrupt
1780
- * brief in group A never blocks a different group B's track with the same index.
2026
+ * Production supplies taskId + dispatchGeneration. The optional form remains
2027
+ * only for backward-compatible diagnostics/tests.
1781
2028
  */
1782
- isTrackTombstoned(taskGroupId: string, trackIndex: number): boolean;
2029
+ isTrackTombstoned(taskGroupId: string, trackIndex: number, taskId?: string, dispatchGeneration?: number): boolean;
1783
2030
  /**
1784
2031
  * #592 PROVENANCE GUARD (live path) — true if `taskGroupId` is a team group this
1785
2032
  * desktop did NOT originate AND this desktop owns ≥1 group. Wired to the LE's
@@ -1883,6 +2130,8 @@ export declare class QuorumLoop {
1883
2130
  * so this method just seeds + relaunches (it is always invoked under a barrier
1884
2131
  * that is already down, and may run multiple times within one barrier window).
1885
2132
  */
2133
+ private normalizeTeamRecoveryRow;
2134
+ private normalizeTeamRecoveryRows;
1886
2135
  recoverTeamTracks(rows: TeamTrackRecoveryRow[]): Promise<void>;
1887
2136
  /**
1888
2137
  * §4.1 PASS 2 (one row) — validate → recoverLaunchTrack → repair-on-duplicate →
@@ -2047,6 +2296,7 @@ export declare class QuorumLoop {
2047
2296
  decision: string;
2048
2297
  action: PostDecisionAction;
2049
2298
  }): Promise<void>;
2299
+ private onApplyUserDecisionEchoOwned;
2050
2300
  /**
2051
2301
  * #585 §3.5 / #C10M-11/13 — resume the task with the user's chosen agent.
2052
2302
  * The SERVER has ALREADY minted the `nextGateId` row + advanced to
@@ -2063,6 +2313,7 @@ export declare class QuorumLoop {
2063
2313
  resumeFromContinuation(input: {
2064
2314
  taskId: string;
2065
2315
  targetAgent: AgentKind;
2316
+ sourceGateId?: string;
2066
2317
  nextGateId: string;
2067
2318
  nextRound: number;
2068
2319
  }): Promise<boolean>;
@@ -6,3 +6,12 @@ export declare const CONVERSATION_BUFFER_MAX = 500;
6
6
  * mutates `state` in place. Map fields are cloned via `new Map(state.x)`.
7
7
  */
8
8
  export declare function reducer(state: OrchestrationState, action: OrchestrationAction): OrchestrationState;
9
+ /**
10
+ * P10 E3 r6/r8 — "is a single-implementor task actually running?" from the
11
+ * TRUTHFUL `sessionTasks` lifecycle (the task-end closers terminalize it;
12
+ * `runningTasks` never terminalizes in production and is kept ONLY for the
13
+ * decision-spawned-a-task size heuristic). Shared by the `/status` running
14
+ * line, `deriveCurrentTaskState` (the planner packet), and the reviewer-line
15
+ * SET guard below.
16
+ */
17
+ export declare function hasRunningSingleTask(state: OrchestrationState): boolean;