wicked-crew 0.7.29 → 0.7.31

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 (152) hide show
  1. package/README.md +4 -1
  2. package/dist/api/chat-scope.d.ts +15 -2
  3. package/dist/api/chat-scope.d.ts.map +1 -1
  4. package/dist/api/chat-scope.js +12 -3
  5. package/dist/api/chat-scope.js.map +1 -1
  6. package/dist/api/eval-sample.d.ts +12 -12
  7. package/dist/api/governance-health.d.ts +25 -17
  8. package/dist/api/governance-health.d.ts.map +1 -1
  9. package/dist/api/governance-health.js +40 -9
  10. package/dist/api/governance-health.js.map +1 -1
  11. package/dist/api/routes.d.ts +32 -0
  12. package/dist/api/routes.d.ts.map +1 -1
  13. package/dist/api/routes.js +315 -67
  14. package/dist/api/routes.js.map +1 -1
  15. package/dist/api/run-files.d.ts +26 -0
  16. package/dist/api/run-files.d.ts.map +1 -1
  17. package/dist/api/run-files.js +78 -0
  18. package/dist/api/run-files.js.map +1 -1
  19. package/dist/api/seat-health.d.ts +71 -0
  20. package/dist/api/seat-health.d.ts.map +1 -1
  21. package/dist/api/seat-health.js +148 -1
  22. package/dist/api/seat-health.js.map +1 -1
  23. package/dist/api/seat-signin.d.ts +8 -0
  24. package/dist/api/seat-signin.d.ts.map +1 -1
  25. package/dist/api/seat-signin.js +48 -3
  26. package/dist/api/seat-signin.js.map +1 -1
  27. package/dist/api/seat-standing.d.ts +113 -0
  28. package/dist/api/seat-standing.d.ts.map +1 -0
  29. package/dist/api/seat-standing.js +148 -0
  30. package/dist/api/seat-standing.js.map +1 -0
  31. package/dist/api/server.d.ts.map +1 -1
  32. package/dist/api/server.js +58 -4
  33. package/dist/api/server.js.map +1 -1
  34. package/dist/api/skills.d.ts +2 -2
  35. package/dist/api/testing.d.ts +28 -1
  36. package/dist/api/testing.d.ts.map +1 -1
  37. package/dist/api/testing.js +190 -0
  38. package/dist/api/testing.js.map +1 -1
  39. package/dist/campaigns/rollup.d.ts +4 -0
  40. package/dist/campaigns/rollup.d.ts.map +1 -1
  41. package/dist/campaigns/rollup.js.map +1 -1
  42. package/dist/campaigns/routes.d.ts +3 -1
  43. package/dist/campaigns/routes.d.ts.map +1 -1
  44. package/dist/campaigns/routes.js +3 -0
  45. package/dist/campaigns/routes.js.map +1 -1
  46. package/dist/cli/index.js +37 -5
  47. package/dist/cli/index.js.map +1 -1
  48. package/dist/core/adapter.d.ts +10 -0
  49. package/dist/core/adapter.d.ts.map +1 -1
  50. package/dist/core/adapter.js +49 -3
  51. package/dist/core/adapter.js.map +1 -1
  52. package/dist/core/bridge-path.d.ts +21 -0
  53. package/dist/core/bridge-path.d.ts.map +1 -1
  54. package/dist/core/bridge-path.js +37 -0
  55. package/dist/core/bridge-path.js.map +1 -1
  56. package/dist/core/bridge-reaper.d.ts.map +1 -1
  57. package/dist/core/bridge-reaper.js +7 -3
  58. package/dist/core/bridge-reaper.js.map +1 -1
  59. package/dist/core/deliver-text.d.ts +7 -0
  60. package/dist/core/deliver-text.d.ts.map +1 -1
  61. package/dist/core/deliver-text.js +41 -2
  62. package/dist/core/deliver-text.js.map +1 -1
  63. package/dist/core/engine-roster.d.ts +68 -0
  64. package/dist/core/engine-roster.d.ts.map +1 -0
  65. package/dist/core/engine-roster.js +156 -0
  66. package/dist/core/engine-roster.js.map +1 -0
  67. package/dist/core/governance-store.d.ts +22 -0
  68. package/dist/core/governance-store.d.ts.map +1 -1
  69. package/dist/core/governance-store.js +7 -0
  70. package/dist/core/governance-store.js.map +1 -1
  71. package/dist/interactive/bridge-pool.d.ts +29 -24
  72. package/dist/interactive/bridge-pool.d.ts.map +1 -1
  73. package/dist/interactive/bridge-pool.js +65 -3
  74. package/dist/interactive/bridge-pool.js.map +1 -1
  75. package/dist/interactive/chat-events.d.ts.map +1 -1
  76. package/dist/interactive/chat-events.js +30 -5
  77. package/dist/interactive/chat-events.js.map +1 -1
  78. package/dist/interactive/council-outcome.d.ts +55 -0
  79. package/dist/interactive/council-outcome.d.ts.map +1 -0
  80. package/dist/interactive/council-outcome.js +107 -0
  81. package/dist/interactive/council-outcome.js.map +1 -0
  82. package/dist/interactive/demo-events.d.ts.map +1 -1
  83. package/dist/interactive/demo-events.js +30 -5
  84. package/dist/interactive/demo-events.js.map +1 -1
  85. package/dist/interactive/doc-delete-routes.d.ts.map +1 -1
  86. package/dist/interactive/doc-delete-routes.js +3 -2
  87. package/dist/interactive/doc-delete-routes.js.map +1 -1
  88. package/dist/interactive/doc-run-index.d.ts +56 -0
  89. package/dist/interactive/doc-run-index.d.ts.map +1 -0
  90. package/dist/interactive/doc-run-index.js +100 -0
  91. package/dist/interactive/doc-run-index.js.map +1 -0
  92. package/dist/interactive/docs-index.d.ts +68 -0
  93. package/dist/interactive/docs-index.d.ts.map +1 -0
  94. package/dist/interactive/docs-index.js +114 -0
  95. package/dist/interactive/docs-index.js.map +1 -0
  96. package/dist/interactive/draft-events.d.ts +18 -0
  97. package/dist/interactive/draft-events.d.ts.map +1 -1
  98. package/dist/interactive/draft-events.js +40 -4
  99. package/dist/interactive/draft-events.js.map +1 -1
  100. package/dist/interactive/edit-events.d.ts.map +1 -1
  101. package/dist/interactive/edit-events.js +30 -5
  102. package/dist/interactive/edit-events.js.map +1 -1
  103. package/dist/interactive/ledger.d.ts +2 -0
  104. package/dist/interactive/ledger.d.ts.map +1 -1
  105. package/dist/interactive/ledger.js +4 -0
  106. package/dist/interactive/ledger.js.map +1 -1
  107. package/dist/projects/auto-refresh.d.ts +54 -0
  108. package/dist/projects/auto-refresh.d.ts.map +1 -0
  109. package/dist/projects/auto-refresh.js +76 -0
  110. package/dist/projects/auto-refresh.js.map +1 -0
  111. package/dist/projects/graph.d.ts +15 -2
  112. package/dist/projects/graph.d.ts.map +1 -1
  113. package/dist/projects/graph.js +18 -8
  114. package/dist/projects/graph.js.map +1 -1
  115. package/dist/projects/routes.d.ts.map +1 -1
  116. package/dist/projects/routes.js +12 -2
  117. package/dist/projects/routes.js.map +1 -1
  118. package/dist/projects/state-home.d.ts +6 -0
  119. package/dist/projects/state-home.d.ts.map +1 -1
  120. package/dist/projects/state-home.js +9 -1
  121. package/dist/projects/state-home.js.map +1 -1
  122. package/dist/qe/author-workflow.d.ts +165 -0
  123. package/dist/qe/author-workflow.d.ts.map +1 -0
  124. package/dist/qe/author-workflow.js +377 -0
  125. package/dist/qe/author-workflow.js.map +1 -0
  126. package/dist/qe/test-sets.d.ts +112 -0
  127. package/dist/qe/test-sets.d.ts.map +1 -0
  128. package/dist/qe/test-sets.js +170 -0
  129. package/dist/qe/test-sets.js.map +1 -0
  130. package/dist/skills/guards.d.ts +17 -6
  131. package/dist/skills/guards.d.ts.map +1 -1
  132. package/dist/skills/guards.js +42 -15
  133. package/dist/skills/guards.js.map +1 -1
  134. package/dist/skills/refs.d.ts +218 -17
  135. package/dist/skills/refs.d.ts.map +1 -1
  136. package/dist/skills/refs.js +367 -26
  137. package/dist/skills/refs.js.map +1 -1
  138. package/dist/skills/runtime.d.ts +13 -1
  139. package/dist/skills/runtime.d.ts.map +1 -1
  140. package/dist/skills/runtime.js +88 -1
  141. package/dist/skills/runtime.js.map +1 -1
  142. package/dist/skills/store.d.ts +103 -5
  143. package/dist/skills/store.d.ts.map +1 -1
  144. package/dist/skills/store.js +265 -39
  145. package/dist/skills/store.js.map +1 -1
  146. package/dist/studio/assets/{index-CK1uJWs2.css → index-C0UZ2BxT.css} +1 -1
  147. package/dist/studio/assets/index-Clm0MXDF.js +544 -0
  148. package/dist/studio/index.html +2 -2
  149. package/dist/studio/testid-inventory.json +606 -5
  150. package/endpoint-manifest.json +31 -3
  151. package/package.json +4 -4
  152. package/dist/studio/assets/index-CeJTutxP.js +0 -540
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/api/routes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/api/routes.ts"],"names":[],"mappings":"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"}
@@ -17,9 +17,13 @@ import { execCapped, ExecOutputTooLarge } from '../core/exec.js';
17
17
  import { callEstateTool, EstateMcpError } from '../core/estate-mcp-client.js';
