@yadsh/dsh-qa-surface 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (281) hide show
  1. package/README.md +136 -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 +127 -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 +35 -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 +33 -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/styles.js +31 -0
  86. package/lib/client/styles.js.map +1 -1
  87. package/lib/client/types.js.map +1 -1
  88. package/lib/client.js +9908 -4857
  89. package/lib/client.js.map +1 -1
  90. package/lib/config-resolvers/defaults.js +0 -2
  91. package/lib/config-resolvers/defaults.js.map +1 -1
  92. package/lib/config.js +0 -249
  93. package/lib/config.js.map +1 -1
  94. package/lib/enforcement/skill-policy.js +172 -0
  95. package/lib/enforcement/skill-policy.js.map +1 -0
  96. package/lib/enforcement/tool-grants.js +151 -0
  97. package/lib/enforcement/tool-grants.js.map +1 -0
  98. package/lib/index.js +224 -42
  99. package/lib/index.js.map +1 -1
  100. package/lib/personal-skills/service.js +10 -3
  101. package/lib/personal-skills/service.js.map +1 -1
  102. package/lib/qa-tools/index.js +4 -0
  103. package/lib/qa-tools/index.js.map +1 -1
  104. package/lib/resolve-config.js +0 -2
  105. package/lib/resolve-config.js.map +1 -1
  106. package/lib/secure-session.js +71 -17
  107. package/lib/secure-session.js.map +1 -1
  108. package/lib/typert.host.js +2237 -202
  109. package/lib/typert.remote-client.d.ts +49 -3
  110. package/lib/typert.remote-client.js +1863 -183
  111. package/lib/types/access/capability-catalog.d.ts +37 -0
  112. package/lib/types/access/model.d.ts +60 -0
  113. package/lib/types/access/role-repository.d.ts +32 -0
  114. package/lib/types/access/service.d.ts +57 -0
  115. package/lib/types/access/skill-metadata.d.ts +53 -0
  116. package/lib/types/account-remotes.d.ts +6 -0
  117. package/lib/types/accounts/errors.d.ts +1 -1
  118. package/lib/types/accounts/file.d.ts +16 -5
  119. package/lib/types/accounts/store.d.ts +83 -3
  120. package/lib/types/admin/conversation-log.d.ts +39 -0
  121. package/lib/types/admin/index.d.ts +24 -0
  122. package/lib/types/admin/metrics.d.ts +29 -0
  123. package/lib/types/admin/paging.d.ts +33 -0
  124. package/lib/types/admin/permissions.d.ts +10 -0
  125. package/lib/types/admin/quality-store.d.ts +82 -0
  126. package/lib/types/admin/queue.d.ts +21 -0
  127. package/lib/types/admin/redaction.d.ts +29 -0
  128. package/lib/types/admin/service.d.ts +105 -0
  129. package/lib/types/admin/session-log.d.ts +53 -0
  130. package/lib/types/client/QaSessionController.d.ts +12 -1
  131. package/lib/types/client/QaSurface.d.ts +7 -1
  132. package/lib/types/client/admin/QaAdmin.d.ts +17 -0
  133. package/lib/types/client/admin/format.d.ts +43 -0
  134. package/lib/types/client/admin/pages/Conversations.d.ts +21 -0
  135. package/lib/types/client/admin/pages/Overview.d.ts +13 -0
  136. package/lib/types/client/admin/pages/Quality.d.ts +18 -0
  137. package/lib/types/client/admin/pages/Review.d.ts +15 -0
  138. package/lib/types/client/admin/pages/Users.d.ts +22 -0
  139. package/lib/types/client/admin/routes.d.ts +50 -0
  140. package/lib/types/client/admin/shared.d.ts +53 -0
  141. package/lib/types/client/admin/styles.d.ts +11 -0
  142. package/lib/types/client/components/QaHeader.d.ts +5 -1
  143. package/lib/types/client/components/QaMessage.d.ts +14 -1
  144. package/lib/types/client/create-session.d.ts +2 -0
  145. package/lib/types/client/role/RoleSelector.d.ts +14 -0
  146. package/lib/types/client/session-sources.d.ts +9 -0
  147. package/lib/types/client/settings/sections.d.ts +0 -1
  148. package/lib/types/client/types.d.ts +39 -2
  149. package/lib/types/enforcement/skill-policy.d.ts +29 -0
  150. package/lib/types/enforcement/tool-grants.d.ts +84 -0
  151. package/lib/types/index.d.ts +62 -14
  152. package/lib/types/qa-tools/index.d.ts +2 -0
  153. package/lib/types/secure-session.d.ts +10 -1
  154. package/lib/types/types.d.ts +568 -5
  155. package/package.json +1 -1
  156. package/lib/client/settings/sections/documents.js +0 -88
  157. package/lib/client/settings/sections/documents.js.map +0 -1
  158. package/lib/documents/artifacts/ids.js +0 -43
  159. package/lib/documents/artifacts/ids.js.map +0 -1
  160. package/lib/documents/artifacts/manifest.js +0 -66
  161. package/lib/documents/artifacts/manifest.js.map +0 -1
  162. package/lib/documents/artifacts/store.js +0 -169
  163. package/lib/documents/artifacts/store.js.map +0 -1
  164. package/lib/documents/capabilities.js +0 -93
  165. package/lib/documents/capabilities.js.map +0 -1
  166. package/lib/documents/config.js +0 -302
  167. package/lib/documents/config.js.map +0 -1
  168. package/lib/documents/defaults.js +0 -78
  169. package/lib/documents/defaults.js.map +0 -1
  170. package/lib/documents/errors.js +0 -101
  171. package/lib/documents/errors.js.map +0 -1
  172. package/lib/documents/index.js +0 -80
  173. package/lib/documents/index.js.map +0 -1
  174. package/lib/documents/inspect/facts.js +0 -161
  175. package/lib/documents/inspect/facts.js.map +0 -1
  176. package/lib/documents/inspect/zip.js +0 -108
  177. package/lib/documents/inspect/zip.js.map +0 -1
  178. package/lib/documents/markdown/directives.js +0 -135
  179. package/lib/documents/markdown/directives.js.map +0 -1
  180. package/lib/documents/markdown/frontmatter.js +0 -35
  181. package/lib/documents/markdown/frontmatter.js.map +0 -1
  182. package/lib/documents/markdown/normalize.js +0 -113
  183. package/lib/documents/markdown/normalize.js.map +0 -1
  184. package/lib/documents/orchestrator/assets.js +0 -243
  185. package/lib/documents/orchestrator/assets.js.map +0 -1
  186. package/lib/documents/orchestrator/convert-document.js +0 -186
  187. package/lib/documents/orchestrator/convert-document.js.map +0 -1
  188. package/lib/documents/orchestrator/create-document.js +0 -292
  189. package/lib/documents/orchestrator/create-document.js.map +0 -1
  190. package/lib/documents/orchestrator/extract-document.js +0 -162
  191. package/lib/documents/orchestrator/extract-document.js.map +0 -1
  192. package/lib/documents/orchestrator/inspect-document.js +0 -89
  193. package/lib/documents/orchestrator/inspect-document.js.map +0 -1
  194. package/lib/documents/orchestrator/runtime-deps.js +0 -59
  195. package/lib/documents/orchestrator/runtime-deps.js.map +0 -1
  196. package/lib/documents/orchestrator/scope.js +0 -132
  197. package/lib/documents/orchestrator/scope.js.map +0 -1
  198. package/lib/documents/providers/docling.js +0 -247
  199. package/lib/documents/providers/docling.js.map +0 -1
  200. package/lib/documents/providers/libreoffice.js +0 -130
  201. package/lib/documents/providers/libreoffice.js.map +0 -1
  202. package/lib/documents/providers/markitdown.js +0 -89
  203. package/lib/documents/providers/markitdown.js.map +0 -1
  204. package/lib/documents/providers/pandoc.js +0 -161
  205. package/lib/documents/providers/pandoc.js.map +0 -1
  206. package/lib/documents/providers/process.js +0 -164
  207. package/lib/documents/providers/process.js.map +0 -1
  208. package/lib/documents/providers/registry.js +0 -152
  209. package/lib/documents/providers/registry.js.map +0 -1
  210. package/lib/documents/providers/shared.js +0 -75
  211. package/lib/documents/providers/shared.js.map +0 -1
  212. package/lib/documents/runtime.js +0 -114
  213. package/lib/documents/runtime.js.map +0 -1
  214. package/lib/documents/security/file-types.js +0 -188
  215. package/lib/documents/security/file-types.js.map +0 -1
  216. package/lib/documents/security/limits.js +0 -78
  217. package/lib/documents/security/limits.js.map +0 -1
  218. package/lib/documents/security/mime.js +0 -43
  219. package/lib/documents/security/mime.js.map +0 -1
  220. package/lib/documents/security/paths.js +0 -133
  221. package/lib/documents/security/paths.js.map +0 -1
  222. package/lib/documents/templates/registry.js +0 -147
  223. package/lib/documents/templates/registry.js.map +0 -1
  224. package/lib/documents/templates/resolver.js +0 -59
  225. package/lib/documents/templates/resolver.js.map +0 -1
  226. package/lib/documents/tools/convert.js +0 -125
  227. package/lib/documents/tools/convert.js.map +0 -1
  228. package/lib/documents/tools/create.js +0 -187
  229. package/lib/documents/tools/create.js.map +0 -1
  230. package/lib/documents/tools/index.js +0 -41
  231. package/lib/documents/tools/index.js.map +0 -1
  232. package/lib/documents/tools/inspect.js +0 -135
  233. package/lib/documents/tools/inspect.js.map +0 -1
  234. package/lib/documents/tools/shared.js +0 -88
  235. package/lib/documents/tools/shared.js.map +0 -1
  236. package/lib/documents/tools/to-markdown.js +0 -125
  237. package/lib/documents/tools/to-markdown.js.map +0 -1
  238. package/lib/documents/types.js +0 -12
  239. package/lib/documents/types.js.map +0 -1
  240. package/lib/types/client/settings/sections/documents.d.ts +0 -13
  241. package/lib/types/documents/artifacts/ids.d.ts +0 -14
  242. package/lib/types/documents/artifacts/manifest.d.ts +0 -32
  243. package/lib/types/documents/artifacts/store.d.ts +0 -67
  244. package/lib/types/documents/capabilities.d.ts +0 -32
  245. package/lib/types/documents/config.d.ts +0 -27
  246. package/lib/types/documents/defaults.d.ts +0 -161
  247. package/lib/types/documents/errors.d.ts +0 -42
  248. package/lib/types/documents/index.d.ts +0 -63
  249. package/lib/types/documents/inspect/facts.d.ts +0 -43
  250. package/lib/types/documents/inspect/zip.d.ts +0 -28
  251. package/lib/types/documents/markdown/directives.d.ts +0 -39
  252. package/lib/types/documents/markdown/frontmatter.d.ts +0 -15
  253. package/lib/types/documents/markdown/normalize.d.ts +0 -30
  254. package/lib/types/documents/orchestrator/assets.d.ts +0 -55
  255. package/lib/types/documents/orchestrator/convert-document.d.ts +0 -25
  256. package/lib/types/documents/orchestrator/create-document.d.ts +0 -18
  257. package/lib/types/documents/orchestrator/extract-document.d.ts +0 -24
  258. package/lib/types/documents/orchestrator/inspect-document.d.ts +0 -12
  259. package/lib/types/documents/orchestrator/runtime-deps.d.ts +0 -43
  260. package/lib/types/documents/orchestrator/scope.d.ts +0 -52
  261. package/lib/types/documents/providers/docling.d.ts +0 -54
  262. package/lib/types/documents/providers/libreoffice.d.ts +0 -40
  263. package/lib/types/documents/providers/markitdown.d.ts +0 -28
  264. package/lib/types/documents/providers/pandoc.d.ts +0 -42
  265. package/lib/types/documents/providers/process.d.ts +0 -54
  266. package/lib/types/documents/providers/registry.d.ts +0 -68
  267. package/lib/types/documents/providers/shared.d.ts +0 -27
  268. package/lib/types/documents/runtime.d.ts +0 -59
  269. package/lib/types/documents/security/file-types.d.ts +0 -39
  270. package/lib/types/documents/security/limits.d.ts +0 -24
  271. package/lib/types/documents/security/mime.d.ts +0 -13
  272. package/lib/types/documents/security/paths.d.ts +0 -38
  273. package/lib/types/documents/templates/registry.d.ts +0 -50
  274. package/lib/types/documents/templates/resolver.d.ts +0 -30
  275. package/lib/types/documents/tools/convert.d.ts +0 -9
  276. package/lib/types/documents/tools/create.d.ts +0 -14
  277. package/lib/types/documents/tools/index.d.ts +0 -33
  278. package/lib/types/documents/tools/inspect.d.ts +0 -9
  279. package/lib/types/documents/tools/shared.d.ts +0 -77
  280. package/lib/types/documents/tools/to-markdown.d.ts +0 -12
  281. package/lib/types/documents/types.d.ts +0 -294
