@yadsh/dsh-qa-surface 0.6.1 → 0.7.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 (287) hide show
  1. package/README.md +163 -7
  2. package/capability-policy.json +1 -1
  3. package/lib/access/capability-catalog.js +144 -0
  4. package/lib/access/capability-catalog.js.map +1 -0
  5. package/lib/access/model.js +379 -0
  6. package/lib/access/model.js.map +1 -0
  7. package/lib/access/role-repository.js +195 -0
  8. package/lib/access/role-repository.js.map +1 -0
  9. package/lib/access/service.js +380 -0
  10. package/lib/access/service.js.map +1 -0
  11. package/lib/access/skill-metadata.js +234 -0
  12. package/lib/access/skill-metadata.js.map +1 -0
  13. package/lib/account-remotes.js +20 -10
  14. package/lib/account-remotes.js.map +1 -1
  15. package/lib/accounts/errors.js.map +1 -1
  16. package/lib/accounts/file.js.map +1 -1
  17. package/lib/accounts/store.js +202 -3
  18. package/lib/accounts/store.js.map +1 -1
  19. package/lib/admin/conversation-log.js +256 -0
  20. package/lib/admin/conversation-log.js.map +1 -0
  21. package/lib/admin/index.js +17 -0
  22. package/lib/admin/index.js.map +1 -0
  23. package/lib/admin/metrics.js +103 -0
  24. package/lib/admin/metrics.js.map +1 -0
  25. package/lib/admin/paging.js +23 -0
  26. package/lib/admin/paging.js.map +1 -0
  27. package/lib/admin/permissions.js +50 -0
  28. package/lib/admin/permissions.js.map +1 -0
  29. package/lib/admin/quality-store.js +485 -0
  30. package/lib/admin/quality-store.js.map +1 -0
  31. package/lib/admin/queue.js +107 -0
  32. package/lib/admin/queue.js.map +1 -0
  33. package/lib/admin/redaction.js +45 -0
  34. package/lib/admin/redaction.js.map +1 -0
  35. package/lib/admin/service.js +897 -0
  36. package/lib/admin/service.js.map +1 -0
  37. package/lib/admin/session-log.js +142 -0
  38. package/lib/admin/session-log.js.map +1 -0
  39. package/lib/cli.js +9 -6
  40. package/lib/cli.js.map +1 -1
  41. package/lib/client/QaSessionController.js +28 -2
  42. package/lib/client/QaSessionController.js.map +1 -1
  43. package/lib/client/QaSurface.js +143 -5
  44. package/lib/client/QaSurface.js.map +1 -1
  45. package/lib/client/QaTranscriptAdapter.js +1 -0
  46. package/lib/client/QaTranscriptAdapter.js.map +1 -1
  47. package/lib/client/admin/QaAdmin.js +458 -0
  48. package/lib/client/admin/QaAdmin.js.map +1 -0
  49. package/lib/client/admin/format.js +177 -0
  50. package/lib/client/admin/format.js.map +1 -0
  51. package/lib/client/admin/pages/Conversations.js +114 -0
  52. package/lib/client/admin/pages/Conversations.js.map +1 -0
  53. package/lib/client/admin/pages/Overview.js +24 -0
  54. package/lib/client/admin/pages/Overview.js.map +1 -0
  55. package/lib/client/admin/pages/Quality.js +71 -0
  56. package/lib/client/admin/pages/Quality.js.map +1 -0
  57. package/lib/client/admin/pages/Review.js +93 -0
  58. package/lib/client/admin/pages/Review.js.map +1 -0
  59. package/lib/client/admin/pages/Users.js +95 -0
  60. package/lib/client/admin/pages/Users.js.map +1 -0
  61. package/lib/client/admin/routes.js +143 -0
  62. package/lib/client/admin/routes.js.map +1 -0
  63. package/lib/client/admin/shared.js +91 -0
  64. package/lib/client/admin/shared.js.map +1 -0
  65. package/lib/client/admin/styles.js +111 -0
  66. package/lib/client/admin/styles.js.map +1 -0
  67. package/lib/client/components/QaChangelog.js +53 -0
  68. package/lib/client/components/QaChangelog.js.map +1 -1
  69. package/lib/client/components/QaHeader.js +3 -3
  70. package/lib/client/components/QaHeader.js.map +1 -1
  71. package/lib/client/components/QaMessage.js +61 -2
  72. package/lib/client/components/QaMessage.js.map +1 -1
  73. package/lib/client/create-session.js +1 -1
  74. package/lib/client/create-session.js.map +1 -1
  75. package/lib/client/index.js +48 -1
  76. package/lib/client/index.js.map +1 -1
  77. package/lib/client/role/RoleSelector.js +31 -0
  78. package/lib/client/role/RoleSelector.js.map +1 -0
  79. package/lib/client/session-sources.js +37 -1
  80. package/lib/client/session-sources.js.map +1 -1
  81. package/lib/client/settings/card.js +2 -2
  82. package/lib/client/settings/card.js.map +1 -1
  83. package/lib/client/settings/sections.js +0 -1
  84. package/lib/client/settings/sections.js.map +1 -1
  85. package/lib/client/settings-extensions/index.js +1 -0
  86. package/lib/client/settings-extensions/index.js.map +1 -1
  87. package/lib/client/settings-extensions/user-session.js +62 -0
  88. package/lib/client/settings-extensions/user-session.js.map +1 -0
  89. package/lib/client/styles.js +31 -0
  90. package/lib/client/styles.js.map +1 -1
  91. package/lib/client/types.js.map +1 -1
  92. package/lib/client.js +9993 -4848
  93. package/lib/client.js.map +1 -1
  94. package/lib/config-resolvers/defaults.js +0 -2
  95. package/lib/config-resolvers/defaults.js.map +1 -1
  96. package/lib/config.js +0 -249
  97. package/lib/config.js.map +1 -1
  98. package/lib/enforcement/skill-policy.js +172 -0
  99. package/lib/enforcement/skill-policy.js.map +1 -0
  100. package/lib/enforcement/tool-grants.js +151 -0
  101. package/lib/enforcement/tool-grants.js.map +1 -0
  102. package/lib/index.js +224 -42
  103. package/lib/index.js.map +1 -1
  104. package/lib/personal-skills/service.js +10 -3
  105. package/lib/personal-skills/service.js.map +1 -1
  106. package/lib/qa-tools/index.js +4 -0
  107. package/lib/qa-tools/index.js.map +1 -1
  108. package/lib/resolve-config.js +0 -2
  109. package/lib/resolve-config.js.map +1 -1
  110. package/lib/secure-session.js +71 -17
  111. package/lib/secure-session.js.map +1 -1
  112. package/lib/typert.host.js +2237 -202
  113. package/lib/typert.remote-client.d.ts +49 -3
  114. package/lib/typert.remote-client.js +1863 -183
  115. package/lib/types/access/capability-catalog.d.ts +37 -0
  116. package/lib/types/access/model.d.ts +60 -0
  117. package/lib/types/access/role-repository.d.ts +32 -0
  118. package/lib/types/access/service.d.ts +57 -0
  119. package/lib/types/access/skill-metadata.d.ts +53 -0
  120. package/lib/types/account-remotes.d.ts +6 -0
  121. package/lib/types/accounts/errors.d.ts +1 -1
  122. package/lib/types/accounts/file.d.ts +16 -5
  123. package/lib/types/accounts/store.d.ts +83 -3
  124. package/lib/types/admin/conversation-log.d.ts +39 -0
  125. package/lib/types/admin/index.d.ts +24 -0
  126. package/lib/types/admin/metrics.d.ts +29 -0
  127. package/lib/types/admin/paging.d.ts +33 -0
  128. package/lib/types/admin/permissions.d.ts +10 -0
  129. package/lib/types/admin/quality-store.d.ts +82 -0
  130. package/lib/types/admin/queue.d.ts +21 -0
  131. package/lib/types/admin/redaction.d.ts +29 -0
  132. package/lib/types/admin/service.d.ts +105 -0
  133. package/lib/types/admin/session-log.d.ts +53 -0
  134. package/lib/types/client/QaSessionController.d.ts +12 -1
  135. package/lib/types/client/QaSurface.d.ts +7 -1
  136. package/lib/types/client/admin/QaAdmin.d.ts +17 -0
  137. package/lib/types/client/admin/format.d.ts +43 -0
  138. package/lib/types/client/admin/pages/Conversations.d.ts +21 -0
  139. package/lib/types/client/admin/pages/Overview.d.ts +13 -0
  140. package/lib/types/client/admin/pages/Quality.d.ts +18 -0
  141. package/lib/types/client/admin/pages/Review.d.ts +15 -0
  142. package/lib/types/client/admin/pages/Users.d.ts +22 -0
  143. package/lib/types/client/admin/routes.d.ts +60 -0
  144. package/lib/types/client/admin/shared.d.ts +53 -0
  145. package/lib/types/client/admin/styles.d.ts +11 -0
  146. package/lib/types/client/components/QaHeader.d.ts +5 -1
  147. package/lib/types/client/components/QaMessage.d.ts +14 -1
  148. package/lib/types/client/create-session.d.ts +2 -0
  149. package/lib/types/client/role/RoleSelector.d.ts +14 -0
  150. package/lib/types/client/session-sources.d.ts +9 -0
  151. package/lib/types/client/settings/sections.d.ts +0 -1
  152. package/lib/types/client/settings-extensions/index.d.ts +2 -0
  153. package/lib/types/client/settings-extensions/user-session.d.ts +59 -0
  154. package/lib/types/client/types.d.ts +39 -2
  155. package/lib/types/enforcement/skill-policy.d.ts +29 -0
  156. package/lib/types/enforcement/tool-grants.d.ts +84 -0
  157. package/lib/types/index.d.ts +62 -14
  158. package/lib/types/qa-tools/index.d.ts +2 -0
  159. package/lib/types/secure-session.d.ts +10 -1
  160. package/lib/types/types.d.ts +568 -5
  161. package/package.json +2 -2
  162. package/lib/client/settings/sections/documents.js +0 -88
  163. package/lib/client/settings/sections/documents.js.map +0 -1
  164. package/lib/documents/artifacts/ids.js +0 -43
  165. package/lib/documents/artifacts/ids.js.map +0 -1
  166. package/lib/documents/artifacts/manifest.js +0 -66
  167. package/lib/documents/artifacts/manifest.js.map +0 -1
  168. package/lib/documents/artifacts/store.js +0 -169
  169. package/lib/documents/artifacts/store.js.map +0 -1
  170. package/lib/documents/capabilities.js +0 -93
  171. package/lib/documents/capabilities.js.map +0 -1
  172. package/lib/documents/config.js +0 -302
  173. package/lib/documents/config.js.map +0 -1
  174. package/lib/documents/defaults.js +0 -78
  175. package/lib/documents/defaults.js.map +0 -1
  176. package/lib/documents/errors.js +0 -101
  177. package/lib/documents/errors.js.map +0 -1
  178. package/lib/documents/index.js +0 -80
  179. package/lib/documents/index.js.map +0 -1
  180. package/lib/documents/inspect/facts.js +0 -161
  181. package/lib/documents/inspect/facts.js.map +0 -1
  182. package/lib/documents/inspect/zip.js +0 -108
  183. package/lib/documents/inspect/zip.js.map +0 -1
  184. package/lib/documents/markdown/directives.js +0 -135
  185. package/lib/documents/markdown/directives.js.map +0 -1
  186. package/lib/documents/markdown/frontmatter.js +0 -35
  187. package/lib/documents/markdown/frontmatter.js.map +0 -1
  188. package/lib/documents/markdown/normalize.js +0 -113
  189. package/lib/documents/markdown/normalize.js.map +0 -1
  190. package/lib/documents/orchestrator/assets.js +0 -243
  191. package/lib/documents/orchestrator/assets.js.map +0 -1
  192. package/lib/documents/orchestrator/convert-document.js +0 -186
  193. package/lib/documents/orchestrator/convert-document.js.map +0 -1
  194. package/lib/documents/orchestrator/create-document.js +0 -292
  195. package/lib/documents/orchestrator/create-document.js.map +0 -1
  196. package/lib/documents/orchestrator/extract-document.js +0 -162
  197. package/lib/documents/orchestrator/extract-document.js.map +0 -1
  198. package/lib/documents/orchestrator/inspect-document.js +0 -89
  199. package/lib/documents/orchestrator/inspect-document.js.map +0 -1
  200. package/lib/documents/orchestrator/runtime-deps.js +0 -59
  201. package/lib/documents/orchestrator/runtime-deps.js.map +0 -1
  202. package/lib/documents/orchestrator/scope.js +0 -132
  203. package/lib/documents/orchestrator/scope.js.map +0 -1
  204. package/lib/documents/providers/docling.js +0 -247
  205. package/lib/documents/providers/docling.js.map +0 -1
  206. package/lib/documents/providers/libreoffice.js +0 -130
  207. package/lib/documents/providers/libreoffice.js.map +0 -1
  208. package/lib/documents/providers/markitdown.js +0 -89
  209. package/lib/documents/providers/markitdown.js.map +0 -1
  210. package/lib/documents/providers/pandoc.js +0 -161
  211. package/lib/documents/providers/pandoc.js.map +0 -1
  212. package/lib/documents/providers/process.js +0 -164
  213. package/lib/documents/providers/process.js.map +0 -1
  214. package/lib/documents/providers/registry.js +0 -152
  215. package/lib/documents/providers/registry.js.map +0 -1
  216. package/lib/documents/providers/shared.js +0 -75
  217. package/lib/documents/providers/shared.js.map +0 -1
  218. package/lib/documents/runtime.js +0 -114
  219. package/lib/documents/runtime.js.map +0 -1
  220. package/lib/documents/security/file-types.js +0 -188
  221. package/lib/documents/security/file-types.js.map +0 -1
  222. package/lib/documents/security/limits.js +0 -78
  223. package/lib/documents/security/limits.js.map +0 -1
  224. package/lib/documents/security/mime.js +0 -43
  225. package/lib/documents/security/mime.js.map +0 -1
  226. package/lib/documents/security/paths.js +0 -133
  227. package/lib/documents/security/paths.js.map +0 -1
  228. package/lib/documents/templates/registry.js +0 -147
  229. package/lib/documents/templates/registry.js.map +0 -1
  230. package/lib/documents/templates/resolver.js +0 -59
  231. package/lib/documents/templates/resolver.js.map +0 -1
  232. package/lib/documents/tools/convert.js +0 -125
  233. package/lib/documents/tools/convert.js.map +0 -1
  234. package/lib/documents/tools/create.js +0 -187
  235. package/lib/documents/tools/create.js.map +0 -1
  236. package/lib/documents/tools/index.js +0 -41
  237. package/lib/documents/tools/index.js.map +0 -1
  238. package/lib/documents/tools/inspect.js +0 -135
  239. package/lib/documents/tools/inspect.js.map +0 -1
  240. package/lib/documents/tools/shared.js +0 -88
  241. package/lib/documents/tools/shared.js.map +0 -1
  242. package/lib/documents/tools/to-markdown.js +0 -125
  243. package/lib/documents/tools/to-markdown.js.map +0 -1
  244. package/lib/documents/types.js +0 -12
  245. package/lib/documents/types.js.map +0 -1
  246. package/lib/types/client/settings/sections/documents.d.ts +0 -13
  247. package/lib/types/documents/artifacts/ids.d.ts +0 -14
  248. package/lib/types/documents/artifacts/manifest.d.ts +0 -32
  249. package/lib/types/documents/artifacts/store.d.ts +0 -67
  250. package/lib/types/documents/capabilities.d.ts +0 -32
  251. package/lib/types/documents/config.d.ts +0 -27
  252. package/lib/types/documents/defaults.d.ts +0 -161
  253. package/lib/types/documents/errors.d.ts +0 -42
  254. package/lib/types/documents/index.d.ts +0 -63
  255. package/lib/types/documents/inspect/facts.d.ts +0 -43
  256. package/lib/types/documents/inspect/zip.d.ts +0 -28
  257. package/lib/types/documents/markdown/directives.d.ts +0 -39
  258. package/lib/types/documents/markdown/frontmatter.d.ts +0 -15
  259. package/lib/types/documents/markdown/normalize.d.ts +0 -30
  260. package/lib/types/documents/orchestrator/assets.d.ts +0 -55
  261. package/lib/types/documents/orchestrator/convert-document.d.ts +0 -25
  262. package/lib/types/documents/orchestrator/create-document.d.ts +0 -18
  263. package/lib/types/documents/orchestrator/extract-document.d.ts +0 -24
  264. package/lib/types/documents/orchestrator/inspect-document.d.ts +0 -12
  265. package/lib/types/documents/orchestrator/runtime-deps.d.ts +0 -43
  266. package/lib/types/documents/orchestrator/scope.d.ts +0 -52
  267. package/lib/types/documents/providers/docling.d.ts +0 -54
  268. package/lib/types/documents/providers/libreoffice.d.ts +0 -40
  269. package/lib/types/documents/providers/markitdown.d.ts +0 -28
  270. package/lib/types/documents/providers/pandoc.d.ts +0 -42
  271. package/lib/types/documents/providers/process.d.ts +0 -54
  272. package/lib/types/documents/providers/registry.d.ts +0 -68
  273. package/lib/types/documents/providers/shared.d.ts +0 -27
  274. package/lib/types/documents/runtime.d.ts +0 -59
  275. package/lib/types/documents/security/file-types.d.ts +0 -39
  276. package/lib/types/documents/security/limits.d.ts +0 -24
  277. package/lib/types/documents/security/mime.d.ts +0 -13
  278. package/lib/types/documents/security/paths.d.ts +0 -38
  279. package/lib/types/documents/templates/registry.d.ts +0 -50
  280. package/lib/types/documents/templates/resolver.d.ts +0 -30
  281. package/lib/types/documents/tools/convert.d.ts +0 -9
  282. package/lib/types/documents/tools/create.d.ts +0 -14
  283. package/lib/types/documents/tools/index.d.ts +0 -33
  284. package/lib/types/documents/tools/inspect.d.ts +0 -9
  285. package/lib/types/documents/tools/shared.d.ts +0 -77
  286. package/lib/types/documents/tools/to-markdown.d.ts +0 -12
  287. package/lib/types/documents/types.d.ts +0 -294