18
18
  import { SeatHealthTracker } from './seat-health.js';
19
19
  import { applyWorkerConfigRoot, signedInHeuristic } from './seat-signin.js';
20
+ import { chatSeatAdmission, seatStanding } from './seat-standing.js';
20
21
  import { ChatScopeIndex, chatScopeDeps, prepareChatScratch, removeChatScratch, resolveChatScope, } from './chat-scope.js';
21
22
  import { allowedRootsFor, isInsideRoot, openWithSystemDefault } from './open-path.js';
22
- import { InvalidDiffBaseError, NotARegularFileError, UnresolvableDiffBaseError, readFileCapped, worktreeDiff, } from './run-files.js';
23
+ import { InvalidDiffBaseError, MERGE_BASE_LITERAL, NotARegularFileError, UnresolvableDiffBaseError, branchDiff, isPlainRef, readFileCapped, worktreeDiff, } from './run-files.js';
24
+ import { DocRunIndex } from '../interactive/doc-run-index.js';
25
+ import { listInteractiveDocs } from '../interactive/docs-index.js';
26
+ import { TestSetIndex } from '../qe/test-sets.js';
23
27
  import { resolveProjectGraphBinding } from '../projects/graph.js';
24
28
  import { registerProjectRoutes } from '../projects/routes.js';
25
29
  import { registerCampaignRoutes } from '../campaigns/routes.js';