@@ -0,0 +1,380 @@
1
+ import { createHash } from "node:crypto";
2
+ import { QaAccountsError } from "../accounts/store.js";
3
+ import { QaAgentToolGrants as Grants } from "../enforcement/tool-grants.js";
4
+ import { enabledSubroles, normalizeCapabilityConfig, normalizeUserAccess, resolveCapabilityPolicy, resolveSkillAccess, } from "./model.js";
5
+ import { QaCapabilityCatalog, withMissingCapabilities, } from "./capability-catalog.js";
6
+ import { QaRoleRepository } from "./role-repository.js";
7
+ /** Attempts recorded per session before the oldest ones are dropped. */
8
+ const MAX_SKILL_ACTIVATIONS = 100;
9
+ function configuredCapabilities(config) {
10
+ return {
11
+ tools: [
12
+ ...new Set([
13
+ ...config.common.tools.always,
14
+ ...config.common.tools.skillGrantable,
15
+ ...config.subroles.flatMap(({ capabilities }) => [
16
+ ...capabilities.tools.always,
17
+ ...capabilities.tools.skillGrantable,
18
+ ]),
19
+ ]),
20
+ ],
21
+ skills: [
22
+ ...new Set([
23
+ ...config.common.skills,
24
+ ...config.subroles.flatMap(({ capabilities }) => capabilities.skills),
25
+ ]),
26
+ ],
27
+ };
28
+ }
29
+ /**
30
+ * Opaque revision of everything that shaped one policy.
31
+ *
32
+ * A session records it next to its snapshot so a later review can tell whether
33
+ * a conversation ran under the policy that is in force now.
34
+ */
35
+ function policyRevision(config, metadata, tools) {
36
+ return createHash("sha1")
37
+ .update(JSON.stringify([
38
+ config,
39
+ [...metadata]
40
+ .sort(([left], [right]) => left.localeCompare(right))
41
+ .map(([name, descriptor]) => [
42
+ name,
43
+ descriptor.audience,
44
+ descriptor.requiredTools,
45
+ descriptor.requireAll,
46
+ ]),
47
+ [...tools].sort(),
48
+ ]))
49
+ .digest("hex")
50
+ .slice(0, 16);
51
+ }
52
+ function requireExactAssignment(input, config) {
53
+ const enabled = new Set(enabledSubroles(config).map(({ id }) => id));
54
+ const allowed = [...new Set(input.allowedSubroles)];
55
+ if (allowed.length === 0 ||
56
+ allowed.some((id) => !enabled.has(id)) ||
57
+ !allowed.includes(input.defaultSubrole)) {
58
+ throw new TypeError("assignment must name enabled roles and select one of them as default");
59
+ }
60
+ return Object.freeze({
61
+ allowedSubroles: Object.freeze(allowed),
62
+ defaultSubrole: input.defaultSubrole,
63
+ });
64
+ }
65
+ function freezePolicy(policy) {
66
+ return Object.freeze({
67
+ subroleId: policy.subroleId,
68
+ tools: Object.freeze([...policy.tools]),
69
+ grantableTools: Object.freeze([...policy.grantableTools]),
70
+ skills: Object.freeze([...policy.skills]),
71
+ userSkills: Object.freeze([...policy.userSkills]),
72
+ sources: Object.freeze({
73
+ systemTools: Object.freeze([...policy.sources.systemTools]),
74
+ commonTools: Object.freeze([...policy.sources.commonTools]),
75
+ roleTools: Object.freeze([...policy.sources.roleTools]),
76
+ commonGrantableTools: Object.freeze([
77
+ ...policy.sources.commonGrantableTools,
78
+ ]),
79
+ roleGrantableTools: Object.freeze([...policy.sources.roleGrantableTools]),
80
+ systemSkills: Object.freeze([...policy.sources.systemSkills]),
81
+ commonSkills: Object.freeze([...policy.sources.commonSkills]),
82
+ roleSkills: Object.freeze([...policy.sources.roleSkills]),
83
+ declaredSkills: Object.freeze([...policy.sources.declaredSkills]),
84
+ }),
85
+ missingTools: Object.freeze([...policy.missingTools]),
86
+ missingSkills: Object.freeze([...policy.missingSkills]),
87
+ policyRevision: policy.policyRevision,
88
+ });
89
+ }
90
+ function retainInstalledSnapshot(stored, catalog) {
91
+ const tool = (values) => values.filter((id) => catalog.toolIds.has(id));
92
+ const modelSkill = (values) => values.filter((id) => catalog.skillIds.has(id));
93
+ const anySkill = (values) => values.filter((id) => catalog.userSkillIds.has(id));
94
+ return freezePolicy({
95
+ subroleId: stored.subroleId,
96
+ tools: tool(stored.tools),
97
+ grantableTools: tool(stored.grantableTools),
98
+ skills: modelSkill(stored.skills),
99
+ userSkills: anySkill(stored.userSkills),
100
+ sources: {
101
+ systemTools: tool(stored.sources.systemTools),
102
+ commonTools: tool(stored.sources.commonTools),
103
+ roleTools: tool(stored.sources.roleTools),
104
+ commonGrantableTools: tool(stored.sources.commonGrantableTools),
105
+ roleGrantableTools: tool(stored.sources.roleGrantableTools),
106
+ systemSkills: modelSkill(stored.sources.systemSkills),
107
+ commonSkills: modelSkill(stored.sources.commonSkills),
108
+ roleSkills: modelSkill(stored.sources.roleSkills),
109
+ declaredSkills: modelSkill(stored.sources.declaredSkills),
110
+ },
111
+ missingTools: [
112
+ ...new Set([
113
+ ...stored.missingTools,
114
+ ...[...stored.tools, ...stored.grantableTools].filter((id) => !catalog.toolIds.has(id)),
115
+ ]),
116
+ ],
117
+ missingSkills: [
118
+ ...new Set([
119
+ ...stored.missingSkills,
120
+ ...stored.skills.filter((id) => !catalog.skillIds.has(id)),
121
+ ]),
122
+ ],
123
+ policyRevision: stored.policyRevision,
124
+ });
125
+ }
126
+ /** Server-only orchestration of roles, assignments, discovery and snapshots. */
127
+ export class QaAccessService {
128
+ options;
129
+ roles;
130
+ catalog;
131
+ constructor(ctx, options) {
132
+ this.options = options;
133
+ this.roles = options.repository ?? new QaRoleRepository();
134
+ this.catalog = new QaCapabilityCatalog(ctx, options.dynamicToolNames ?? (() => []), () => this.roles.snapshot().subroles.map(({ id }) => id));
135
+ }
136
+ current(token) {
137
+ const accounts = this.requireAccounts();
138
+ const user = accounts.currentUser(token);
139
+ const config = this.roles.snapshot();
140
+ const access = normalizeUserAccess(accounts.accessOf(user.id), config);
141
+ const allowed = new Set(access.allowedSubroles);
142
+ return Object.freeze({
143
+ subroles: Object.freeze(config.subroles.filter(({ id, enabled }) => enabled && allowed.has(id))),
144
+ defaultSubrole: access.defaultSubrole,
145
+ });
146
+ }
147
+ session(token, sessionId) {
148
+ const accounts = this.requireAccounts();
149
+ const owner = accounts.ensureSessionAccess(token, sessionId);
150
+ const record = accounts.sessionAccess(sessionId);
151
+ const config = this.roles.snapshot();
152
+ const access = normalizeUserAccess(accounts.accessOf(owner.id), config);
153
+ const subroleId = record?.subroleId ?? access.defaultSubrole;
154
+ if (record?.subroleId === undefined) {
155
+ accounts.updateSessionAccess(sessionId, { subroleId });
156
+ }
157
+ const role = config.subroles.find(({ id }) => id === subroleId) ??
158
+ {
159
+ id: subroleId,
160
+ name: subroleId,
161
+ description: "Снимок удалённой саброли",
162
+ enabled: false,
163
+ capabilities: {
164
+ tools: { always: [], skillGrantable: [] },
165
+ skills: [],
166
+ },
167
+ };
168
+ return Object.freeze({
169
+ subrole: role,
170
+ adminPreview: record?.adminPreview === true,
171
+ });
172
+ }
173
+ reserveSession(token, sessionId, requestedSubrole, adminPreview) {
174
+ const accounts = this.requireAccounts();
175
+ const user = accounts.currentUser(token);
176
+ const config = this.roles.snapshot();
177
+ const assignment = normalizeUserAccess(accounts.accessOf(user.id), config);
178
+ const selected = requestedSubrole ?? assignment.defaultSubrole;
179
+ const role = config.subroles.find(({ id, enabled }) => id === selected && enabled);
180
+ if (role === undefined)
181
+ throw new TypeError("QA subrole is unavailable");
182
+ if (adminPreview) {
183
+ if (user.role !== "admin") {
184
+ throw new QaAccountsError("admin-required", "previewing a QA subrole requires an admin account");
185
+ }
186
+ }
187
+ else if (!assignment.allowedSubroles.includes(selected)) {
188
+ throw new QaAccountsError("invalid-role", "this QA subrole is not assigned to the account");
189
+ }
190
+ return accounts.reserveSession(token, sessionId, {
191
+ subroleId: selected,
192
+ ...(adminPreview ? { adminPreview: true } : {}),
193
+ });
194
+ }
195
+ async policyForSession(token, sessionId, agent) {
196
+ const accounts = this.options.accounts();
197
+ if (accounts === undefined)
198
+ return undefined;
199
+ const owner = accounts.ensureSessionAccess(token, sessionId);
200
+ let record = accounts.sessionAccess(sessionId);
201
+ const config = this.roles.snapshot();
202
+ const assignment = normalizeUserAccess(accounts.accessOf(owner.id), config);
203
+ const subroleId = record?.subroleId ?? assignment.defaultSubrole;
204
+ if (record?.subroleId === undefined) {
205
+ record = accounts.updateSessionAccess(sessionId, { subroleId });
206
+ }
207
+ const catalog = await this.catalog.snapshot(agent);
208
+ const policy = record?.capabilitySnapshot === undefined
209
+ ? resolveCapabilityPolicy({
210
+ config,
211
+ subroleId,
212
+ systemTools: this.systemRequiredTools(),
213
+ systemSkills: [],
214
+ available: {
215
+ tools: catalog.toolIds,
216
+ skills: catalog.skillIds,
217
+ userSkills: catalog.userSkillIds,
218
+ },
219
+ skillMetadata: catalog.skillMetadata,
220
+ revision: policyRevision(config, catalog.skillMetadata, catalog.toolIds),
221
+ })
222
+ : retainInstalledSnapshot(record.capabilitySnapshot, catalog);
223
+ if (record?.capabilitySnapshot === undefined) {
224
+ accounts.updateSessionAccess(sessionId, { capabilitySnapshot: policy });
225
+ this.options.logger.info("access.policy-snapshotted", {
226
+ sessionId,
227
+ subroleId,
228
+ tools: policy.tools,
229
+ grantableTools: policy.grantableTools,
230
+ skills: policy.skills,
231
+ revision: policy.policyRevision,
232
+ });
233
+ }
234
+ return {
235
+ policy,
236
+ skills: catalog.skills,
237
+ skillMetadata: catalog.skillMetadata,
238
+ adminPreview: record?.adminPreview === true,
239
+ createGrants: () => new Grants({
240
+ agent,
241
+ baseTools: policy.tools,
242
+ grantableTools: policy.grantableTools,
243
+ descriptors: catalog.skillMetadata,
244
+ logger: this.options.logger,
245
+ record: (entry) => this.recordSkillActivation(sessionId, entry),
246
+ }),
247
+ };
248
+ }
249
+ /** Activation history of one session, for review and quality analysis. */
250
+ skillActivations(token, sessionId) {
251
+ const { accounts } = this.requireAdmin(token);
252
+ return accounts.sessionAccess(sessionId)?.skillActivations ?? [];
253
+ }
254
+ /** Append one activation attempt; a lost record never fails the session. */
255
+ recordSkillActivation(sessionId, entry) {
256
+ const accounts = this.options.accounts();
257
+ if (accounts === undefined)
258
+ return;
259
+ try {
260
+ accounts.recordSkillActivation(sessionId, entry, MAX_SKILL_ACTIVATIONS);
261
+ }
262
+ catch (error) {
263
+ this.options.logger.warn("access.skill-activation-record-failed", {
264
+ sessionId,
265
+ skill: entry.skillName,
266
+ error: error instanceof Error ? error.message : String(error),
267
+ });
268
+ }
269
+ }
270
+ async adminSnapshot(token) {
271
+ const { accounts } = this.requireAdmin(token);
272
+ const config = this.roles.snapshot();
273
+ const catalog = await this.catalog.snapshot();
274
+ const configured = configuredCapabilities(config);
275
+ const systemRequired = Object.freeze({
276
+ tools: Object.freeze({
277
+ always: Object.freeze(this.systemRequiredTools()),
278
+ skillGrantable: Object.freeze([]),
279
+ }),
280
+ skills: Object.freeze([]),
281
+ });
282
+ const rows = withMissingCapabilities(catalog.descriptors, [...systemRequired.tools.always, ...configured.tools], [...systemRequired.skills, ...configured.skills]);
283
+ const skills = resolveSkillAccess({
284
+ config,
285
+ descriptors: catalog.skillMetadata,
286
+ rows: rows.filter(({ type }) => type === "skill"),
287
+ installedTools: catalog.toolIds,
288
+ });
289
+ return Object.freeze({
290
+ config,
291
+ systemRequired,
292
+ catalog: rows,
293
+ skills,
294
+ users: accounts.listAccessUsers((value) => normalizeUserAccess(value, config)),
295
+ audit: this.roles.audit(),
296
+ });
297
+ }
298
+ /** Replace or clear one skill's administrator overlay. */
299
+ updateSkillOverride(token, input) {
300
+ const { actor } = this.requireAdmin(token);
301
+ return this.roles.updateSkillOverride(actor.id, input);
302
+ }
303
+ createSubrole(token, input) {
304
+ const { actor } = this.requireAdmin(token);
305
+ return this.roles.create(actor.id, input);
306
+ }
307
+ updateSubrole(token, id, input) {
308
+ const { actor } = this.requireAdmin(token);
309
+ return this.roles.update(actor.id, id, input);
310
+ }
311
+ deleteSubrole(token, id, replacementId) {
312
+ const { actor, accounts } = this.requireAdmin(token);
313
+ const before = this.roles.snapshot();
314
+ const assigned = accounts
315
+ .listAccessUsers((value) => normalizeUserAccess(value, before))
316
+ .filter(({ access }) => access.allowedSubroles.includes(id));
317
+ if (assigned.length > 0) {
318
+ const replacement = before.subroles.find(({ id: candidate, enabled }) => candidate === replacementId && candidate !== id && enabled);
319
+ if (replacement === undefined) {
320
+ throw new TypeError("deleting an assigned subrole requires an enabled replacement");
321
+ }
322
+ }
323
+ this.roles.delete(actor.id, id);
324
+ const after = this.roles.snapshot();
325
+ for (const user of assigned) {
326
+ const allowed = user.access.allowedSubroles.filter((value) => value !== id);
327
+ if (replacementId !== null && !allowed.includes(replacementId)) {
328
+ allowed.push(replacementId);
329
+ }
330
+ const next = requireExactAssignment({
331
+ allowedSubroles: allowed,
332
+ defaultSubrole: user.access.defaultSubrole === id
333
+ ? replacementId
334
+ : user.access.defaultSubrole,
335
+ }, after);
336
+ accounts.setAccess(user.id, next);
337
+ this.roles.recordAssignment(actor.id, user.id, user.access, next);
338
+ }
339
+ }
340
+ updateCommon(token, input) {
341
+ const { actor } = this.requireAdmin(token);
342
+ return this.roles.updateCommon(actor.id, input);
343
+ }
344
+ updateAssignment(token, userId, input) {
345
+ const { actor, accounts } = this.requireAdmin(token);
346
+ const access = requireExactAssignment(input, this.roles.snapshot());
347
+ const before = accounts.accessOf(userId);
348
+ accounts.setAccess(userId, access);
349
+ this.roles.recordAssignment(actor.id, userId, before, access);
350
+ return access;
351
+ }
352
+ requireAccounts() {
353
+ const accounts = this.options.accounts();
354
+ if (accounts === undefined) {
355
+ throw new Error("QA accounts are required for subrole management");
356
+ }
357
+ return accounts;
358
+ }
359
+ /** The activation diagnostic is runtime plumbing, not an administrator grant. */
360
+ systemRequiredTools() {
361
+ return [
362
+ ...new Set([
363
+ ...this.options.config().lockdown.toolPolicy.allow,
364
+ ...(this.options.dynamicToolNames?.() ?? []).filter((name) => name === "qa_tools_selfcheck"),
365
+ ]),
366
+ ];
367
+ }
368
+ requireAdmin(token) {
369
+ const accounts = this.requireAccounts();
370
+ const actor = accounts.currentUser(token);
371
+ if (actor.role !== "admin") {
372
+ throw new QaAccountsError("admin-required", "QA access administration requires an admin account");
373
+ }
374
+ return { accounts, actor };
375
+ }
376
+ }
377
+ export function validateCapabilityConfig(config) {
378
+ return normalizeCapabilityConfig(config);
379
+ }
380
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/access/service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,234 @@
1
+ /**
2
+ * DSH skill frontmatter carries unknown keys in `metadata`. Everything this
3
+ * plugin understands lives under this one key, so a skill file stays a plain
4
+ * valid Agent Skill outside a QA deployment and no upstream schema is forked.
5
+ */
6
+ const QA_METADATA_KEY = "qa-surface";
7
+ /** Metadata schema this build reads. Unknown versions stay unassigned. */
8
+ const SUPPORTED_SCHEMA_VERSION = 1;
9
+ const CAPABILITY_ID = /^[a-zA-Z0-9][a-zA-Z0-9._:/-]{0,199}$/u;
10
+ const SUBROLE_ID = /^[a-z0-9][a-z0-9-]{0,63}$/u;
11
+ function isPlainObject(value) {
12
+ return typeof value === "object" && value !== null && !Array.isArray(value);
13
+ }
14
+ function strings(value, label, warnings) {
15
+ if (value === undefined)
16
+ return [];
17
+ if (!Array.isArray(value)) {
18
+ warnings.push(`${label} must be a list of capability ids`);
19
+ return [];
20
+ }
21
+ const result = [];
22
+ for (const entry of value) {
23
+ if (typeof entry !== "string" || !CAPABILITY_ID.test(entry.trim())) {
24
+ warnings.push(`${label} contains an invalid id: ${JSON.stringify(entry)}`);
25
+ continue;
26
+ }
27
+ result.push(entry.trim());
28
+ }
29
+ return [...new Set(result)];
30
+ }
31
+ /** The fail-closed descriptor of a skill that declares nothing. */
32
+ export function unassignedSkill(name) {
33
+ return Object.freeze({
34
+ name,
35
+ audience: Object.freeze({ type: "unassigned" }),
36
+ requiredTools: Object.freeze([]),
37
+ requireAll: false,
38
+ lifecycle: "session",
39
+ schemaVersion: 0,
40
+ declared: false,
41
+ warnings: Object.freeze([]),
42
+ });
43
+ }
44
+ function audience(value, knownSubroles, warnings) {
45
+ if (value === undefined)
46
+ return Object.freeze({ type: "unassigned" });
47
+ if (!isPlainObject(value)) {
48
+ warnings.push("audience must be an object");
49
+ return Object.freeze({ type: "unassigned" });
50
+ }
51
+ if (value.type === "common") {
52
+ return Object.freeze({ type: "common" });
53
+ }
54
+ if (value.type !== "subroles") {
55
+ warnings.push(`unsupported audience type: ${JSON.stringify(value.type)}`);
56
+ return Object.freeze({ type: "unassigned" });
57
+ }
58
+ const requested = strings(value.include, "audience.include", warnings);
59
+ const include = [];
60
+ for (const id of requested) {
61
+ if (knownSubroles.has(id)) {
62
+ include.push(id);
63
+ continue;
64
+ }
65
+ // An unknown role fails closed for itself and never invalidates the skill.
66
+ warnings.push(`unknown subrole: ${id}`);
67
+ }
68
+ if (include.length === 0) {
69
+ warnings.push("audience lists no known subrole");
70
+ return Object.freeze({ type: "unassigned" });
71
+ }
72
+ return Object.freeze({
73
+ type: "subroles",
74
+ include: Object.freeze(include),
75
+ });
76
+ }
77
+ /**
78
+ * Read and normalize one skill's `metadata.qa-surface` block.
79
+ *
80
+ * The block is advisory input, never an authority: it decides who may see the
81
+ * skill and which tools the skill needs, while the role ceiling still decides
82
+ * whether a tool can ever be granted. Malformed input degrades to the
83
+ * fail-closed default and is reported instead of throwing, because one broken
84
+ * skill must not take down discovery for the whole deployment.
85
+ * @param name - the skill name the registry resolved, not the metadata's.
86
+ * @param metadata - the raw frontmatter `metadata` object, if any.
87
+ * @param knownSubroles - role ids that currently exist, for typo reporting.
88
+ * @returns the normalized descriptor with every complaint in `warnings`.
89
+ */
90
+ export function parseQaSkillMetadata(name, metadata, knownSubroles) {
91
+ const raw = metadata?.[QA_METADATA_KEY];
92
+ if (!isPlainObject(raw))
93
+ return unassignedSkill(name);
94
+ const warnings = [];
95
+ const version = raw.version;
96
+ if (version !== undefined && version !== SUPPORTED_SCHEMA_VERSION) {
97
+ warnings.push(`unsupported qa-surface metadata version: ${JSON.stringify(version)}`);
98
+ return Object.freeze({
99
+ ...unassignedSkill(name),
100
+ declared: true,
101
+ warnings: Object.freeze(warnings),
102
+ });
103
+ }
104
+ const declaredAudience = audience(raw.audience, knownSubroles, warnings);
105
+ const toolsBlock = isPlainObject(raw.tools) ? raw.tools : undefined;
106
+ if (raw.tools !== undefined && toolsBlock === undefined) {
107
+ warnings.push("tools must be an object");
108
+ }
109
+ const requiredTools = strings(toolsBlock?.requires, "tools.requires", warnings);
110
+ const grant = isPlainObject(toolsBlock?.grant) ? toolsBlock.grant : undefined;
111
+ if (toolsBlock?.grant !== undefined && grant === undefined) {
112
+ warnings.push("tools.grant must be an object");
113
+ }
114
+ let requireAll = false;
115
+ if (grant?.requireAll !== undefined) {
116
+ if (typeof grant.requireAll === "boolean") {
117
+ requireAll = grant.requireAll;
118
+ }
119
+ else {
120
+ warnings.push("tools.grant.requireAll must be a boolean");
121
+ }
122
+ }
123
+ if (grant?.lifecycle !== undefined && grant.lifecycle !== "session") {
124
+ // `turn`/`task` lifecycles are deliberately unsupported in v1: a grant
125
+ // that expires before the model acts on the instructions is a trap.
126
+ warnings.push(`unsupported grant lifecycle: ${JSON.stringify(grant.lifecycle)}; using session`);
127
+ }
128
+ return Object.freeze({
129
+ name,
130
+ audience: declaredAudience,
131
+ requiredTools: Object.freeze(requiredTools),
132
+ requireAll,
133
+ lifecycle: "session",
134
+ schemaVersion: SUPPORTED_SCHEMA_VERSION,
135
+ declared: true,
136
+ warnings: Object.freeze(warnings),
137
+ });
138
+ }
139
+ /** Validate one administrator overlay row before it reaches the policy file. */
140
+ export function normalizeSkillOverride(value) {
141
+ const skillName = String(value.skillName ?? "").trim();
142
+ if (!CAPABILITY_ID.test(skillName)) {
143
+ throw new TypeError("skill override must name a skill");
144
+ }
145
+ const roles = (input, label) => {
146
+ const result = [
147
+ ...new Set((input ?? []).map((entry) => String(entry).trim())),
148
+ ].filter(Boolean);
149
+ if (result.some((entry) => !SUBROLE_ID.test(entry))) {
150
+ throw new TypeError(`${label} must contain subrole ids`);
151
+ }
152
+ return result;
153
+ };
154
+ const add = roles(value.addToSubroles, "addToSubroles");
155
+ const remove = roles(value.removeFromSubroles, "removeFromSubroles");
156
+ const disabled = value.disabled === true;
157
+ const forceCommon = value.forceCommon === true;
158
+ return Object.freeze({
159
+ skillName,
160
+ ...(add.length === 0 ? {} : { addToSubroles: Object.freeze(add) }),
161
+ ...(remove.length === 0
162
+ ? {}
163
+ : { removeFromSubroles: Object.freeze(remove) }),
164
+ ...(forceCommon ? { forceCommon: true } : {}),
165
+ ...(disabled ? { disabled: true } : {}),
166
+ });
167
+ }
168
+ /**
169
+ * Merge one skill's declared audience with its administrator overlay.
170
+ *
171
+ * The declared list is only a default: an administrator may extend it, force
172
+ * the skill on for every role, or withdraw it. A withdrawal always wins over
173
+ * an addition, so a contradictory pair of edits can only narrow access.
174
+ * @param descriptor - normalized metadata of the skill.
175
+ * @param override - administrator overlay, when one exists.
176
+ * @param enabledRoles - ids of subroles that are currently enabled.
177
+ */
178
+ export function resolveSkillVisibility(descriptor, override, enabledRoles) {
179
+ const declaredTo = descriptor.audience.type === "common"
180
+ ? [...enabledRoles]
181
+ : descriptor.audience.type === "subroles"
182
+ ? descriptor.audience.include.filter((id) => enabledRoles.includes(id))
183
+ : [];
184
+ const enabled = new Set(enabledRoles);
185
+ const addedByAdmin = (override?.addToSubroles ?? []).filter((id) => enabled.has(id));
186
+ // Reported as given, not only when it takes something away: a withdrawal must
187
+ // also beat an administrator's own explicit role list, so the caller has to
188
+ // see it for every role it names.
189
+ const removedByAdmin = (override?.removeFromSubroles ?? []).filter((id) => enabled.has(id));
190
+ const disabled = override?.disabled === true;
191
+ const visible = new Set(declaredTo);
192
+ if (override?.forceCommon === true) {
193
+ for (const role of enabledRoles)
194
+ visible.add(role);
195
+ }
196
+ for (const role of addedByAdmin)
197
+ visible.add(role);
198
+ for (const role of removedByAdmin)
199
+ visible.delete(role);
200
+ if (disabled)
201
+ visible.clear();
202
+ const overridden = disabled ||
203
+ override?.forceCommon === true ||
204
+ addedByAdmin.some((id) => !declaredTo.includes(id)) ||
205
+ removedByAdmin.some((id) => declaredTo.includes(id));
206
+ return Object.freeze({
207
+ declaredTo: Object.freeze(declaredTo),
208
+ visibleTo: Object.freeze(enabledRoles.filter((id) => visible.has(id))),
209
+ addedByAdmin: Object.freeze(addedByAdmin),
210
+ removedByAdmin: Object.freeze(removedByAdmin),
211
+ disabled,
212
+ overridden,
213
+ });
214
+ }
215
+ /**
216
+ * Computed health of one skill for the administration table.
217
+ *
218
+ * `blocked` and `degraded` differ only in what `requireAll` promises: a strict
219
+ * skill refuses to activate at all, a best-effort one activates with a warning.
220
+ * @param descriptor - normalized metadata carrying the requirement list.
221
+ * @param available - required tools that are installed and grantable for at
222
+ * least one role that can see the skill.
223
+ * @param missing - required tools no visible role could ever grant.
224
+ * @param visibleTo - roles that currently see the skill.
225
+ */
226
+ export function skillHealth(descriptor, available, missing, visibleTo) {
227
+ if (available + missing === 0) {
228
+ return visibleTo.length === 0 ? "unassigned" : "healthy";
229
+ }
230
+ if (missing === 0)
231
+ return "healthy";
232
+ return descriptor.requireAll ? "blocked" : "degraded";
233
+ }
234
+ //# sourceMappingURL=skill-metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-metadata.js","sourceRoot":"","sources":["../../src/access/skill-metadata.ts"],"names":[],"mappings":"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"}