@@ -0,0 +1,151 @@
1
+ function describe(tools) {
2
+ return tools.map((tool) => `"${tool}"`).join(", ");
3
+ }
4
+ /**
5
+ * The scoped tool policy of one live agent.
6
+ *
7
+ * Two independent layers enforce the same effective set. `restrict()` decides
8
+ * what the model can see at the next step, and the admission's guard decides
9
+ * what may actually run; a grant widens both, and only up to the ceiling the
10
+ * subrole was configured with. A skill file can therefore ask for anything —
11
+ * the intersection with the role ceiling is what it gets.
12
+ *
13
+ * A restriction may only name tools the scope inherits, so a grant is verified
14
+ * by applying it: a name the registry refuses (agent-local, unregistered) is
15
+ * dropped from the grant instead of breaking the session.
16
+ */
17
+ export class QaAgentToolGrants {
18
+ options;
19
+ active = new Map();
20
+ tools;
21
+ disposeRestriction;
22
+ constructor(options) {
23
+ this.options = options;
24
+ this.tools = new Set(options.baseTools);
25
+ this.applyRestriction([...this.tools]);
26
+ }
27
+ /** Whether the model would see this tool right now. */
28
+ effectiveTools() {
29
+ return this.tools;
30
+ }
31
+ /** Grants currently held, newest last; one entry per activated skill. */
32
+ activeGrants() {
33
+ return [...this.active.values()];
34
+ }
35
+ /**
36
+ * Activate one skill's declared tool requirements.
37
+ *
38
+ * The whole operation is atomic from the caller's point of view: either the
39
+ * grant is recorded and the restriction admits it, or nothing changed and
40
+ * the reason is returned. A strict skill refuses the activation outright; a
41
+ * best-effort one activates and reports what it had to give up.
42
+ * @param skillName - the skill the agent asked to load.
43
+ * @param origin - which activation path asked, for the session record.
44
+ * @returns the outcome, including the model-facing reason on refusal.
45
+ */
46
+ activate(skillName, origin) {
47
+ const descriptor = this.options.descriptors.get(skillName);
48
+ const requested = [...(descriptor?.requiredTools ?? [])];
49
+ const candidates = requested.filter((tool) => this.options.grantableTools.includes(tool));
50
+ const before = [...this.tools];
51
+ const accepted = [];
52
+ for (const tool of candidates) {
53
+ if (this.tools.has(tool)) {
54
+ accepted.push(tool);
55
+ continue;
56
+ }
57
+ try {
58
+ this.applyRestriction([...this.tools, tool]);
59
+ this.tools.add(tool);
60
+ accepted.push(tool);
61
+ }
62
+ catch {
63
+ // The registry refused the name (unregistered or agent-local), so the
64
+ // tool stays out of the grant rather than breaking the activation.
65
+ }
66
+ }
67
+ const denied = requested.filter((tool) => !accepted.includes(tool));
68
+ if (descriptor?.requireAll === true && denied.length > 0) {
69
+ this.restore(before);
70
+ const reason = `Skill "${skillName}" cannot be activated because required tool ${describe(denied)} is unavailable for the current role.`;
71
+ this.commit(skillName, origin, "rejected", requested, [], denied, reason);
72
+ return { status: "rejected", reason };
73
+ }
74
+ const grant = Object.freeze({
75
+ skillName,
76
+ origin,
77
+ requestedTools: Object.freeze(requested),
78
+ grantedTools: Object.freeze(accepted),
79
+ deniedTools: Object.freeze(denied),
80
+ activatedAt: new Date().toISOString(),
81
+ });
82
+ this.active.set(skillName, grant);
83
+ this.options.logger.info("skill-grant.activated", {
84
+ skill: skillName,
85
+ origin,
86
+ granted: accepted,
87
+ denied,
88
+ });
89
+ this.commit(skillName, origin, "activated", requested, accepted, denied);
90
+ const warning = denied.length === 0
91
+ ? undefined
92
+ : [
93
+ "Skill loaded with limited capabilities.",
94
+ "",
95
+ "Unavailable required tools:",
96
+ ...denied.map((tool) => `- ${tool}`),
97
+ ].join("\n");
98
+ return {
99
+ status: "activated",
100
+ grant,
101
+ ...(warning === undefined ? {} : { warning }),
102
+ };
103
+ }
104
+ /** Record an audience refusal; no tool state changes. */
105
+ deny(skillName, origin, reason) {
106
+ const descriptor = this.options.descriptors.get(skillName);
107
+ this.commit(skillName, origin, "denied", descriptor?.requiredTools ?? [], [], descriptor?.requiredTools ?? [], reason);
108
+ }
109
+ /** Lift the restriction this instance owns. Safe to call more than once. */
110
+ dispose() {
111
+ const dispose = this.disposeRestriction;
112
+ this.disposeRestriction = undefined;
113
+ this.active.clear();
114
+ this.tools.clear();
115
+ for (const tool of this.options.baseTools)
116
+ this.tools.add(tool);
117
+ dispose?.();
118
+ }
119
+ /**
120
+ * Swap the scoped restriction, newest first.
121
+ *
122
+ * The new mask is installed before the previous one is lifted: restrictions
123
+ * intersect, so lifting first would leave a window in which the agent is
124
+ * unrestricted, and a rejected name would then leave it that way.
125
+ */
126
+ applyRestriction(allow) {
127
+ const next = this.options.agent.ctx.tools.restrict({ allow: [...allow] });
128
+ const previous = this.disposeRestriction;
129
+ this.disposeRestriction = next;
130
+ previous?.();
131
+ }
132
+ restore(before) {
133
+ this.tools.clear();
134
+ for (const tool of before)
135
+ this.tools.add(tool);
136
+ this.applyRestriction(before);
137
+ }
138
+ commit(skillName, origin, outcome, requested, granted, denied, reason) {
139
+ this.options.record?.(Object.freeze({
140
+ timestamp: new Date().toISOString(),
141
+ skillName,
142
+ origin,
143
+ outcome,
144
+ requestedTools: Object.freeze([...requested]),
145
+ grantedTools: Object.freeze([...granted]),
146
+ deniedTools: Object.freeze([...denied]),
147
+ ...(reason === undefined ? {} : { reason }),
148
+ }));
149
+ }
150
+ }
151
+ //# sourceMappingURL=tool-grants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-grants.js","sourceRoot":"","sources":["../../src/enforcement/tool-grants.ts"],"names":[],"mappings":"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"}
package/lib/index.js CHANGED
@@ -39,11 +39,12 @@ import { WorkspaceId } from "@deepseek-ai/dsh-workspace";
39
39
  import { createHostLoggerSink, getPluginLogger, } from "@yadsh/dsh-plugin-log";