@@ -73,13 +77,6 @@ const STATUS_ORDER = {
73
77
  function sortActionableFirst(views) {
74
78
  return [...views].sort((a, b) => (STATUS_ORDER[a.session.status] ?? 9) - (STATUS_ORDER[b.session.status] ?? 9));
75
79
  }
76
- /**
77
- * `codeGraphDb(repo)` for a repo surface, or `null` after answering **503** — a CURRENT engine that
78
- * resolved no repo-graph root (`code_graph_root_unresolvable`, wicked-core#406) is a daemon-
79
- * environment fault, not a bad request and not Fastify's generic 500. The mapping is the shared
80
- * `codeGraphErrorStatus`; anything it does not classify rethrows unchanged (the stale-addon error
81
- * keeps its pre-existing shape here).
82
- */
83
80
  function codeGraphDbOr503(repo, reply) {
84
81
  try {
85
82
  return codeGraphDb(repo);
@@ -475,6 +472,10 @@ runtime = {}) {
475
472
  const guidanceIndex = runtime.guidanceIndex ?? new GuidanceIndex();
476
473
  const chatScopes = runtime.chatScopes ?? new ChatScopeIndex();
477
474
  const deliveryIndex = runtime.deliveryIndex ?? new DeliveryIndex();
475
+ // Wave 6: the doc↔run binding and the registered test sets — `createServer` injects the real
476
+ // ones; a directly-driven route set gets an empty index (every run `document_id: null`, no sets).
477
+ const docRuns = runtime.docRuns ?? new DocRunIndex(() => []);
478
+ const testSets = runtime.testSets ?? new TestSetIndex();
478
479
  const worktreeExists = runtime.worktreeExists ?? ((p) => existsSync(p));
479
480
  const vacuityProbes = {
480
481
  worktreeExists,
@@ -563,6 +564,9 @@ runtime = {}) {
563
564
  const decorateRun = (view) => {
564
565
  const conflictStrand = normalizeStranded(view);
565
566
  view.session.project_id = projects.index.projectOf(view.session.id) ?? null;
567
+ // Wave 6 (F-4R2-006): the interactive document this run answered, from the seams' handoff
568
+ // ledgers — `null` = genuinely not a document run, so the field is ALWAYS present on served runs.
569
+ view.session.document_id = docRuns.documentOf(view.session.id) ?? null;
566
570
  const retryOf = retryIndex.retryOfFor(view.session.id);
567
571
  if (retryOf !== undefined)
568
572
  view.session.retry_of = retryOf;
@@ -707,16 +711,33 @@ runtime = {}) {
707
711
  // gains `signed_in`: the cheap file/env presence heuristic, computed against the LIVE
708
712
  // `WICKED_WORKER_HOME` env — the same value the engine reads at the next worker spawn, kept
709
713
  // current by `applyWorkerConfigRoot` at boot and on every settings change.
710
- app.get(`${V}/roster`, async () => {
714
+ //
715
+ // Each seat ALSO carries its STANDING (F-2R2-009): `auth` re-reads `signed_in` for what it means
716
+ // (a `signed_out` codex is benched on its first ballot; a `not_required` opencode answers on its
717
+ // free tier), and `council_eligible` says what a council would do with the seat as far as the
718
+ // daemon can tell. `POST /chats` seats its defaults through the SAME standing, so the roster and
719
+ // the chat never disagree about a seat.
720
+ const rosterWithStanding = () => {
711
721
  const workerRoot = process.env['WICKED_WORKER_HOME'];
712
- return {
713
- roster: CoreAdapter.roster().map((seat) => ({
722
+ return CoreAdapter.roster().map((seat) => {
723
+ const key = String(seat.key);
724
+ const health = seatHealth.healthFor(key);
725
+ const signed = signedIn(key, workerRoot === '' ? undefined : workerRoot);
726
+ return {
714
727
  ...seat,
715
- health: seatHealth.healthFor(String(seat.key)),
716
- signed_in: signedIn(String(seat.key), workerRoot === '' ? undefined : workerRoot),
717
- })),
718
- };
719
- });
728
+ health,
729
+ signed_in: signed,
730
+ // The bench is THIS daemon's council evidence (councilSeatFailed, bounded window) — the
731
+ // prediction learns from what the engine actually did with the seat (#533 review, F-1).
732
+ ...seatStanding(seat, signed, health, seatHealth.councilBenchFor(key),
733
+ // F-A45-006: the seat's OWN "no credential" report (a ballot's "No API key found", a
734
+ // worker's 401, an auth ACP fallback) overrides the file probe — `auth` flips, not only
735
+ // `council_eligible`, and the evidence rides on the wire.
736
+ seatHealth.authFailureFor(key)),
737
+ };
738
+ });
739
+ };
740
+ app.get(`${V}/roster`, async () => ({ roster: rosterWithStanding() }));
720
741
  // Open a file/folder with the OS default application (crew#273) — the studio Files tab's
721
742
  // click-to-open. The open MUST happen daemon-side (the SPA cannot spawn a process), which is
722
743
  // why the path is validated first: absolute, and inside one of the caller-visible roots — the
@@ -861,26 +882,8 @@ runtime = {}) {
861
882
  if (resolved === null)
862
883
  return reply;
863
884
  const workdir = resolved.session.workdir;
864
- if (typeof workdir !== 'string' || workdir.length === 0) {
865
- return reply.code(409).send({ error: `run ${id} has no workdir — nothing to diff` });
866
- }
867
- if (!existsSync(workdir)) {
868
- return reply.code(409).send({ error: `run ${id}'s workdir no longer exists: ${workdir}` });
869
- }
870
- // Narrowing is WORKTREE-scoped: a contained-but-outside-the-worktree path (extra write
871
- // root / repo root) is a valid FILE read but has no meaning as a diff pathspec — rejected
872
- // explicitly here rather than handing git a `../`-prefixed pathspec and surfacing its
873
- // "outside repository" error as a 500 (Copilot, #305).
874
- if (resolved.target !== undefined && !isInsideRoot(workdir, resolved.target)) {
875
- return reply.code(400).send({
876
- error: `\`path\` must be inside the run's worktree to diff: ${workdir}`,
877
- });
878
- }
879
- const rel = resolved.target === undefined ? undefined : relative(workdir, resolved.target);
880
- try {
881
- return await worktreeDiff(workdir, rel, rawBase);
882
- }
883
- catch (err) {
885
+ /** The route's one error mapping, shared by the worktree and the branch reads. */
886
+ const diffError = (err) => {
884
887
  // Named 400s (§8.1): malformed base (not a plain ref) and well-formed-but-unresolvable
885
888
  // base are both client errors, each with its error name in the body — never a git 500.
886
889
  if (err instanceof InvalidDiffBaseError || err instanceof UnresolvableDiffBaseError) {
@@ -898,6 +901,75 @@ runtime = {}) {
898
901
  });
899
902
  }
900
903
  return reply.code(500).send({ error: message(err) });
904
+ };
905
+ const worktreeLive = typeof workdir === 'string' && workdir.length > 0 && existsSync(workdir);
906
+ if (!worktreeLive) {
907
+ // Wave 6 (F-7R2-013): the engine reaps a completed run's worktree, and the run page went dark
908
+ // (`409 workdir no longer exists`). The run's WORK is not gone — it lives on the `wicked/<id>`
909
+ // branch of the registered repo, and the wave-6 engine records `run_branch` + `base_commit`
910
+ // on the session. Serve the diff from the BRANCH (`source: 'branch'`): the recorded branch
911
+ // (else `wicked/<id>`) against the recorded base (else its merge-base with the default
912
+ // branch), `?base=<ref>` overriding the base with a plain in-repo ref. Only when there is
913
+ // neither a worktree nor a branch does the 409 stand — and then it says so.
914
+ const repoRef = resolved.session.repo_ref;
915
+ const root = repoRef !== null ? await repoRootOf(repoRef) : undefined;
916
+ if (root !== undefined) {
917
+ const session = resolved.session;
918
+ const branch = typeof session.run_branch === 'string' && session.run_branch !== '' ? session.run_branch : `wicked/${id}`;
919
+ let base = typeof session.base_commit === 'string' && session.base_commit !== '' ? session.base_commit : null;
920
+ if (rawBase !== undefined && rawBase !== '' && rawBase !== MERGE_BASE_LITERAL) {
921
+ if (!isPlainRef(rawBase)) {
922
+ return reply.code(400).send({
923
+ error: `InvalidDiffBaseError: \`base\` must be the literal '${MERGE_BASE_LITERAL}' or a plain git ref`,
924
+ });
925
+ }
926
+ base = rawBase;
927
+ }
928
+ // Narrowing: a path under the (gone) worktree or under the repo root, made repo-relative.
929
+ let rel;
930
+ if (resolved.target !== undefined) {
931
+ if (isInsideRoot(root, resolved.target))
932
+ rel = relative(root, resolved.target);
933
+ else if (typeof workdir === 'string' && workdir.length > 0 && isInsideRoot(workdir, resolved.target)) {
934
+ rel = relative(workdir, resolved.target);
935
+ }
936
+ else {
937
+ return reply.code(400).send({
938
+ error: `\`path\` must be inside the run's worktree or its repository to diff: ${root}`,
939
+ });
940
+ }
941
+ }
942
+ try {
943
+ const fromBranch = await branchDiff(root, branch, base, rel);
944
+ if (fromBranch !== null)
945
+ return fromBranch;
946
+ }
947
+ catch (err) {
948
+ return diffError(err);
949
+ }
950
+ }
951
+ if (typeof workdir !== 'string' || workdir.length === 0) {
952
+ return reply.code(409).send({ error: `run ${id} has no workdir and no run branch — nothing to diff` });
953
+ }
954
+ return reply.code(409).send({
955
+ error: `run ${id}'s workdir no longer exists (${workdir}) and its run branch holds no commits — nothing to diff`,
956
+ });
957
+ }
958
+ // Narrowing is WORKTREE-scoped: a contained-but-outside-the-worktree path (extra write
959
+ // root / repo root) is a valid FILE read but has no meaning as a diff pathspec — rejected
960
+ // explicitly here rather than handing git a `../`-prefixed pathspec and surfacing its
961
+ // "outside repository" error as a 500 (Copilot, #305).
962
+ if (resolved.target !== undefined && !isInsideRoot(workdir, resolved.target)) {
963
+ return reply.code(400).send({
964
+ error: `\`path\` must be inside the run's worktree to diff: ${workdir}`,
965
+ });
966
+ }
967
+ const rel = resolved.target === undefined ? undefined : relative(workdir, resolved.target);
968
+ try {
969
+ return { ...(await worktreeDiff(workdir, rel, rawBase)), source: 'worktree' };
970
+ }
971
+ catch (err) {
972
+ return diffError(err);
901
973
  }
902
974
  });
903
975
  // Registered repos → target-repo picker.
@@ -974,7 +1046,10 @@ runtime = {}) {
974
1046
  const input = {
975
1047
  problem: b.problem,
976
1048
  sessionId: b.sessionId ?? randomUUID(),
977
- clisJson: b.clisJson ?? JSON.stringify(CoreAdapter.roster()),
1049
+ // The default roster carries crew's STANDING (wave 6, the crew half of F-7R2-006): the adapter
1050
+ // translates `council_eligible: false` into the engine's per-seat bench verdict at launch
1051
+ // (`core/engine-roster.ts`), so a signed-out seat is never convened, never a judge.
1052
+ clisJson: b.clisJson ?? JSON.stringify(rosterWithStanding()),
978
1053
  };
979
1054
  if (b.entityMode !== undefined)
980
1055
  input.entityMode = b.entityMode;
@@ -1145,8 +1220,17 @@ runtime = {}) {
1145
1220
  // resolve, not leak.
1146
1221
  // Fastify parses a REPEATED query param as string[] — normalize so `?include=archived`
1147
1222
  // and `?include=archived&include=archived` behave identically (Copilot).
1148
- const { include, limit } = req.query;
1223
+ const { include, limit, doc } = req.query;
1149
1224
  const includeArchived = (Array.isArray(include) ? include : [include]).includes('archived');
1225
+ // `?doc=<document id>` (wave 6, F-4R2-006): only the runs the interactive seams launched for
1226
+ // that document — the doc↔run binding as a direct read (the run DTO carries `document_id`).
1227
+ // A repeated `?doc` is an ambiguity, not a repetition — refused like a repeated `?limit`.
1228
+ if (Array.isArray(doc)) {
1229
+ return reply.code(400).send({ error: '`doc` may be given at most once' });
1230
+ }
1231
+ if (doc !== undefined && doc.trim() === '') {
1232
+ return reply.code(400).send({ error: '`doc` must name a document id' });
1233
+ }
1150
1234
  // `?limit=N` — the top N AFTER the actionable-first sort below, so a capped poll still sees
1151
1235
  // the runs that need a human before the terminal sediment. The default stays UNBOUNDED: the
1152
1236
  // param used to be read by nobody (silently ignored — the full payload regardless), so an
@@ -1169,9 +1253,10 @@ runtime = {}) {
1169
1253
  }
1170
1254
  cap = Number(limit);
1171
1255
  }
1172
- const visible = includeArchived
1256
+ const unarchived = includeArchived
1173
1257
  ? views
1174
1258
  : views.filter((v) => v.session.archived_at == null);
1259
+ const visible = doc === undefined ? unarchived : unarchived.filter((v) => docRuns.documentOf(v.session.id) === doc.trim());
1175
1260
  const ordered = sortActionableFirst(visible);
1176
1261
  return { runs: (cap !== undefined ? ordered.slice(0, cap) : ordered).map(decorateRun) };
1177
1262
  });
@@ -1559,26 +1644,47 @@ runtime = {}) {
1559
1644
  .code(500)
1560
1645
  .send({ error: `cannot prepare the chat's scratch root ${scope.cwd}: ${message(err)}` });
1561
1646
  }
1562
- // The default seats of a SCOPED chat are pre-filtered by admissibility (independent review,
1563
- // W5): the engine admits a seat to a scoped chat only when its ACP adapter asks permissions
1564
- // (`acp_input_governance`) or its record arms the kernel write floor (`os_sandbox`) — with the
1565
- // default roster that is claude and opencode — so a default project-scoped open does not show
1566
- // four refused seats. Explicit `clis` are passed through as asked; the engine refuses per seat
1567
- // with the reason.
1647
+ // The DEFAULT seats are the roster seats the daemon's own admission admits (F-2R2-007,
1648
+ // F-2R2-009): the seat's auth standing (a signed-out seat is refused up front, with the
1649
+ // reason, instead of failing its first turn — the same predicate `GET /roster` reports as
1650
+ // `council_eligible`) and, for a SCOPED chat, the engine's rule restated (only a seat whose
1651
+ // ACP adapter asks permissions or whose record arms the kernel write floor can be held to
1652
+ // read-only roots — with the default roster that is claude and opencode). Every seat dropped
1653
+ // here is NAMED on the response (`refused`) and in the thread (`chatSeatRefused`), so a
1654
+ // person can see why pi is missing. Explicit `clis` are passed through as asked; the engine
1655
+ // refuses per seat with its reason, which is copied into `refused` too.
1568
1656
  const scoped = scope.kind !== 'none';