40
40
  import { ConfigSchema, resolveConfig } from "./config.js";
41
41
  import { createQaAccountRemotes } from "./account-remotes.js";
42
+ import { QaAdminService } from "./admin/service.js";
43
+ import { QaQualityStore } from "./admin/quality-store.js";
44
+ import { createSessionLogReader } from "./admin/session-log.js";
42
45
  import { createQaPersonalSkillRemotes, QaPersonalSkillsHost, } from "./personal-skills/index.js";
43
46
  import { QaApprovalGate } from "./approvals.js";
44
47
  import { QaAttestationError, qaAttestationFailureMessage, } from "./attestation.js";
45
- import { applyDocumentsEnvOverrides } from "./documents/config.js";
46
- import { installDocumentSubsystem, } from "./documents/index.js";
47
48
  import { QaQuestionGate } from "./questions.js";
48
49
  import { QaSessionOwnership } from "./session-ownership.js";
49
50
  import { entryRedirectRow } from "./entry-redirect.js";
@@ -51,6 +52,7 @@ import { registerQaNavigationRoute } from "./host-route.js";
51
52
  import { makeLaunchTokenSource } from "./launch-token.js";
52
53
  import { QaIntegrationPrincipalBindings } from "./integration-principals.js";
53
54
  import { QaPolicyAdmission } from "./secure-session.js";