1569
- const roster = CoreAdapter.roster();
1570
- const clis = b.clis ??
1571
- roster
1572
- .filter((s) => !scoped || s.acp?.acp_input_governance === true || s.acp?.os_sandbox === true)
1573
- .map((s) => s.key)
1574
- .filter((k) => typeof k === 'string');
1657
+ const refused = [];
1658
+ // The standing roster, read ONCE: the default admission below and the engine-drop
1659
+ // attribution after `chatOpen` both consult it (F-A45-011).
1660
+ const standing = rosterWithStanding();
1661
+ const standingOf = (key) => standing.find((s) => String(s.key) === key);
1662
+ let clis;
1663
+ if (b.clis !== undefined) {
1664
+ clis = b.clis;
1665
+ }
1666
+ else {
1667
+ clis = [];
1668
+ for (const seat of standing) {
1669
+ const key = String(seat.key);
1670
+ const admission = chatSeatAdmission(seat, seat.auth ?? 'unknown', scoped);
1671
+ if (admission.ok)
1672
+ clis.push(key);
1673
+ else
1674
+ refused.push({ cliKey: key, reason: admission.reason, source: admission.source });
1675
+ }
1676
+ }
1575
1677
  if (clis.length === 0) {
1576
1678
  chatScopes.release(chatId, token);
1577
1679
  removeChatScratch(scope.cwd, chatScopes.base);
1578
1680
  return reply.code(409).send({
1579
- error: 'no seat in the roster can be held to a scoped chat (an ACP adapter admitted to input ' +
1580
- 'governance, or `os_sandbox = true` on its [cli.acp] record); open the chat unscoped, or ' +
1581
- 'name seats with `clis`',
1681
+ error: (scoped
1682
+ ? 'no seat in the roster can be held to a scoped chat (an ACP adapter admitted to input ' +
1683
+ 'governance, or `os_sandbox = true` on its [cli.acp] record) and take a turn; open the ' +
1684
+ 'chat unscoped, sign a seat in, or name seats with `clis`'
1685
+ : 'no seat in the roster can take a turn (every seat is signed out); sign a seat in from ' +
1686
+ 'the System page, or name seats with `clis`') + ' — see refused',
1687
+ refused,
1582
1688
  });
1583
1689
  }