55
+ import { QaAccessService } from "./access/service.js";
54
56
  import { QaPromptNotes } from "./prompt-notes.js";
55
57
  import { QaTools } from "./qa-tools/index.js";
56
58
  import { QaProvenanceHost } from "./provenance/host-store.js";
@@ -95,6 +97,29 @@ let QaSurface = (() => {
95
97
  let _accountsUpdateStarters_decorators;
96
98
  let _describe_decorators;
97
99
  let _createSession_decorators;
100
+ let _accessCurrent_decorators;
101
+ let _accessSession_decorators;
102
+ let _accessAdminSnapshot_decorators;
103
+ let _accessCreateSubrole_decorators;
104
+ let _accessUpdateSubrole_decorators;
105
+ let _accessDeleteSubrole_decorators;
106
+ let _accessUpdateCommon_decorators;
107
+ let _accessUpdateAssignment_decorators;
108
+ let _accessUpdateSkillOverride_decorators;
109
+ let _accessSkillActivations_decorators;
110
+ let _adminOverview_decorators;
111
+ let _adminUsers_decorators;
112
+ let _adminUser_decorators;
113
+ let _adminUpdateUser_decorators;
114
+ let _adminConversations_decorators;
115
+ let _adminConversation_decorators;
116
+ let _adminFeedback_decorators;
117
+ let _adminRateMessage_decorators;
118
+ let _adminReviewQueue_decorators;
119
+ let _adminQueueConversation_decorators;
120
+ let _adminSaveReview_decorators;
121
+ let _adminMetrics_decorators;
122
+ let _adminAudit_decorators;
98
123
  let _secureSession_decorators;
99
124
  let _sources_decorators;
100
125
  let _pendingApprovals_decorators;
@@ -123,6 +148,29 @@ let QaSurface = (() => {
123
148
  _accountsUpdateStarters_decorators = [Remote("accountsUpdateStarters")];
124
149
  _describe_decorators = [Remote("describe")];
125
150
  _createSession_decorators = [Remote("createSession")];
151
+ _accessCurrent_decorators = [Remote("accessCurrent")];
152
+ _accessSession_decorators = [Remote("accessSession")];
153
+ _accessAdminSnapshot_decorators = [Remote("accessAdminSnapshot")];
154
+ _accessCreateSubrole_decorators = [Remote("accessCreateSubrole")];
155
+ _accessUpdateSubrole_decorators = [Remote("accessUpdateSubrole")];
156
+ _accessDeleteSubrole_decorators = [Remote("accessDeleteSubrole")];
157
+ _accessUpdateCommon_decorators = [Remote("accessUpdateCommon")];
158
+ _accessUpdateAssignment_decorators = [Remote("accessUpdateAssignment")];
159
+ _accessUpdateSkillOverride_decorators = [Remote("accessUpdateSkillOverride")];
160
+ _accessSkillActivations_decorators = [Remote("accessSkillActivations")];
161
+ _adminOverview_decorators = [Remote("adminOverview")];
162
+ _adminUsers_decorators = [Remote("adminUsers")];
163
+ _adminUser_decorators = [Remote("adminUser")];
164
+ _adminUpdateUser_decorators = [Remote("adminUpdateUser")];
165
+ _adminConversations_decorators = [Remote("adminConversations")];
166
+ _adminConversation_decorators = [Remote("adminConversation")];
167
+ _adminFeedback_decorators = [Remote("adminFeedback")];
168
+ _adminRateMessage_decorators = [Remote("adminRateMessage")];
169
+ _adminReviewQueue_decorators = [Remote("adminReviewQueue")];
170
+ _adminQueueConversation_decorators = [Remote("adminQueueConversation")];
171
+ _adminSaveReview_decorators = [Remote("adminSaveReview")];
172
+ _adminMetrics_decorators = [Remote("adminMetrics")];
173
+ _adminAudit_decorators = [Remote("adminAudit")];
126
174
  _secureSession_decorators = [Remote("secureSession")];
127
175
  _sources_decorators = [Remote("sources")];
128
176
  _pendingApprovals_decorators = [Remote("pendingApprovals")];
@@ -148,6 +196,29 @@ let QaSurface = (() => {
148
196
  __esDecorate(this, null, _accountsUpdateStarters_decorators, { kind: "method", name: "accountsUpdateStarters", static: false, private: false, access: { has: obj => "accountsUpdateStarters" in obj, get: obj => obj.accountsUpdateStarters }, metadata: _metadata }, null, _instanceExtraInitializers);
149
197
  __esDecorate(this, null, _describe_decorators, { kind: "method", name: "describe", static: false, private: false, access: { has: obj => "describe" in obj, get: obj => obj.describe }, metadata: _metadata }, null, _instanceExtraInitializers);
150
198
  __esDecorate(this, null, _createSession_decorators, { kind: "method", name: "createSession", static: false, private: false, access: { has: obj => "createSession" in obj, get: obj => obj.createSession }, metadata: _metadata }, null, _instanceExtraInitializers);
199
+ __esDecorate(this, null, _accessCurrent_decorators, { kind: "method", name: "accessCurrent", static: false, private: false, access: { has: obj => "accessCurrent" in obj, get: obj => obj.accessCurrent }, metadata: _metadata }, null, _instanceExtraInitializers);
200
+ __esDecorate(this, null, _accessSession_decorators, { kind: "method", name: "accessSession", static: false, private: false, access: { has: obj => "accessSession" in obj, get: obj => obj.accessSession }, metadata: _metadata }, null, _instanceExtraInitializers);
201
+ __esDecorate(this, null, _accessAdminSnapshot_decorators, { kind: "method", name: "accessAdminSnapshot", static: false, private: false, access: { has: obj => "accessAdminSnapshot" in obj, get: obj => obj.accessAdminSnapshot }, metadata: _metadata }, null, _instanceExtraInitializers);
202
+ __esDecorate(this, null, _accessCreateSubrole_decorators, { kind: "method", name: "accessCreateSubrole", static: false, private: false, access: { has: obj => "accessCreateSubrole" in obj, get: obj => obj.accessCreateSubrole }, metadata: _metadata }, null, _instanceExtraInitializers);
203
+ __esDecorate(this, null, _accessUpdateSubrole_decorators, { kind: "method", name: "accessUpdateSubrole", static: false, private: false, access: { has: obj => "accessUpdateSubrole" in obj, get: obj => obj.accessUpdateSubrole }, metadata: _metadata }, null, _instanceExtraInitializers);
204
+ __esDecorate(this, null, _accessDeleteSubrole_decorators, { kind: "method", name: "accessDeleteSubrole", static: false, private: false, access: { has: obj => "accessDeleteSubrole" in obj, get: obj => obj.accessDeleteSubrole }, metadata: _metadata }, null, _instanceExtraInitializers);
205
+ __esDecorate(this, null, _accessUpdateCommon_decorators, { kind: "method", name: "accessUpdateCommon", static: false, private: false, access: { has: obj => "accessUpdateCommon" in obj, get: obj => obj.accessUpdateCommon }, metadata: _metadata }, null, _instanceExtraInitializers);
206
+ __esDecorate(this, null, _accessUpdateAssignment_decorators, { kind: "method", name: "accessUpdateAssignment", static: false, private: false, access: { has: obj => "accessUpdateAssignment" in obj, get: obj => obj.accessUpdateAssignment }, metadata: _metadata }, null, _instanceExtraInitializers);
207
+ __esDecorate(this, null, _accessUpdateSkillOverride_decorators, { kind: "method", name: "accessUpdateSkillOverride", static: false, private: false, access: { has: obj => "accessUpdateSkillOverride" in obj, get: obj => obj.accessUpdateSkillOverride }, metadata: _metadata }, null, _instanceExtraInitializers);
208
+ __esDecorate(this, null, _accessSkillActivations_decorators, { kind: "method", name: "accessSkillActivations", static: false, private: false, access: { has: obj => "accessSkillActivations" in obj, get: obj => obj.accessSkillActivations }, metadata: _metadata }, null, _instanceExtraInitializers);
209
+ __esDecorate(this, null, _adminOverview_decorators, { kind: "method", name: "adminOverview", static: false, private: false, access: { has: obj => "adminOverview" in obj, get: obj => obj.adminOverview }, metadata: _metadata }, null, _instanceExtraInitializers);
210
+ __esDecorate(this, null, _adminUsers_decorators, { kind: "method", name: "adminUsers", static: false, private: false, access: { has: obj => "adminUsers" in obj, get: obj => obj.adminUsers }, metadata: _metadata }, null, _instanceExtraInitializers);
211
+ __esDecorate(this, null, _adminUser_decorators, { kind: "method", name: "adminUser", static: false, private: false, access: { has: obj => "adminUser" in obj, get: obj => obj.adminUser }, metadata: _metadata }, null, _instanceExtraInitializers);
212
+ __esDecorate(this, null, _adminUpdateUser_decorators, { kind: "method", name: "adminUpdateUser", static: false, private: false, access: { has: obj => "adminUpdateUser" in obj, get: obj => obj.adminUpdateUser }, metadata: _metadata }, null, _instanceExtraInitializers);
213
+ __esDecorate(this, null, _adminConversations_decorators, { kind: "method", name: "adminConversations", static: false, private: false, access: { has: obj => "adminConversations" in obj, get: obj => obj.adminConversations }, metadata: _metadata }, null, _instanceExtraInitializers);
214
+ __esDecorate(this, null, _adminConversation_decorators, { kind: "method", name: "adminConversation", static: false, private: false, access: { has: obj => "adminConversation" in obj, get: obj => obj.adminConversation }, metadata: _metadata }, null, _instanceExtraInitializers);
215
+ __esDecorate(this, null, _adminFeedback_decorators, { kind: "method", name: "adminFeedback", static: false, private: false, access: { has: obj => "adminFeedback" in obj, get: obj => obj.adminFeedback }, metadata: _metadata }, null, _instanceExtraInitializers);
216
+ __esDecorate(this, null, _adminRateMessage_decorators, { kind: "method", name: "adminRateMessage", static: false, private: false, access: { has: obj => "adminRateMessage" in obj, get: obj => obj.adminRateMessage }, metadata: _metadata }, null, _instanceExtraInitializers);
217
+ __esDecorate(this, null, _adminReviewQueue_decorators, { kind: "method", name: "adminReviewQueue", static: false, private: false, access: { has: obj => "adminReviewQueue" in obj, get: obj => obj.adminReviewQueue }, metadata: _metadata }, null, _instanceExtraInitializers);
218
+ __esDecorate(this, null, _adminQueueConversation_decorators, { kind: "method", name: "adminQueueConversation", static: false, private: false, access: { has: obj => "adminQueueConversation" in obj, get: obj => obj.adminQueueConversation }, metadata: _metadata }, null, _instanceExtraInitializers);
219
+ __esDecorate(this, null, _adminSaveReview_decorators, { kind: "method", name: "adminSaveReview", static: false, private: false, access: { has: obj => "adminSaveReview" in obj, get: obj => obj.adminSaveReview }, metadata: _metadata }, null, _instanceExtraInitializers);
220
+ __esDecorate(this, null, _adminMetrics_decorators, { kind: "method", name: "adminMetrics", static: false, private: false, access: { has: obj => "adminMetrics" in obj, get: obj => obj.adminMetrics }, metadata: _metadata }, null, _instanceExtraInitializers);
221
+ __esDecorate(this, null, _adminAudit_decorators, { kind: "method", name: "adminAudit", static: false, private: false, access: { has: obj => "adminAudit" in obj, get: obj => obj.adminAudit }, metadata: _metadata }, null, _instanceExtraInitializers);
151
222
  __esDecorate(this, null, _secureSession_decorators, { kind: "method", name: "secureSession", static: false, private: false, access: { has: obj => "secureSession" in obj, get: obj => obj.secureSession }, metadata: _metadata }, null, _instanceExtraInitializers);
152
223
  __esDecorate(this, null, _sources_decorators, { kind: "method", name: "sources", static: false, private: false, access: { has: obj => "sources" in obj, get: obj => obj.sources }, metadata: _metadata }, null, _instanceExtraInitializers);
153
224
  __esDecorate(this, null, _pendingApprovals_decorators, { kind: "method", name: "pendingApprovals", static: false, private: false, access: { has: obj => "pendingApprovals" in obj, get: obj => obj.pendingApprovals }, metadata: _metadata }, null, _instanceExtraInitializers);
@@ -178,6 +249,13 @@ let QaSurface = (() => {
178
249
  tools;
179
250
  /** Account-remote bodies; the wire signatures stay on this class. */
180
251
  accountRemotes;
252
+ /** Roles, assignments, discovery and immutable per-session capability sets. */
253
+ access;
254
+ /**
255
+ * The administrative console: authorization, conversation queries over
256
+ * stored logs, quality records and their aggregations.
257
+ */
258
+ admin;
181
259
  /** Personal skills: storage, the DSH provider and the manual-edit watcher. */
182
260
  personalSkills;
183
261
  /** Personal-skill remote bodies; the wire signatures stay on this class. */
@@ -189,12 +267,10 @@ let QaSurface = (() => {
189
267
  disposeRoute;
190
268
  routeKey;
191
269
  /**
192
- * The document subsystem: its own runtime and the four tool registrations.
193
- * Rebuilt when the document configuration changes and torn down while the
194
- * subsystem or the whole surface is disabled.
270
+ * The quality store opens its file on first use, so a deployment that never
271
+ * opens the admin console never grows one.
195
272
  */
196
- documents;
197
- documentsKey;
273
+ qualityStore;
198
274
  constructor(ctx, entry = {}) {
199
275
  super(ctx, "qaSurface", { namespace: "qaSurface" });
200
276
  const resolvedEntry = resolveConfig(entry);
@@ -207,11 +283,25 @@ let QaSurface = (() => {
207
283
  getConfig: () => this.getConfig(),
208
284
  logger: this.logger,
209
285
  });
286
+ this.access = new QaAccessService(ctx, {
287
+ accounts: () => this.accountRemotes.resolve(this.getConfig()),
288
+ config: () => this.getConfig(),
289
+ logger: this.logger,
290
+ dynamicToolNames: () => this.tools?.catalogToolNames() ?? [],
291
+ });
210
292
  this.personalSkills = new QaPersonalSkillsHost({
211
293
  ctx,
212
294
  getConfig: () => this.getConfig(),
213
295
  logger: this.logger,
214
296
  });
297
+ this.admin = new QaAdminService({
298
+ accounts: () => this.accountRemotes.resolve(this.getConfig()),
299
+ quality: () => this.quality(),
300
+ roles: () => this.access.roles,
301
+ access: () => this.access,
302
+ sessionLog: createSessionLogReader(ctx),
303
+ logger: this.logger,
304
+ });
215
305
  this.skillRemotes = createQaPersonalSkillRemotes({
216
306
  getConfig: () => this.getConfig(),
217
307
  logger: this.logger,
@@ -228,9 +318,10 @@ let QaSurface = (() => {
228
318
  },
229
319
  userWorkspace: (userId, registeredWorkspacePath) => existingQaUserWorkspace(registeredWorkspacePath, userId),
230
320
  },
231
- // Dynamically attached QA tools are not operator-configured allow-list
232
- // entries, so the execution guard reads them per call instead.
233
- (agent) => this.tools?.activeToolNames(agent) ?? []);
321
+ // Legacy account-free sessions retain the dynamic catalog behavior;
322
+ // role-managed sessions authorize its known entries through the frozen
323
+ // capability policy instead.
324
+ (agent) => this.tools?.activeToolNames(agent) ?? [], (token, sessionId, agent) => this.access.policyForSession(token, sessionId, agent), () => this.tools?.catalogToolNames() ?? []);
234
325
  this.provenance = new QaProvenanceHost(ctx, () => this.getConfig(), new FileQaProvenanceSnapshotStore(), (error) => this.logger.error("sources.persistence-failed", {
235
326
  message: error instanceof Error ? error.message : String(error),
236
327
  }));
@@ -266,14 +357,7 @@ let QaSurface = (() => {
266
357
  ctx.effect(() => () => this.provenance.dispose(), "dsh-qa-surface.provenance");
267
358
  ctx.effect(() => () => this.notes.dispose(), "dsh-qa-surface.prompt-notes");
268
359
  ctx.effect(() => () => this.personalSkills.dispose(), "dsh-qa-surface.personal-skills");
269
- ctx.effect(() => () => {
270
- this.documents?.dispose();
271
- this.documents = undefined;
272
- this.documentsKey = undefined;
273
- }, "dsh-qa-surface.documents");
274
- // Registered here rather than from the settings callback alone, so a
275
- // deployment that never opens the settings page still gets the tools.
276
- this.refreshDocuments();
360
+ this.warnDocumentsMoved();
277
361
  // The QA tool catalog is attached per agent, never at boot: nothing here
278
362
  // reaches the model until a managed agent loads the activation skill.
279
363
  this.tools = new QaTools(ctx, {
@@ -299,12 +383,11 @@ let QaSurface = (() => {
299
383
  onChange: () => {
300
384
  const config = this.getConfig();
301
385
  this.refreshRoute();
302
- this.refreshDocuments();
386
+ this.warnDocumentsMoved();
303
387
  this.logger.info("config.updated", {
304
388
  enabled: config.enabled,
305
389
  route: config.route.path,
306
390
  sessionPolicy: config.session.policy,
307
- documents: config.documents.enabled,
308
391
  });
309
392
  },
310
393
  validate: (value) => {
@@ -328,6 +411,11 @@ let QaSurface = (() => {
328
411
  sessionPolicy: resolvedEntry.session.policy,
329
412
  });
330
413
  }
414
+ /** The quality store, opening its file the first time anyone needs it. */
415
+ quality() {
416
+ this.qualityStore ??= new QaQualityStore();
417
+ return this.qualityStore;
418
+ }
331
419
  /** Resolve browser authentication to the caller only; never accepts an id. */
332
420
  principalForToken(token) {
333
421
  const accounts = this.accountRemotes.resolve(this.getConfig());
@@ -417,7 +505,7 @@ let QaSurface = (() => {
417
505
  * cwd is `<configured workspace>/.qa-users/<account UUID>` and the child is
418
506
  * intentionally not registered or attached as another DSH workspace.
419
507
  */
420
- async createSession(token) {
508
+ async createSession(token, subroleId, adminPreview) {
421
509
  const config = this.getConfig();
422
510
  if (config.session.policy === "fixed") {
423
511
  throw new Error("Fixed QA sessions cannot be created.");
@@ -426,7 +514,7 @@ let QaSurface = (() => {
426
514
  const accounts = this.accountRemotes.resolve(config);
427
515
  const owner = accounts === undefined
428
516
  ? undefined
429
- : this.accountRemotes.run(() => accounts.reserveSession(token, String(id)));
517
+ : this.accountRemotes.run(() => this.access.reserveSession(token, String(id), subroleId, adminPreview));
430
518
  let hostCreated = false;
431
519
  try {
432
520
  // Check deployment-only pins before creating a durable Host session.
@@ -485,6 +573,102 @@ let QaSurface = (() => {
485
573
  throw new Error(qaAttestationFailureMessage("Unable to create a QA session.", error), { cause: error });
486
574
  }
487
575
  }
576
+ /** The selector model for the signed-in user; admin grants are irrelevant. */
577
+ accessCurrent(token) {
578
+ return this.accountRemotes.run(() => this.access.current(token));
579
+ }
580
+ /** The immutable role pinned to an existing session. */
581
+ accessSession(token, sessionId) {
582
+ return this.accountRemotes.run(() => this.access.session(token, sessionId), sessionId);
583
+ }
584
+ /** Complete administrator projection; authorization is checked before discovery. */
585
+ async accessAdminSnapshot(token) {
586
+ try {
587
+ return await this.access.adminSnapshot(token);
588
+ }
589
+ catch (error) {
590
+ return this.accountRemotes.run(() => {
591
+ throw error;
592
+ });
593
+ }
594
+ }
595
+ accessCreateSubrole(token, input) {
596
+ return this.accountRemotes.run(() => this.access.createSubrole(token, input));
597
+ }
598
+ accessUpdateSubrole(token, id, input) {
599
+ return this.accountRemotes.run(() => this.access.updateSubrole(token, id, input));
600
+ }
601
+ accessDeleteSubrole(token, id, replacementId) {
602
+ return this.accountRemotes.run(() => {
603
+ this.access.deleteSubrole(token, id, replacementId);
604
+ return { deleted: true };
605
+ });
606
+ }
607
+ accessUpdateCommon(token, input) {
608
+ return this.accountRemotes.run(() => this.access.updateCommon(token, input));
609
+ }
610
+ accessUpdateAssignment(token, userId, input) {
611
+ return this.accountRemotes.run(() => this.access.updateAssignment(token, userId, input));
612
+ }
613
+ /** Layer one administrator assignment over what a SKILL.md declares. */
614
+ accessUpdateSkillOverride(token, input) {
615
+ return this.accountRemotes.run(() => this.access.updateSkillOverride(token, input));
616
+ }
617
+ /** What each skill activation actually granted in this session. */
618
+ accessSkillActivations(token, sessionId) {
619
+ return this.accountRemotes.run(() => this.access.skillActivations(token, sessionId), sessionId);
620
+ }
621
+ // ---------------------------------------------------------------------------
622
+ // Administrative console. Every method names its permission inside the
623
+ // service; the wire carries a token and never an identity.
624
+ // ---------------------------------------------------------------------------
625
+ /** Counters, attention lines and the newest quality signals. */
626
+ adminOverview(token) {
627
+ return this.accountRemotes.runAsync(() => this.admin.overview(token));
628
+ }
629
+ adminUsers(token, query, cursor, limit) {
630
+ return this.accountRemotes.runAsync(() => this.admin.users(token, query, cursor ?? undefined, limit ?? undefined));
631
+ }
632
+ adminUser(token, userId) {
633
+ return this.accountRemotes.runAsync(() => this.admin.user(token, userId));
634
+ }
635
+ /** Authorization role, status and subrole assignment of one account. */
636
+ adminUpdateUser(token, userId, update) {
637
+ return this.accountRemotes.runAsync(() => this.admin.updateUser(token, userId, update));
638
+ }
639
+ adminConversations(token, query, cursor, limit) {
640
+ return this.accountRemotes.runAsync(() => this.admin.conversations(token, query, cursor ?? undefined, limit ?? undefined));
641
+ }
642
+ /** One conversation with its messages, tool calls and review state. */
643
+ adminConversation(token, conversationId) {
644
+ return this.accountRemotes.runAsync(() => this.admin.conversation(token, conversationId));
645
+ }
646
+ adminFeedback(token, query, cursor, limit) {
647
+ return this.accountRemotes.runAsync(() => this.admin.feedback(token, query, cursor ?? undefined, limit ?? undefined));
648
+ }
649
+ /**
650
+ * Rate one of the caller's own assistant messages. The token names the only
651
+ * ratable conversation, exactly as the self-service profile write does.
652
+ */
653
+ adminRateMessage(token, conversationId, messageId, input) {
654
+ return this.accountRemotes.run(() => this.admin.rateMessage(token, conversationId, messageId, input));
655
+ }
656
+ adminReviewQueue(token, cursor, limit) {
657
+ return this.accountRemotes.runAsync(() => this.admin.reviewQueue(token, cursor ?? undefined, limit ?? undefined));
658
+ }
659
+ /** Park a conversation for review without rating it. */
660
+ adminQueueConversation(token, conversationId, messageId) {
661
+ return this.accountRemotes.run(() => this.admin.queueConversation(token, conversationId, messageId ?? undefined));
662
+ }
663
+ adminSaveReview(token, input) {
664
+ return this.accountRemotes.run(() => this.admin.saveReview(token, input));
665
+ }
666
+ adminMetrics(token) {
667
+ return this.accountRemotes.runAsync(() => this.admin.metrics(token));
668
+ }
669
+ adminAudit(token, query, cursor, limit) {
670
+ return this.accountRemotes.runAsync(() => this.admin.audit(token, query, cursor ?? undefined, limit ?? undefined));
671
+ }
488
672
  /** Pin and attest the effective policy. The browser supplies identity only. */
489
673
  async secureSession(token, sessionId) {
490
674
  try {
@@ -652,27 +836,21 @@ let QaSurface = (() => {
652
836
  this.routeKey = key;
653
837
  }
654
838
  /**
655
- * Install, rebuild or tear down the document subsystem. The raw entry is
656
- * resolved with the documented environment overrides applied, so a
657
- * deployment can point `QA_DOCLING_BASE_URL` at its own service without
658
- * touching the settings namespace; the settings layer stays authoritative
659
- * for everything it declares.
839
+ * The document pipeline moved out of this plugin into `@yadsh/dsh-documents`.
840
+ * A deployment whose profile still carries the old `documents` section would
841
+ * otherwise lose its Docling endpoint and artifact root silently, so the
842
+ * leftover section is reported once per configuration change instead.
660
843
  */
661
- refreshDocuments() {
662
- const config = this.getConfig();
663
- const enabled = config.enabled && config.documents.enabled;
664
- const key = enabled ? JSON.stringify(config.documents) : undefined;
665
- if (key === this.documentsKey)
844
+ warnDocumentsMoved() {
845
+ // The section is no longer part of this plugin's schema, so it is read off
846
+ // the raw entry: unknown keys survive schema parsing on purpose.
847
+ const legacy = this.source()
848
+ .documents;
849
+ if (legacy === undefined || Object.keys(legacy).length === 0)
666
850
  return;
667
- this.documents?.dispose();
668
- this.documents = undefined;
669
- this.documentsKey = key;
670
- if (key === undefined)
671
- return;
672
- this.documents = installDocumentSubsystem(this.ctx, {
673
- config: applyDocumentsEnvOverrides(this.source().documents ?? {}, process.env),
674
- logger: this.logger,
675
- register: (definition) => this.ctx.tools.register(definition),
851
+ this.logger.warn("documents.moved", {
852
+ plugin: "@yadsh/dsh-documents",
853
+ message: "the documents section moved to the @yadsh/dsh-documents plugin; the copy under qa-surface is ignored",
676
854
  });
677
855
  }
678
856
  };
@@ -685,8 +863,12 @@ export { entryRedirectRow, entryRedirectScript } from "./entry-redirect.js";
685
863
  export { registerQaNavigationRoute } from "./host-route.js";
686
864
  export { QaIntegrationPrincipalBindings } from "./integration-principals.js";
687
865
  export { qaToolDenial, qaToolPolicyPlan } from "./lockdown-policy.js";
688
- export * from "./documents/index.js";
689
866
  export { QaPolicyAdmission } from "./secure-session.js";
867
+ export { QaAccessService } from "./access/service.js";
868
+ export { QaRoleRepository } from "./access/role-repository.js";
869
+ export { QaAgentToolGrants } from "./enforcement/tool-grants.js";
870
+ export { defaultCapabilityConfig, normalizeCapabilityConfig, normalizeUserAccess, resolveCapabilityPolicy, resolveSkillAccess, } from "./access/model.js";
871
+ export { parseQaSkillMetadata, resolveSkillVisibility, } from "./access/skill-metadata.js";
690
872
  export { QaPromptNotes, renderUserIdentity, QA_IDENTITY_NOTE, QA_SOURCES_NOTE, } from "./prompt-notes.js";
691
873
  export * from "./provenance/index.js";
692
874
  export default QaSurface;