1584
1690
  try {
@@ -1586,6 +1692,48 @@ runtime = {}) {
1586
1692
  codeGraphDb: engine.codeGraphDb,
1587
1693
  readRoots: engine.readRoots,
1588
1694
  });
1695
+ // A REQUESTED seat the engine refused joins the same list, with the engine's reason.
1696
+ for (const s of seats) {
1697
+ if (!s.ok)
1698
+ refused.push({ cliKey: s.cliKey, reason: s.error ?? 'the engine refused the seat', source: 'engine' });
1699
+ }
1700
+ // F-A45-011 (F-2R2-007 still open): a seat the engine DROPPED — absent from `seats`
1701
+ // altogether, neither ok nor refused — used to vanish without a trace (the fresh rig's pi:
1702
+ // default chips claude·pi·opencode, 201 `seats:[claude, opencode]`, `refused: []`). It was
1703
+ // taken out by the council-bench / dispatch-timeout path, not by admission, so admission's
1704
+ // list never named it. Every requested-or-defaulted seat that is not in `seats` is named
1705
+ // here with the most specific cause the daemon knows: its own "no credential" report
1706
+ // (`auth`), this daemon's council bench (`bench`), else the dispatch budget (`budget`).
1707
+ for (const key of clis) {
1708
+ if (seats.some((s) => s.cliKey === key) || refused.some((r) => r.cliKey === key))
1709
+ continue;
1710
+ const st = standingOf(key);
1711
+ const authFailure = seatHealth.authFailureFor(key);
1712
+ if (authFailure !== null || st?.auth === 'signed_out') {
1713
+ refused.push({
1714
+ cliKey: key,
1715
+ reason: authFailure !== null
1716
+ ? `not seated — the seat itself reported no credential (${authFailure.source}: ${authFailure.detail}); sign it in from the System page`
1717
+ : 'not seated — signed out; sign it in from the System page',
1718
+ source: 'auth',
1719
+ });
1720
+ }
1721
+ else if (st?.council_bench !== undefined) {
1722
+ refused.push({
1723
+ cliKey: key,
1724
+ reason: `not seated — ${st.council_ineligible_reason ?? 'benched by this daemon’s recent councils'}`,
1725
+ source: 'bench',
1726
+ });
1727
+ }
1728
+ else {
1729
+ refused.push({
1730
+ cliKey: key,
1731
+ reason: 'not seated — the engine did not warm it within its dispatch budget (the seat timed out or ' +
1732
+ 'was dropped at dispatch); check GET /roster and try again, or name seats with `clis`',
1733
+ source: 'budget',
1734
+ });
1735
+ }
1736
+ }
1589
1737
  // Nothing warmed (independent review, W1): the engine holds no pool row and has dropped the
1590
1738
  // scope itself (no `chatClosed` will come) — report the PER-SEAT reasons, never an
1591
1739
  // engine-version guess; the root goes, the id is free again.
@@ -1595,6 +1743,7 @@ runtime = {}) {
1595
1743
  return reply.code(409).send({
1596
1744
  error: `chat ${chatId}: no seat warmed (${seats.length} failed) — see seats`,
1597
1745
  seats,
1746
+ refused,
1598
1747
  });
1599
1748
  }
1600
1749
  // Honest scope (Copilot, #518): a SCOPED chat is a promise — the roots are read-only, the
@@ -1649,7 +1798,7 @@ runtime = {}) {
1649
1798
  projectAttachError = message(err);
1650
1799
  }
1651
1800
  }
1652
- if (!chatScopes.set(chatId, scope, token)) {
1801
+ if (!chatScopes.set(chatId, scope, token, refused)) {
1653
1802
  // The reservation was cancelled while the open was in flight — an engine `chatClosed` or a
1654
1803
  // `DELETE` for this id (Copilot, #518). Nothing was recorded; tear the chat down (engine
1655
1804
  // session, scratch root, and the filing just made) instead of returning a stale 201.
@@ -1663,10 +1812,24 @@ runtime = {}) {
1663
1812
  error: `chat ${chatId} was closed while it was being opened; open it again`,
1664
1813
  });
1665
1814
  }
1815
+ // The thread learns of every refused seat the way it learns of everything else — a frame
1816
+ // on /ws — AFTER the scope is published, so a reader never sees a refusal for a chat it
1817
+ // cannot yet look up.
1818
+ for (const r of refused) {
1819
+ runtime.broadcast?.({
1820
+ type: 'chatSeatRefused',
1821
+ chat: chatId,
1822
+ cliKey: r.cliKey,
1823
+ reason: r.reason,
1824
+ source: r.source,
1825
+ ...(b.projectId !== undefined ? { project_id: b.projectId } : {}),
1826
+ });
1827
+ }
1666
1828
  return reply.code(201).send({
1667
1829
  chatId,
1668
1830
  seats,
1669
1831
  scope,
1832
+ refused,
1670
1833
  ...(projectAttachError !== undefined ? { projectAttachError } : {}),
1671
1834
  });
1672
1835
  }
@@ -1723,11 +1886,33 @@ runtime = {}) {
1723
1886
  .send({ error: message(err) });
1724
1887
  }
1725
1888
  });
1889
+ // ── Interactive documents, daemon-wide, WITHOUT spawning a bridge (wave 6, studio #263) ──────
1890
+ // The per-project listing (`GET /projects/:id/interactive/api/docs`) asks the project's bridge —
1891
+ // one `wicked-interactive serve` per project root, ≈60 s cold start — so a skin must never fan
1892
+ // it out on mount. This reads what the bridge reads (every project's docs root, each slug child
1893
+ // carrying a `versions.json`) plus what only the daemon knows (the seams that answered each doc
1894
+ // and the runs they launched, from the handoff ledgers). `?includeRetired=1` lists tombstones.
1895
+ app.get(`${V}/interactive/docs`, { config: { manifest: { responseType: 'InteractiveDocsListing', statusCodes: [200] } } }, async (req) => {
1896
+ const q = req.query;
1897
+ const flag = Array.isArray(q.includeRetired) ? q.includeRetired[0] : q.includeRetired;
1898
+ return listInteractiveDocs({
1899
+ adapter,
1900
+ settings: projectSettings,
1901
+ docRuns,
1902
+ includeRetired: flag === '1' || flag === 'true',
1903
+ });
1904
+ });
1726
1905
  app.get(`${V}/chats/:id`, { config: { manifest: { responseType: 'ChatDetailResponse', statusCodes: [200, 400] } } }, async (req, reply) => {
1727
1906
  const { id } = req.params;
1728
1907
  try {
1729
- // The scope recorded at open (crew#502) — `null` for a chat this daemon did not open.
1730
- return { chatId: id, seats: await adapter.chatSeats(id), scope: chatScopes.get(id) ?? null };
1908
+ // The scope recorded at open (crew#502) — `null` for a chat this daemon did not open — and
1909
+ // the seats refused at open (F-A45-011), so the studio's admission copy survives a reload.
1910
+ return {
1911
+ chatId: id,
1912
+ seats: await adapter.chatSeats(id),
1913
+ scope: chatScopes.get(id) ?? null,
1914
+ refused: chatScopes.refusedOf(id) ?? null,
1915
+ };
1731
1916
  }
1732
1917
  catch (err) {
1733
1918
  return reply.code(400).send({ error: message(err) });
@@ -2008,11 +2193,39 @@ runtime = {}) {
2008
2193
  const run = views.find((v) => v.session.id === id);
2009
2194
  if (!run)
2010
2195
  return reply.code(404).send({ error: 'Run not found' });
2011
- if (run.session.status !== 'executing') {
2196
+ // Wave 6 (F-7R2-007 root fix): a run PARKED at a gate on a dead seat — the stall watchdog's
2197
+ // escalation gate, or a verdict escalation — used to answer 409 here, so the studio's control
2198
+ // needed two calls (approve, then race the engine's re-dispatch of the same dead seat with a
2199
+ // reassign). The ENGINE's `reassign_unit` accepts ONLY an Executing run (wicked-core actor.rs:
2200
+ // "run X is not Executing (status: AwaitingHuman)") — there is no reassign-in-place for a gated
2201
+ // run — so this route performs APPROVE-THEN-REASSIGN in one call: the approve resumes the run
2202
+ // (the engine re-dispatches the cursor unit to its current seat), and the reassign IMMEDIATELY
2203
+ // supersedes that turn (cancels its epoch, closes the seat's session, bumps the attempt) and
2204
+ // re-dispatches to the requested seat or the council's pick. The dead seat is dispatched for
2205
+ // the gap between the two engine calls — a bounded window the engine contract leaves open (a
2206
+ // reassign-as-approval engine op would close it; documented in the PR). Audited as BOTH a gate
2207
+ // decision (`via: 'reassign'`) and a reassign, so the "who approved" trail has no side door.
2208
+ // A steering-author propose gate is NOT approvable this way: its approve LANDS the proposal
2209
+ // through `POST /runs/:id/gate` (crew#388), and a reassign is not a review of the rules.
2210
+ const gated = run.session.status === 'awaiting_human';
2211
+ if (run.session.status !== 'executing' && !gated) {
2012
2212
  return reply.code(409).send({
2013
2213
  error: `run ${id} is ${run.session.status}, not executing — only an executing run has a cursor unit to reassign`,
2014
2214
  });
2015
2215
  }
2216
+ if (gated && typeof adapter.confirmGate !== 'function') {
2217
+ // A partial adapter (a directly-driven route set) cannot approve the gate on the caller's
2218
+ // behalf — say so by name, never a TypeError dressed as a refusal.
2219
+ return reply.code(409).send({
2220
+ error: `run ${id} is awaiting_human, not executing — the engine reassigns only an executing run, and ` +
2221
+ `this build cannot approve the gate on your behalf (no confirmGate); approve via POST /runs/${id}/gate, then reassign`,
2222
+ });
2223
+ }
2224
+ if (gated && typeof adapter.listWorkflows === 'function' && isSteeringAuthorRun(run, adapter.listWorkflows())) {
2225
+ return reply.code(409).send({
2226
+ error: `run ${id} is awaiting a steering-author propose gate — approve or reject it via POST /runs/${id}/gate (the approve lands the proposal); reassign is not a review of the rules`,
2227
+ });
2228
+ }
2016
2229
  const requestedCli = parsed.data.cli;
2017
2230
  if (requestedCli !== undefined) {
2018
2231
  const pool = Array.isArray(run.session.clis) ? run.session.clis : [];
@@ -2025,12 +2238,24 @@ runtime = {}) {
2025
2238
  const cursor = resolveCursorUnit(run);
2026
2239
  const ord = cursor?.ord ?? run.session.unit_ix;
2027
2240
  try {
2241
+ if (gated) {
2242
+ const status = await adapter.confirmGate(id, true);
2243
+ audit.record('gate.decided', actorOf(req), {
2244
+ runId: id,
2245
+ detail: { approve: true, via: 'reassign', status },
2246
+ });
2247
+ }
2028
2248
  await adapter.reassignUnit(id, ord, requestedCli ?? null);
2029
2249
  audit.record('run.reassigned', actorOf(req), {
2030
2250
  runId: id,
2031
- detail: { ord, ...(requestedCli !== undefined ? { cli: requestedCli } : {}) },
2251
+ detail: { ord, ...(requestedCli !== undefined ? { cli: requestedCli } : {}), ...(gated ? { approved: true } : {}) },
2252
+ });
2253
+ return reply.send({
2254
+ status: 'ok',
2255
+ ord,
2256
+ ...(requestedCli !== undefined ? { cli: requestedCli } : {}),
2257
+ ...(gated ? { approved: true } : {}),
2032
2258
  });
2033
- return reply.send({ status: 'ok', ord, ...(requestedCli !== undefined ? { cli: requestedCli } : {}) });
2034
2259
  }
2035
2260
  catch (err) {
2036
2261
  return reply.code(409).send({ error: message(err) });
@@ -2791,7 +3016,7 @@ runtime = {}) {
2791
3016
  return reply.code(404).send({ error: 'Requirement not found' });
2792
3017
  return { requirement: detail };
2793
3018
  });
2794
- app.get(`${V}/repos/:id/graph`, async (req, reply) => {
3019
+ app.get(`${V}/repos/:id/graph`, { config: { manifest: { responseType: 'RepoGraphResponse', statusCodes: [200, 404, 500, 503] } } }, async (req, reply) => {
2795
3020
  const { id } = req.params;
2796
3021
  const repos = await adapter.listRepos();
2797
3022
  const repo = repos.find((r) => r.id === id);
@@ -2801,7 +3026,17 @@ runtime = {}) {
2801
3026
  if (dbPath === null)
2802
3027
  return reply;
2803
3028
  if (!existsSync(dbPath)) {
2804
- return reply.send({ graph: null });
3029
+ // `graph: null` alone cannot tell "not indexed" from "empty" (F-2R2-005): say WHY, with the
3030
+ // same finding text the repos wire carries when the engine has one.
3031
+ const finding = (repo.findings ?? []).find((f) => f.code === 'in_tree_code_graph_ignored' || f.code === 'code_graph_root_unresolvable');
3032
+ const unbuilt = {
3033
+ graph: null,
3034
+ reason: finding?.message ??
3035
+ `no code graph has been built for '${repo.name}' yet (nothing at ${dbPath}) — run onboarding ` +
3036
+ `(POST /api/v1/repos/${repo.id}/onboard) to index it`,
3037
+ ...(finding !== undefined ? { finding } : {}),
3038
+ };
3039
+ return reply.send(unbuilt);
2805
3040
  }
2806
3041
  try {
2807
3042
  const settings = await adapter.getSettings();
@@ -2822,13 +3057,14 @@ runtime = {}) {
2822
3057
  });
2823
3058
  const raw = JSON.parse(stdout);
2824
3059
  const fileCount = new Set(raw.nodes.map((n) => n.file)).size;
2825
- return reply.send({
3060
+ const built = {
2826
3061
  graph: {
2827
3062
  nodes: raw.nodes,
2828
3063
  edges: raw.edges,
2829
3064
  stats: { nodeCount: raw.nodes.length, edgeCount: raw.edges.length, fileCount },
2830
3065
  },
2831
- });
3066
+ };
3067
+ return reply.send(built);
2832
3068
  }
2833
3069
  catch (err) {
2834
3070
  return reply.code(500).send({ error: message(err) });
@@ -3442,8 +3678,14 @@ runtime = {}) {
3442
3678
  registerCampaignRoutes(app, adapter, {
3443
3679
  audit,
3444
3680
  actorOf,
3445
- roster: () => CoreAdapter.roster(),
3681
+ // The roster WITH crew's standing (F-086 — parity with POST /runs and POST /testing/*): the
3682
+ // adapter turns `council_eligible` into the engine's per-seat bench at launch, per campaign
3683
+ // node (`core/engine-roster.ts` `engineCampaignDef`), so a signed-out seat is never convened
3684
+ // by a campaign node either.
3685
+ roster: () => rosterWithStanding(),
3446
3686
  groupIndex,
3687
+ // Wave 6 (F-7R2-014): the registered test sets ride beside the campaigns + groups.
3688
+ testSets,
3447
3689
  deliveryUrlFor: (runId) => deliveryIndex.urlFor(runId),
3448
3690
  vacuity: vacuityProbes,
3449
3691
  // A non-probe derivation throw in the rollup is a defect — error level, loud in diagnostics.
@@ -3460,7 +3702,9 @@ runtime = {}) {
3460
3702
  registerGovernanceSteeringRoutes(app, adapter, {
3461
3703
  audit,
3462
3704
  actorOf,
3463
- roster: () => CoreAdapter.roster(),
3705
+ // Standing too (F-086 parity): the steering-author run launches through `launchRun`, whose
3706
+ // roster translation (`engineRosterJson`) already benches `council_eligible: false` seats.
3707
+ roster: () => rosterWithStanding(),
3464
3708
  // So the steering-author run's `run.launched` entry stamps `created_at` live too (Copilot #466).
3465
3709
  runTimingIndex,
3466
3710
  });
@@ -3472,8 +3716,12 @@ runtime = {}) {
3472
3716
  registerTestingRoutes(app, adapter, {
3473
3717
  audit,
3474
3718
  actorOf,
3475
- roster: () => CoreAdapter.roster(),
3719
+ // The roster WITH crew's standing (wave 6): the adapter turns `council_eligible` into the
3720
+ // engine's per-seat bench at launch, and the author response's `plan.seats` reads it.
3721
+ roster: () => rosterWithStanding(),
3476
3722
  projects: { bus: projects.bus, index: projects.index },
3723
+ // The author launch files each run under its repo's `qe-tests-<repo>` label (F-7R2-014).
3724
+ groupIndex,
3477
3725
  // So the recon fan's `run.launched` entries stamp `created_at` live too (Copilot #466), not
3478
3726
  // just after a restart re-hydrates the trail.
3479
3727
  runTimingIndex,