open-multi-agent-kit 0.91.0 → 0.93.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 (168) hide show
  1. package/CHANGELOG.md +32 -1
  2. package/README.md +2 -2
  3. package/dist/core/agent-session.d.ts +29 -0
  4. package/dist/core/agent-session.d.ts.map +1 -1
  5. package/dist/core/agent-session.js +89 -21
  6. package/dist/core/agent-session.js.map +1 -1
  7. package/dist/core/command-safety.d.ts.map +1 -1
  8. package/dist/core/command-safety.js +0 -50
  9. package/dist/core/command-safety.js.map +1 -1
  10. package/dist/core/compaction/branch-summarization.d.ts +5 -1
  11. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  12. package/dist/core/compaction/branch-summarization.js +5 -7
  13. package/dist/core/compaction/branch-summarization.js.map +1 -1
  14. package/dist/core/compaction/compaction.d.ts +12 -3
  15. package/dist/core/compaction/compaction.d.ts.map +1 -1
  16. package/dist/core/compaction/compaction.js +28 -15
  17. package/dist/core/compaction/compaction.js.map +1 -1
  18. package/dist/core/compaction/transaction.d.ts.map +1 -1
  19. package/dist/core/compaction/transaction.js +7 -3
  20. package/dist/core/compaction/transaction.js.map +1 -1
  21. package/dist/core/context-budget-headroom-candidates.d.ts.map +1 -1
  22. package/dist/core/context-budget-headroom-candidates.js +21 -11
  23. package/dist/core/context-budget-headroom-candidates.js.map +1 -1
  24. package/dist/core/context-budget-system-prompt-items.d.ts +1 -0
  25. package/dist/core/context-budget-system-prompt-items.d.ts.map +1 -1
  26. package/dist/core/context-budget-system-prompt-items.js +7 -8
  27. package/dist/core/context-budget-system-prompt-items.js.map +1 -1
  28. package/dist/core/extensions/builtin/command-safety-gate.d.ts +8 -0
  29. package/dist/core/extensions/builtin/command-safety-gate.d.ts.map +1 -1
  30. package/dist/core/extensions/builtin/command-safety-gate.js +23 -0
  31. package/dist/core/extensions/builtin/command-safety-gate.js.map +1 -1
  32. package/dist/core/extensions/runner.d.ts.map +1 -1
  33. package/dist/core/extensions/runner.js +4 -0
  34. package/dist/core/extensions/runner.js.map +1 -1
  35. package/dist/core/extensions/types.d.ts +2 -0
  36. package/dist/core/extensions/types.d.ts.map +1 -1
  37. package/dist/core/extensions/types.js.map +1 -1
  38. package/dist/core/keybindings.d.ts +5 -0
  39. package/dist/core/keybindings.d.ts.map +1 -1
  40. package/dist/core/keybindings.js +5 -0
  41. package/dist/core/keybindings.js.map +1 -1
  42. package/dist/core/loadouts.d.ts.map +1 -1
  43. package/dist/core/loadouts.js +27 -48
  44. package/dist/core/loadouts.js.map +1 -1
  45. package/dist/core/model-resolver.d.ts +41 -3
  46. package/dist/core/model-resolver.d.ts.map +1 -1
  47. package/dist/core/model-resolver.js +17 -9
  48. package/dist/core/model-resolver.js.map +1 -1
  49. package/dist/core/provider-resilience.d.ts.map +1 -1
  50. package/dist/core/provider-resilience.js +3 -1
  51. package/dist/core/provider-resilience.js.map +1 -1
  52. package/dist/core/reasoning-router-v4-weights.d.ts.map +1 -1
  53. package/dist/core/reasoning-router-v4-weights.js +9 -3
  54. package/dist/core/reasoning-router-v4-weights.js.map +1 -1
  55. package/dist/core/reasoning-router-v4.d.ts.map +1 -1
  56. package/dist/core/reasoning-router-v4.js +94 -24
  57. package/dist/core/reasoning-router-v4.js.map +1 -1
  58. package/dist/core/resource-loader.d.ts.map +1 -1
  59. package/dist/core/resource-loader.js +11 -5
  60. package/dist/core/resource-loader.js.map +1 -1
  61. package/dist/core/session-file-compaction.d.ts.map +1 -1
  62. package/dist/core/session-file-compaction.js +39 -5
  63. package/dist/core/session-file-compaction.js.map +1 -1
  64. package/dist/core/session-termination.d.ts.map +1 -1
  65. package/dist/core/session-termination.js +1 -1
  66. package/dist/core/session-termination.js.map +1 -1
  67. package/dist/core/settings-manager.d.ts +3 -0
  68. package/dist/core/settings-manager.d.ts.map +1 -1
  69. package/dist/core/settings-manager.js +8 -0
  70. package/dist/core/settings-manager.js.map +1 -1
  71. package/dist/core/system-prompt.d.ts.map +1 -1
  72. package/dist/core/system-prompt.js +36 -31
  73. package/dist/core/system-prompt.js.map +1 -1
  74. package/dist/core/tools/bash.d.ts +2 -0
  75. package/dist/core/tools/bash.d.ts.map +1 -1
  76. package/dist/core/tools/bash.js +38 -11
  77. package/dist/core/tools/bash.js.map +1 -1
  78. package/dist/main.d.ts.map +1 -1
  79. package/dist/main.js +112 -11
  80. package/dist/main.js.map +1 -1
  81. package/dist/modes/interactive/components/control-panel-box.d.ts +27 -0
  82. package/dist/modes/interactive/components/control-panel-box.d.ts.map +1 -1
  83. package/dist/modes/interactive/components/control-panel-box.js +60 -8
  84. package/dist/modes/interactive/components/control-panel-box.js.map +1 -1
  85. package/dist/modes/interactive/components/control-panel-layout.d.ts.map +1 -1
  86. package/dist/modes/interactive/components/control-panel-layout.js +100 -45
  87. package/dist/modes/interactive/components/control-panel-layout.js.map +1 -1
  88. package/dist/modes/interactive/components/control-panel-runtime-status.d.ts +9 -0
  89. package/dist/modes/interactive/components/control-panel-runtime-status.d.ts.map +1 -1
  90. package/dist/modes/interactive/components/control-panel-runtime-status.js +10 -8
  91. package/dist/modes/interactive/components/control-panel-runtime-status.js.map +1 -1
  92. package/dist/modes/interactive/components/control-panel-sparkles.d.ts +5 -0
  93. package/dist/modes/interactive/components/control-panel-sparkles.d.ts.map +1 -1
  94. package/dist/modes/interactive/components/control-panel-sparkles.js +14 -9
  95. package/dist/modes/interactive/components/control-panel-sparkles.js.map +1 -1
  96. package/dist/modes/interactive/components/footer.d.ts +10 -0
  97. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  98. package/dist/modes/interactive/components/footer.js +3 -3
  99. package/dist/modes/interactive/components/footer.js.map +1 -1
  100. package/dist/modes/interactive/components/status-sidebar.d.ts +49 -0
  101. package/dist/modes/interactive/components/status-sidebar.d.ts.map +1 -0
  102. package/dist/modes/interactive/components/status-sidebar.js +253 -0
  103. package/dist/modes/interactive/components/status-sidebar.js.map +1 -0
  104. package/dist/modes/interactive/interactive-mode.d.ts +9 -0
  105. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  106. package/dist/modes/interactive/interactive-mode.js +94 -20
  107. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  108. package/dist/modes/interactive/theme/omk-neon-control.json +13 -13
  109. package/dist/modes/print-mode.d.ts.map +1 -1
  110. package/dist/modes/print-mode.js +9 -0
  111. package/dist/modes/print-mode.js.map +1 -1
  112. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  113. package/dist/modes/rpc/rpc-mode.js +1 -0
  114. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  115. package/dist/utils/clipboard.d.ts.map +1 -1
  116. package/dist/utils/clipboard.js +19 -8
  117. package/dist/utils/clipboard.js.map +1 -1
  118. package/docs/adaptorch-preview-spec.md +174 -0
  119. package/docs/adaptorch-preview.md +1 -1
  120. package/docs/compaction.md +20 -13
  121. package/docs/correctness-wall.md +13 -5
  122. package/docs/custom-provider.md +8 -8
  123. package/docs/development.md +2 -2
  124. package/docs/docs.json +4 -0
  125. package/docs/environment-variables.md +90 -0
  126. package/docs/extensions.md +8 -8
  127. package/docs/index.md +1 -0
  128. package/docs/json.md +4 -4
  129. package/docs/providers.md +1 -1
  130. package/docs/rpc.md +5 -2
  131. package/docs/session-format.md +5 -5
  132. package/docs/settings.md +1 -0
  133. package/docs/skills.md +2 -0
  134. package/docs/themes.md +2 -2
  135. package/docs/tui.md +4 -4
  136. package/docs/usage.md +4 -0
  137. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  138. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  139. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  140. package/examples/extensions/gondolin/package-lock.json +2 -2
  141. package/examples/extensions/gondolin/package.json +1 -1
  142. package/examples/extensions/sandbox/package-lock.json +2 -2
  143. package/examples/extensions/sandbox/package.json +1 -1
  144. package/examples/extensions/subagent/README.md +35 -10
  145. package/examples/extensions/subagent/adaptive-agent-runtime.test.ts +234 -0
  146. package/examples/extensions/subagent/adaptive-agent-runtime.ts +240 -0
  147. package/examples/extensions/subagent/adaptive-result.ts +112 -0
  148. package/examples/extensions/subagent/agents.test.ts +86 -0
  149. package/examples/extensions/subagent/agents.ts +18 -4
  150. package/examples/extensions/subagent/capabilities.ts +15 -1
  151. package/examples/extensions/subagent/checkpoint-runtime.test.ts +125 -0
  152. package/examples/extensions/subagent/checkpoint-runtime.ts +198 -0
  153. package/examples/extensions/subagent/deadline-budget.test.ts +135 -0
  154. package/examples/extensions/subagent/deadline-budget.ts +242 -0
  155. package/examples/extensions/subagent/deadline-profile-store.test.ts +72 -0
  156. package/examples/extensions/subagent/deadline-profile-store.ts +172 -0
  157. package/examples/extensions/subagent/domain-profiles.ts +272 -0
  158. package/examples/extensions/subagent/fixtures/fake-omk-json.mjs +13 -0
  159. package/examples/extensions/subagent/fixtures/hanging-process-tree.mjs +40 -0
  160. package/examples/extensions/subagent/index.ts +253 -137
  161. package/examples/extensions/subagent/managed-process.test.ts +178 -0
  162. package/examples/extensions/subagent/managed-process.ts +236 -0
  163. package/examples/extensions/subagent/subagent-extension-smoke.test.ts +112 -0
  164. package/examples/extensions/subagent/subagent-runtime-types.ts +76 -0
  165. package/examples/extensions/with-deps/package-lock.json +2 -2
  166. package/examples/extensions/with-deps/package.json +1 -1
  167. package/npm-shrinkwrap.json +21 -21
  168. package/package.json +10 -7
@@ -1 +1 @@
1
- {"version":3,"file":"loadouts.d.ts","sourceRoot":"","sources":["../../src/core/loadouts.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure loadout / lane-profile algorithms for the OMK control plane.\n *\n * This module is I/O-free. It owns the loadout schema, built-in presets,\n * capability gating (allow/exclude/require selectors), profile validation, and\n * the derivation of scheduler read/write/parallelizable fields from a lane's\n * optional assigned paths. Runtime wiring (AgentSession tool registry, skill\n * prompt construction, MCP runtime, scheduler admission) lives in sibling\n * modules and consumes the decisions made here.\n *\n * Schema and presets follow the OMK package hardening loadout plan.\n *\n * Erasable TypeScript only (no enum/namespace/parameter properties).\n */\n\nimport type { HookPolicyMetadata } from \"./hooks/index.ts\";\n\nexport type LoadoutAuthority =\n\t| \"advisory\"\n\t| \"read-only\"\n\t| \"execute-tests\"\n\t| \"write-scoped\"\n\t| \"review-only\"\n\t| \"security-review\";\n\nexport type LoadoutRole =\n\t| \"planner\"\n\t| \"explorer\"\n\t| \"architect\"\n\t| \"coder\"\n\t| \"executor\"\n\t| \"tester\"\n\t| \"reviewer\"\n\t| \"critic\"\n\t| \"security\"\n\t| \"visual-qa\"\n\t| \"rhwp-doc\"\n\t| \"synthesizer\"\n\t| \"package-maintainer\";\n\n/** Resource kinds the loadout layer can describe. Only the last four are gated here. */\nexport type ResourceKind = \"extension\" | \"skill\" | \"prompt\" | \"theme\" | \"tool\" | \"mcp\" | \"hook\";\nexport type ResourceOrigin = \"package\" | \"top-level\";\nexport type SourceScope = \"user\" | \"project\" | \"temporary\" | \"builtin\";\nexport type CommandMode = \"none\" | \"read-only-shell\" | \"tests-only\" | \"scoped-shell\";\nexport type ToolDefaultMode = \"default-builtins\" | \"no-tools\" | \"no-builtin-tools\";\n\nexport interface NamedResource {\n\tkind: ResourceKind;\n\tname: string;\n\tsource?: string;\n\tscope?: SourceScope;\n\t/** Package-relative or absolute resource path, when meaningful (skills/prompts). */\n\tpath?: string;\n\torigin?: ResourceOrigin;\n\tpolicy?: HookPolicyMetadata;\n}\n\n/**\n * A selector matches inventory resources by name and/or provenance criteria.\n * A resource matches when its kind equals `kind` and every defined criterion\n * matches (names is an OR over the listed names; paths/sources are OR over globs).\n */\nexport interface ResourceSelector {\n\tkind: ResourceKind;\n\tnames?: readonly string[];\n\t/** Glob patterns matched against `NamedResource.path`. */\n\tpaths?: readonly string[];\n\t/** Glob patterns matched against `NamedResource.source`. */\n\tsources?: readonly string[];\n\tscopes?: readonly SourceScope[];\n\torigins?: readonly ResourceOrigin[];\n\t/** Marker only; requirement is expressed by placement in `CapabilityGate.require`. */\n\trequired?: boolean;\n}\n\n/** Tool gating uses flat name arrays (mapped to SDK tools / setActiveTools). */\nexport interface ToolGate {\n\tallow?: readonly string[];\n\texclude?: readonly string[];\n\trequire?: readonly string[];\n\tdefaultMode?: ToolDefaultMode;\n}\n\n/** Skills / MCP / hooks gating uses selector arrays. */\nexport interface CapabilityGate {\n\tallow?: readonly ResourceSelector[];\n\texclude?: readonly ResourceSelector[];\n\trequire?: readonly ResourceSelector[];\n}\n\nexport interface LoadoutCommands {\n\tmode: CommandMode;\n\tallowPatterns?: readonly string[];\n\tblockPatterns?: readonly string[];\n}\n\nexport interface LoadoutEvidence {\n\trequired: boolean;\n\toutputPattern: string;\n}\n\nexport interface LoadoutProfile {\n\tschemaVersion: \"omk.loadout.v1\";\n\tname: string;\n\tdescription?: string;\n\tauthority: LoadoutAuthority;\n\ttools: ToolGate;\n\tskills?: CapabilityGate;\n\tmcp?: CapabilityGate;\n\thooks?: CapabilityGate;\n\tcommands?: LoadoutCommands;\n\tevidence?: LoadoutEvidence;\n}\n\nexport interface CapabilityInventory {\n\ttools: readonly NamedResource[];\n\tskills: readonly NamedResource[];\n\tmcp: readonly NamedResource[];\n\thooks: readonly NamedResource[];\n}\n\nexport interface LaneDefaults {\n\tloadout: string;\n\tauthority: LoadoutAuthority;\n\tparallelizable: boolean;\n\treadOnly: boolean;\n\twritesProductFiles: boolean;\n}\n\nexport interface AppliedLoadout {\n\tprofileName: string;\n\tauthority: LoadoutAuthority;\n\tactiveTools: string[];\n\tactiveSkills: string[];\n\tactiveMcp: string[];\n\tactiveHooks: string[];\n\tblockers: string[];\n\twarnings: string[];\n}\n\nexport interface LoadoutValidation {\n\tvalid: boolean;\n\terrors: string[];\n}\n\n/** A scheduler access entry; shape matches `AccessSetEntry` in the orchestration layer. */\nexport interface LoadoutAccessEntry {\n\tpath: string;\n\tsymbols?: readonly string[];\n}\n\nexport interface SchedulerFields {\n\treadSet: LoadoutAccessEntry[];\n\twriteSet: LoadoutAccessEntry[];\n\tparallelizable: boolean;\n}\n\nexport interface SchedulerDerivationInput {\n\trole: LoadoutRole;\n\tassignedReadPaths?: readonly string[];\n\tassignedWritePaths?: readonly string[];\n}\n\nconst AUTHORITY_RANK: Record<LoadoutAuthority, number> = {\n\tadvisory: 0,\n\t\"read-only\": 1,\n\t\"review-only\": 1,\n\t\"security-review\": 2,\n\t\"execute-tests\": 3,\n\t\"write-scoped\": 4,\n};\n\nconst KNOWN_RESOURCE_KINDS: ReadonlySet<ResourceKind> = new Set([\n\t\"extension\",\n\t\"skill\",\n\t\"prompt\",\n\t\"theme\",\n\t\"tool\",\n\t\"mcp\",\n\t\"hook\",\n]);\n\nconst KNOWN_COMMAND_MODES: ReadonlySet<CommandMode> = new Set([\n\t\"none\",\n\t\"read-only-shell\",\n\t\"tests-only\",\n\t\"scoped-shell\",\n]);\n\nconst KNOWN_TOOL_DEFAULT_MODES: ReadonlySet<ToolDefaultMode> = new Set([\n\t\"default-builtins\",\n\t\"no-tools\",\n\t\"no-builtin-tools\",\n]);\n\n/** Roles permitted to declare a non-empty writeSet during scheduler derivation. */\nconst WRITING_ROLES: ReadonlySet<LoadoutRole> = new Set([\n\t\"coder\",\n\t\"executor\",\n\t\"tester\",\n\t\"rhwp-doc\",\n\t\"synthesizer\",\n\t\"package-maintainer\",\n]);\n\nconst LOCKFILE_BASENAMES: ReadonlySet<string> = new Set([\n\t\"package-lock.json\",\n\t\"npm-shrinkwrap.json\",\n\t\"yarn.lock\",\n\t\"pnpm-lock.yaml\",\n]);\n\nfunction allowNames(kind: ResourceKind, names: readonly string[]): CapabilityGate {\n\treturn { allow: [{ kind, names }] };\n}\n\nexport const BUILTIN_LOADOUTS: Readonly<Record<string, LoadoutProfile>> = {\n\tinspect: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"inspect\",\n\t\tauthority: \"read-only\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\"] },\n\t\tskills: allowNames(\"skill\", [\"understand-chat\", \"analyze\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem-readonly\", \"memory\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\"]),\n\t},\n\tplan: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"plan\",\n\t\tauthority: \"advisory\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\"] },\n\t\tskills: allowNames(\"skill\", [\"adaptorch-route\", \"writing-plans\", \"ddd-software-architecture\"]),\n\t\tmcp: allowNames(\"mcp\", [\"memory\", \"adaptorch\"]),\n\t\thooks: allowNames(\"hook\", [\"session-context\", \"precompact-checkpoint\"]),\n\t},\n\tarchitect: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"architect\",\n\t\tauthority: \"review-only\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"bash\", \"report_finding\"] },\n\t\tskills: allowNames(\"skill\", [\"ddd-software-architecture\", \"code-review\", \"security-review\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem-readonly\", \"memory\", \"context7\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"stop-verify\", \"subagent-stop-audit\"]),\n\t\tcommands: { mode: \"read-only-shell\" },\n\t\tevidence: { required: true, outputPattern: \".omk/runs/<goal>/architect.md\" },\n\t},\n\tcode: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"code\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\"test-driven-development\", \"coding-standards\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\", \"context7\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"typecheck-after-edit\"]),\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\texecutor: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"executor\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\"test-driven-development\", \"coding-standards\", \"verification-before-completion\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\", \"context7\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"typecheck-after-edit\", \"stop-verify\"]),\n\t\tcommands: { mode: \"scoped-shell\" },\n\t\tevidence: { required: true, outputPattern: \".omk/runs/<goal>/implementation.md\" },\n\t},\n\ttest: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"test\",\n\t\tauthority: \"execute-tests\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\"verification-before-completion\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"stop-verify\"]),\n\t\tcommands: { mode: \"tests-only\" },\n\t},\n\treview: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"review\",\n\t\tauthority: \"review-only\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\"] },\n\t\tskills: allowNames(\"skill\", [\"code-review\", \"differential-review\"]),\n\t\tmcp: allowNames(\"mcp\", [\"memory\"]),\n\t\thooks: allowNames(\"hook\", [\"stop-verify\", \"subagent-stop-audit\"]),\n\t},\n\tcritic: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"critic\",\n\t\tauthority: \"review-only\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\"code-review\", \"verification-before-completion\", \"scientific-critical-thinking\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem-readonly\", \"memory\", \"context7\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"stop-verify\", \"subagent-stop-audit\"]),\n\t\tcommands: { mode: \"read-only-shell\" },\n\t\tevidence: { required: true, outputPattern: \".omk/runs/<goal>/critic.md\" },\n\t},\n\tsecurity: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"security\",\n\t\tauthority: \"security-review\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\"security-review\", \"differential-review\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem-readonly\", \"memory\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"stop-verify\"]),\n\t\tcommands: { mode: \"read-only-shell\" },\n\t},\n\t\"visual-qa\": {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"visual-qa\",\n\t\tauthority: \"execute-tests\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\n\t\t\t\"clone-website\",\n\t\t\t\"visual-qa\",\n\t\t\t\"visual-diff\",\n\t\t\t\"visual-regression\",\n\t\t\t\"browser-qa\",\n\t\t\t\"web-quality-audit\",\n\t\t]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\", \"chrome-devtools\", \"playwright\", \"context7\"]),\n\t\thooks: allowNames(\"hook\", [\n\t\t\t\"component-spec-before-build\",\n\t\t\t\"visual-diff-after-edit\",\n\t\t\t\"typecheck-after-edit\",\n\t\t\t\"bounded-evidence\",\n\t\t\t\"protect-secrets\",\n\t\t\t\"stop-verify\",\n\t\t]),\n\t\tcommands: { mode: \"tests-only\" },\n\t\tevidence: { required: true, outputPattern: \".omk/runs/<goal>/visual-qa.md\" },\n\t},\n\t\"rhwp-doc\": {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"rhwp-doc\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\n\t\t\t\"rhwp\",\n\t\t\t\"rhwp-doc\",\n\t\t\t\"document-extraction\",\n\t\t\t\"document-conversion\",\n\t\t\t\"technical-writing\",\n\t\t]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\", \"context7\", \"playwright\"]),\n\t\thooks: allowNames(\"hook\", [\n\t\t\t\"document-artifact-guard\",\n\t\t\t\"bounded-evidence\",\n\t\t\t\"pre-shell-guard\",\n\t\t\t\"protect-secrets\",\n\t\t\t\"stop-verify\",\n\t\t]),\n\t\tcommands: { mode: \"scoped-shell\" },\n\t\tevidence: { required: true, outputPattern: \".omk/runs/<goal>/rhwp-doc.md\" },\n\t},\n\t\"package-maintainer\": {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"package-maintainer\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\n\t\t\t\"exact-pin\",\n\t\t\t\"no-lifecycle-scripts\",\n\t\t\t\"security-review\",\n\t\t\t\"verification-before-completion\",\n\t\t]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"npm-audit-summary\", \"stop-verify\"]),\n\t\tcommands: {\n\t\t\tmode: \"scoped-shell\",\n\t\t\tallowPatterns: [\n\t\t\t\t\"npm install --ignore-scripts*\",\n\t\t\t\t\"npm ci --ignore-scripts*\",\n\t\t\t\t\"npm install --package-lock-only --ignore-scripts*\",\n\t\t\t\t\"node scripts/generate-coding-agent-shrinkwrap.mjs*\",\n\t\t\t],\n\t\t\tblockPatterns: [\n\t\t\t\t\"*@latest*\",\n\t\t\t\t\"npm install *--ignore-scripts=false*\",\n\t\t\t\t\"npm ci *--ignore-scripts=false*\",\n\t\t\t\t\"npm rebuild*\",\n\t\t\t],\n\t\t},\n\t},\n\tnone: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"none\",\n\t\tauthority: \"advisory\",\n\t\ttools: { allow: [], defaultMode: \"no-tools\" },\n\t\tcommands: { mode: \"none\" },\n\t},\n};\n\nexport function inferLoadoutForRole(role: LoadoutRole): string {\n\tswitch (role) {\n\t\tcase \"planner\":\n\t\t\treturn \"plan\";\n\t\tcase \"explorer\":\n\t\t\treturn \"inspect\";\n\t\tcase \"architect\":\n\t\t\treturn \"architect\";\n\t\tcase \"coder\":\n\t\t\treturn \"code\";\n\t\tcase \"executor\":\n\t\t\treturn \"executor\";\n\t\tcase \"tester\":\n\t\t\treturn \"test\";\n\t\tcase \"reviewer\":\n\t\t\treturn \"review\";\n\t\tcase \"critic\":\n\t\t\treturn \"critic\";\n\t\tcase \"security\":\n\t\t\treturn \"security\";\n\t\tcase \"visual-qa\":\n\t\t\treturn \"visual-qa\";\n\t\tcase \"rhwp-doc\":\n\t\t\treturn \"rhwp-doc\";\n\t\tcase \"package-maintainer\":\n\t\t\treturn \"package-maintainer\";\n\t\tcase \"synthesizer\":\n\t\t\treturn \"plan\";\n\t}\n}\n\nexport function authorityWithinGrant(requested: LoadoutAuthority, grant: LoadoutAuthority): boolean {\n\treturn AUTHORITY_RANK[requested] <= AUTHORITY_RANK[grant];\n}\n\nexport function laneDefaultsForRole(role: LoadoutRole): LaneDefaults {\n\tconst loadout = inferLoadoutForRole(role);\n\tconst profile = BUILTIN_LOADOUTS[loadout];\n\treturn {\n\t\tloadout,\n\t\tauthority: profile.authority,\n\t\tparallelizable: profile.authority !== \"write-scoped\",\n\t\treadOnly:\n\t\t\tprofile.authority === \"read-only\" || profile.authority === \"review-only\" || profile.authority === \"advisory\",\n\t\twritesProductFiles: profile.authority === \"write-scoped\",\n\t};\n}\n\nexport function applyLoadoutProfile(\n\tprofile: LoadoutProfile,\n\tinventory: CapabilityInventory,\n\toptions: { grantAuthority?: LoadoutAuthority } = {},\n): AppliedLoadout {\n\tconst blockers: string[] = [];\n\tconst warnings: string[] = [];\n\t// Deterministic blocker order: authority, then tool/skill/mcp/hook requires.\n\tif (options.grantAuthority && !authorityWithinGrant(profile.authority, options.grantAuthority)) {\n\t\tblockers.push(`loadout authority ${profile.authority} exceeds grant ${options.grantAuthority}`);\n\t}\n\n\tconst activeTools = applyToolGate(profile.tools, inventory.tools, blockers, warnings);\n\tconst activeSkills = applyCapabilityGate(\"skill\", profile.skills, inventory.skills, blockers, warnings);\n\tconst activeMcp = applyCapabilityGate(\"mcp\", profile.mcp, inventory.mcp, blockers, warnings);\n\tconst activeHooks = applyCapabilityGate(\"hook\", profile.hooks, inventory.hooks, blockers, warnings);\n\n\treturn {\n\t\tprofileName: profile.name,\n\t\tauthority: profile.authority,\n\t\tactiveTools,\n\t\tactiveSkills,\n\t\tactiveMcp,\n\t\tactiveHooks,\n\t\tblockers,\n\t\twarnings,\n\t};\n}\n\n/**\n * Fail-closed structural validation of a loadout profile. Errors are returned\n * in a deterministic order: schemaVersion, name, authority, tools, skills, mcp,\n * hooks, commands.\n */\nexport function validateLoadoutProfile(profile: LoadoutProfile): LoadoutValidation {\n\tconst errors: string[] = [];\n\tif (profile.schemaVersion !== \"omk.loadout.v1\") {\n\t\terrors.push(`unknown schemaVersion: ${String(profile.schemaVersion)}`);\n\t}\n\tif (typeof profile.name !== \"string\" || profile.name.trim() === \"\") {\n\t\terrors.push(\"missing loadout name\");\n\t}\n\tif (!(profile.authority in AUTHORITY_RANK)) {\n\t\terrors.push(`unknown authority: ${String(profile.authority)}`);\n\t}\n\tvalidateToolGate(profile.tools, errors);\n\tvalidateCapabilityGate(\"skills\", \"skill\", profile.skills, errors);\n\tvalidateCapabilityGate(\"mcp\", \"mcp\", profile.mcp, errors);\n\tvalidateCapabilityGate(\"hooks\", \"hook\", profile.hooks, errors);\n\tif (profile.commands) {\n\t\tif (!KNOWN_COMMAND_MODES.has(profile.commands.mode)) {\n\t\t\terrors.push(`unknown command mode: ${String(profile.commands.mode)}`);\n\t\t} else if (profile.authority in AUTHORITY_RANK) {\n\t\t\tconst conflict = commandModeAuthorityConflict(profile.commands.mode, profile.authority);\n\t\t\tif (conflict) errors.push(conflict);\n\t\t}\n\t}\n\treturn { valid: errors.length === 0, errors };\n}\n\n/**\n * Derive scheduler readSet/writeSet/parallelizable from a lane role plus the\n * optional paths granted to that lane. Non-writing roles never produce a\n * writeSet. parallelizable is false when a write-scoped lane writes anything,\n * or when any write touches a lockfile, package config, snapshot, or git index.\n */\nexport function deriveSchedulerFields(input: SchedulerDerivationInput): SchedulerFields {\n\tconst defaults = laneDefaultsForRole(input.role);\n\tconst readSet = toAccessSet(input.assignedReadPaths);\n\tconst writeSet = WRITING_ROLES.has(input.role) ? toAccessSet(input.assignedWritePaths) : [];\n\tconst parallelizable = deriveParallelizable(defaults.authority, writeSet);\n\treturn { readSet, writeSet, parallelizable };\n}\n\nfunction deriveParallelizable(authority: LoadoutAuthority, writeSet: readonly LoadoutAccessEntry[]): boolean {\n\tif (writeSet.length === 0) return true;\n\tif (authority === \"write-scoped\") return false;\n\tif (writeSet.some((entry) => isSerializeTriggerPath(entry.path))) return false;\n\treturn true;\n}\n\n/** Lockfile, package config, snapshot, or git-index writes force serialization. */\nexport function isSerializeTriggerPath(path: string): boolean {\n\tconst normalized = path.replaceAll(\"\\\\\", \"/\");\n\tconst base = normalized.slice(normalized.lastIndexOf(\"/\") + 1);\n\tif (LOCKFILE_BASENAMES.has(base)) return true;\n\tif (base === \"package.json\") return true;\n\tif (base.endsWith(\".snap\")) return true;\n\tif (normalized === \".git/index\" || normalized.startsWith(\".git/\") || normalized.includes(\"/.git/\")) return true;\n\treturn false;\n}\n\nfunction toAccessSet(paths: readonly string[] | undefined): LoadoutAccessEntry[] {\n\tif (!paths) return [];\n\tconst seen = new Set<string>();\n\tconst entries: LoadoutAccessEntry[] = [];\n\tfor (const raw of paths) {\n\t\tconst path = raw.trim();\n\t\tif (path === \"\" || seen.has(path)) continue;\n\t\tseen.add(path);\n\t\tentries.push({ path });\n\t}\n\tentries.sort((a, b) => compareString(a.path, b.path));\n\treturn entries;\n}\n\nfunction resourceNames(resources: readonly NamedResource[]): Set<string> {\n\treturn new Set(resources.map((resource) => resource.name));\n}\n\nfunction applyToolGate(\n\tgate: ToolGate,\n\tresources: readonly NamedResource[],\n\tblockers: string[],\n\twarnings: string[],\n): string[] {\n\tconst available = resourceNames(resources);\n\tfor (const required of gate.require ?? []) {\n\t\tif (!available.has(required)) blockers.push(`missing required tool: ${required}`);\n\t}\n\tconst base = gate.defaultMode === \"no-tools\" ? [] : (gate.allow ?? resources.map((resource) => resource.name));\n\tconst excluded = new Set(gate.exclude ?? []);\n\tconst active: string[] = [];\n\tfor (const tool of base) {\n\t\tif (!available.has(tool)) {\n\t\t\twarnings.push(`optional tool not available: ${tool}`);\n\t\t\tcontinue;\n\t\t}\n\t\tif (!excluded.has(tool)) active.push(tool);\n\t}\n\treturn [...new Set(active)].sort(compareString);\n}\n\nfunction applyCapabilityGate(\n\tkind: ResourceKind,\n\tgate: CapabilityGate | undefined,\n\tresources: readonly NamedResource[],\n\tblockers: string[],\n\twarnings: string[],\n): string[] {\n\tif (!gate) return [];\n\tconst active = new Set<string>();\n\n\t// require: every required selector must resolve, else a deterministic blocker.\n\tfor (const selector of gate.require ?? []) {\n\t\tresolveRequireSelector(kind, selector, resources, blockers, active);\n\t}\n\n\t// allow: union of matches; warn on named-but-missing optional capabilities.\n\tfor (const selector of gate.allow ?? []) {\n\t\tfor (const match of matchSelector(selector, resources)) active.add(match.name);\n\t\tfor (const name of selector.names ?? []) {\n\t\t\tif (!resources.some((resource) => resource.name === name && matchesCriteria(selector, resource))) {\n\t\t\t\twarnings.push(`optional ${kind} not available: ${name}`);\n\t\t\t}\n\t\t}\n\t}\n\n\t// exclude: applied last.\n\tconst excluded = new Set<string>();\n\tfor (const selector of gate.exclude ?? []) {\n\t\tfor (const match of matchSelector(selector, resources)) excluded.add(match.name);\n\t}\n\n\tconst result = [...active].filter((name) => !excluded.has(name));\n\treturn [...new Set(result)].sort(compareString);\n}\n\nfunction resolveRequireSelector(\n\tkind: ResourceKind,\n\tselector: ResourceSelector,\n\tresources: readonly NamedResource[],\n\tblockers: string[],\n\tactive: Set<string>,\n): void {\n\tif (selector.names && selector.names.length > 0) {\n\t\tfor (const name of selector.names) {\n\t\t\tconst matched = resources.some((resource) => resource.name === name && matchesCriteria(selector, resource));\n\t\t\tif (matched) active.add(name);\n\t\t\telse blockers.push(`missing required ${kind}: ${name}`);\n\t\t}\n\t\treturn;\n\t}\n\tconst matches = matchSelector(selector, resources);\n\tif (matches.length === 0) {\n\t\tblockers.push(`missing required ${kind}: ${describeSelector(selector)}`);\n\t\treturn;\n\t}\n\tfor (const match of matches) active.add(match.name);\n}\n\nfunction matchSelector(selector: ResourceSelector, resources: readonly NamedResource[]): NamedResource[] {\n\treturn resources.filter((resource) => {\n\t\tif (selector.names && !selector.names.includes(resource.name)) return false;\n\t\treturn matchesCriteria(selector, resource);\n\t});\n}\n\nfunction matchesCriteria(selector: ResourceSelector, resource: NamedResource): boolean {\n\tif (resource.kind !== selector.kind) return false;\n\tif (selector.scopes && (resource.scope === undefined || !selector.scopes.includes(resource.scope))) return false;\n\tif (selector.origins && (resource.origin === undefined || !selector.origins.includes(resource.origin))) return false;\n\tif (selector.sources && !selector.sources.some((glob) => globMatch(glob, resource.source ?? \"\"))) return false;\n\tif (selector.paths && !selector.paths.some((glob) => globMatch(glob, resource.path ?? \"\"))) return false;\n\treturn true;\n}\n\nfunction describeSelector(selector: ResourceSelector): string {\n\tconst parts: string[] = [`kind=${selector.kind}`];\n\tif (selector.paths) parts.push(`paths=${selector.paths.join(\",\")}`);\n\tif (selector.sources) parts.push(`sources=${selector.sources.join(\",\")}`);\n\tif (selector.scopes) parts.push(`scopes=${selector.scopes.join(\",\")}`);\n\tif (selector.origins) parts.push(`origins=${selector.origins.join(\",\")}`);\n\treturn parts.join(\" \");\n}\n\nfunction validateToolGate(gate: ToolGate | undefined, errors: string[]): void {\n\tif (!gate) {\n\t\terrors.push(\"missing tools gate\");\n\t\treturn;\n\t}\n\tif (gate.defaultMode !== undefined && !KNOWN_TOOL_DEFAULT_MODES.has(gate.defaultMode)) {\n\t\terrors.push(`unknown tool defaultMode: ${String(gate.defaultMode)}`);\n\t}\n}\n\nfunction validateCapabilityGate(\n\tgateName: string,\n\texpectedKind: ResourceKind,\n\tgate: CapabilityGate | undefined,\n\terrors: string[],\n): void {\n\tif (!gate) return;\n\tfor (const group of [\"allow\", \"exclude\", \"require\"] as const) {\n\t\tconst selectors = gate[group];\n\t\tif (!selectors) continue;\n\t\tfor (const selector of selectors) {\n\t\t\tif (!KNOWN_RESOURCE_KINDS.has(selector.kind)) {\n\t\t\t\terrors.push(`unknown resource kind in ${gateName}.${group}: ${String(selector.kind)}`);\n\t\t\t} else if (selector.kind !== expectedKind) {\n\t\t\t\terrors.push(\n\t\t\t\t\t`mismatched selector kind in ${gateName}.${group}: expected ${expectedKind}, got ${selector.kind}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction commandModeAuthorityConflict(mode: CommandMode, authority: LoadoutAuthority): string | undefined {\n\tif (mode === \"scoped-shell\" && authority !== \"write-scoped\") {\n\t\treturn `command mode scoped-shell requires write-scoped authority, got ${authority}`;\n\t}\n\tif (mode === \"tests-only\" && authority !== \"execute-tests\" && authority !== \"write-scoped\") {\n\t\treturn `command mode tests-only requires execute-tests or write-scoped authority, got ${authority}`;\n\t}\n\treturn undefined;\n}\n\nfunction globMatch(glob: string, value: string): boolean {\n\treturn globToRegExp(glob).test(value);\n}\n\nfunction globToRegExp(glob: string): RegExp {\n\tlet pattern = \"\";\n\tfor (let index = 0; index < glob.length; index++) {\n\t\tconst char = glob[index];\n\t\tif (char === \"*\") {\n\t\t\tif (glob[index + 1] === \"*\") {\n\t\t\t\tpattern += \".*\";\n\t\t\t\tindex++;\n\t\t\t} else {\n\t\t\t\tpattern += \"[^/]*\";\n\t\t\t}\n\t\t} else if (char === \"?\") {\n\t\t\tpattern += \".\";\n\t\t} else {\n\t\t\tpattern += char.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\t\t}\n\t}\n\treturn new RegExp(`^${pattern}$`);\n}\n\nfunction compareString(a: string, b: string): number {\n\tif (a < b) return -1;\n\tif (a > b) return 1;\n\treturn 0;\n}\n"]}
1
+ {"version":3,"file":"loadouts.d.ts","sourceRoot":"","sources":["../../src/core/loadouts.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure loadout / lane-profile algorithms for the OMK control plane.\n *\n * This module is I/O-free. It owns the loadout schema, built-in presets,\n * capability gating (allow/exclude/require selectors), profile validation, and\n * the derivation of scheduler read/write/parallelizable fields from a lane's\n * optional assigned paths. Runtime wiring (AgentSession tool registry, skill\n * prompt construction, MCP runtime, scheduler admission) lives in sibling\n * modules and consumes the decisions made here.\n *\n * Schema and presets follow the OMK package hardening loadout plan.\n *\n * Erasable TypeScript only (no enum/namespace/parameter properties).\n */\n\nimport type { HookPolicyMetadata } from \"./hooks/index.ts\";\n\nexport type LoadoutAuthority =\n\t| \"advisory\"\n\t| \"read-only\"\n\t| \"execute-tests\"\n\t| \"write-scoped\"\n\t| \"review-only\"\n\t| \"security-review\";\n\nexport type LoadoutRole =\n\t| \"planner\"\n\t| \"explorer\"\n\t| \"architect\"\n\t| \"coder\"\n\t| \"executor\"\n\t| \"tester\"\n\t| \"reviewer\"\n\t| \"critic\"\n\t| \"security\"\n\t| \"visual-qa\"\n\t| \"rhwp-doc\"\n\t| \"synthesizer\"\n\t| \"package-maintainer\";\n\n/** Resource kinds the loadout layer can describe. Only the last four are gated here. */\nexport type ResourceKind = \"extension\" | \"skill\" | \"prompt\" | \"theme\" | \"tool\" | \"mcp\" | \"hook\";\nexport type ResourceOrigin = \"package\" | \"top-level\";\nexport type SourceScope = \"user\" | \"project\" | \"temporary\" | \"builtin\";\nexport type CommandMode = \"none\" | \"read-only-shell\" | \"tests-only\" | \"scoped-shell\";\nexport type ToolDefaultMode = \"default-builtins\" | \"no-tools\" | \"no-builtin-tools\";\n\nexport interface NamedResource {\n\tkind: ResourceKind;\n\tname: string;\n\tsource?: string;\n\tscope?: SourceScope;\n\t/** Package-relative or absolute resource path, when meaningful (skills/prompts). */\n\tpath?: string;\n\torigin?: ResourceOrigin;\n\tpolicy?: HookPolicyMetadata;\n}\n\n/**\n * A selector matches inventory resources by name and/or provenance criteria.\n * A resource matches when its kind equals `kind` and every defined criterion\n * matches (names is an OR over the listed names; paths/sources are OR over globs).\n */\nexport interface ResourceSelector {\n\tkind: ResourceKind;\n\tnames?: readonly string[];\n\t/** Glob patterns matched against `NamedResource.path`. */\n\tpaths?: readonly string[];\n\t/** Glob patterns matched against `NamedResource.source`. */\n\tsources?: readonly string[];\n\tscopes?: readonly SourceScope[];\n\torigins?: readonly ResourceOrigin[];\n\t/** Marker only; requirement is expressed by placement in `CapabilityGate.require`. */\n\trequired?: boolean;\n}\n\n/** Tool gating uses flat name arrays (mapped to SDK tools / setActiveTools). */\nexport interface ToolGate {\n\tallow?: readonly string[];\n\texclude?: readonly string[];\n\trequire?: readonly string[];\n\tdefaultMode?: ToolDefaultMode;\n}\n\n/** Skills / MCP / hooks gating uses selector arrays. */\nexport interface CapabilityGate {\n\tallow?: readonly ResourceSelector[];\n\texclude?: readonly ResourceSelector[];\n\trequire?: readonly ResourceSelector[];\n}\n\nexport interface LoadoutCommands {\n\tmode: CommandMode;\n\tallowPatterns?: readonly string[];\n\tblockPatterns?: readonly string[];\n}\n\nexport interface LoadoutEvidence {\n\trequired: boolean;\n\toutputPattern: string;\n}\n\nexport interface LoadoutProfile {\n\tschemaVersion: \"omk.loadout.v1\";\n\tname: string;\n\tdescription?: string;\n\tauthority: LoadoutAuthority;\n\ttools: ToolGate;\n\tskills?: CapabilityGate;\n\tmcp?: CapabilityGate;\n\thooks?: CapabilityGate;\n\tcommands?: LoadoutCommands;\n\tevidence?: LoadoutEvidence;\n}\n\nexport interface CapabilityInventory {\n\ttools: readonly NamedResource[];\n\tskills: readonly NamedResource[];\n\tmcp: readonly NamedResource[];\n\thooks: readonly NamedResource[];\n}\n\nexport interface LaneDefaults {\n\tloadout: string;\n\tauthority: LoadoutAuthority;\n\tparallelizable: boolean;\n\treadOnly: boolean;\n\twritesProductFiles: boolean;\n}\n\nexport interface AppliedLoadout {\n\tprofileName: string;\n\tauthority: LoadoutAuthority;\n\tactiveTools: string[];\n\tactiveSkills: string[];\n\tactiveMcp: string[];\n\tactiveHooks: string[];\n\tblockers: string[];\n\twarnings: string[];\n}\n\nexport interface LoadoutValidation {\n\tvalid: boolean;\n\terrors: string[];\n}\n\n/** A scheduler access entry; shape matches `AccessSetEntry` in the orchestration layer. */\nexport interface LoadoutAccessEntry {\n\tpath: string;\n\tsymbols?: readonly string[];\n}\n\nexport interface SchedulerFields {\n\treadSet: LoadoutAccessEntry[];\n\twriteSet: LoadoutAccessEntry[];\n\tparallelizable: boolean;\n}\n\nexport interface SchedulerDerivationInput {\n\trole: LoadoutRole;\n\tassignedReadPaths?: readonly string[];\n\tassignedWritePaths?: readonly string[];\n}\n\nconst AUTHORITY_RANK: Record<LoadoutAuthority, number> = {\n\tadvisory: 0,\n\t\"read-only\": 1,\n\t\"review-only\": 1,\n\t\"security-review\": 2,\n\t\"execute-tests\": 3,\n\t\"write-scoped\": 4,\n};\n\nconst KNOWN_RESOURCE_KINDS: ReadonlySet<ResourceKind> = new Set([\n\t\"extension\",\n\t\"skill\",\n\t\"prompt\",\n\t\"theme\",\n\t\"tool\",\n\t\"mcp\",\n\t\"hook\",\n]);\n\nconst KNOWN_COMMAND_MODES: ReadonlySet<CommandMode> = new Set([\n\t\"none\",\n\t\"read-only-shell\",\n\t\"tests-only\",\n\t\"scoped-shell\",\n]);\n\nconst KNOWN_TOOL_DEFAULT_MODES: ReadonlySet<ToolDefaultMode> = new Set([\n\t\"default-builtins\",\n\t\"no-tools\",\n\t\"no-builtin-tools\",\n]);\n\n/** Roles permitted to declare a non-empty writeSet during scheduler derivation. */\nconst WRITING_ROLES: ReadonlySet<LoadoutRole> = new Set([\n\t\"coder\",\n\t\"executor\",\n\t\"tester\",\n\t\"rhwp-doc\",\n\t\"synthesizer\",\n\t\"package-maintainer\",\n]);\n\nconst LOCKFILE_BASENAMES: ReadonlySet<string> = new Set([\n\t\"package-lock.json\",\n\t\"npm-shrinkwrap.json\",\n\t\"yarn.lock\",\n\t\"pnpm-lock.yaml\",\n]);\n\nfunction allowNames(kind: ResourceKind, names: readonly string[]): CapabilityGate {\n\treturn { allow: [{ kind, names }] };\n}\n\nexport const BUILTIN_LOADOUTS: Readonly<Record<string, LoadoutProfile>> = {\n\tinspect: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"inspect\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\tplan: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"plan\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\tarchitect: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"architect\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\", \"report_finding\"] },\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\tcode: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"code\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\"test-driven-development\", \"coding-standards\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\", \"context7\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"typecheck-after-edit\"]),\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\texecutor: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"executor\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\"test-driven-development\", \"coding-standards\", \"verification-before-completion\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\", \"context7\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"typecheck-after-edit\", \"stop-verify\"]),\n\t\tcommands: { mode: \"scoped-shell\" },\n\t\tevidence: { required: true, outputPattern: \".omk/runs/<goal>/implementation.md\" },\n\t},\n\ttest: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"test\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\treview: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"review\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\tcritic: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"critic\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\tsecurity: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"security\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\t\"visual-qa\": {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"visual-qa\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\n\t\t\t\"clone-website\",\n\t\t\t\"visual-qa\",\n\t\t\t\"visual-diff\",\n\t\t\t\"visual-regression\",\n\t\t\t\"browser-qa\",\n\t\t\t\"web-quality-audit\",\n\t\t]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\", \"chrome-devtools\", \"playwright\", \"context7\"]),\n\t\thooks: allowNames(\"hook\", [\n\t\t\t\"component-spec-before-build\",\n\t\t\t\"visual-diff-after-edit\",\n\t\t\t\"typecheck-after-edit\",\n\t\t\t\"bounded-evidence\",\n\t\t\t\"protect-secrets\",\n\t\t\t\"stop-verify\",\n\t\t]),\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\t\"rhwp-doc\": {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"rhwp-doc\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\n\t\t\t\"rhwp\",\n\t\t\t\"rhwp-doc\",\n\t\t\t\"document-extraction\",\n\t\t\t\"document-conversion\",\n\t\t\t\"technical-writing\",\n\t\t]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\", \"context7\", \"playwright\"]),\n\t\thooks: allowNames(\"hook\", [\n\t\t\t\"document-artifact-guard\",\n\t\t\t\"bounded-evidence\",\n\t\t\t\"pre-shell-guard\",\n\t\t\t\"protect-secrets\",\n\t\t\t\"stop-verify\",\n\t\t]),\n\t\tcommands: { mode: \"scoped-shell\" },\n\t\tevidence: { required: true, outputPattern: \".omk/runs/<goal>/rhwp-doc.md\" },\n\t},\n\t\"package-maintainer\": {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"package-maintainer\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\n\t\t\t\"exact-pin\",\n\t\t\t\"no-lifecycle-scripts\",\n\t\t\t\"security-review\",\n\t\t\t\"verification-before-completion\",\n\t\t]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"npm-audit-summary\", \"stop-verify\"]),\n\t\tcommands: {\n\t\t\tmode: \"scoped-shell\",\n\t\t\tallowPatterns: [\n\t\t\t\t\"npm install --ignore-scripts*\",\n\t\t\t\t\"npm ci --ignore-scripts*\",\n\t\t\t\t\"npm install --package-lock-only --ignore-scripts*\",\n\t\t\t\t\"node scripts/generate-coding-agent-shrinkwrap.mjs*\",\n\t\t\t],\n\t\t\tblockPatterns: [\n\t\t\t\t\"*@latest*\",\n\t\t\t\t\"npm install *--ignore-scripts=false*\",\n\t\t\t\t\"npm ci *--ignore-scripts=false*\",\n\t\t\t\t\"npm rebuild*\",\n\t\t\t],\n\t\t},\n\t},\n\tnone: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"none\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n};\n\nexport function inferLoadoutForRole(role: LoadoutRole): string {\n\tswitch (role) {\n\t\tcase \"planner\":\n\t\t\treturn \"plan\";\n\t\tcase \"explorer\":\n\t\t\treturn \"inspect\";\n\t\tcase \"architect\":\n\t\t\treturn \"architect\";\n\t\tcase \"coder\":\n\t\t\treturn \"code\";\n\t\tcase \"executor\":\n\t\t\treturn \"executor\";\n\t\tcase \"tester\":\n\t\t\treturn \"test\";\n\t\tcase \"reviewer\":\n\t\t\treturn \"review\";\n\t\tcase \"critic\":\n\t\t\treturn \"critic\";\n\t\tcase \"security\":\n\t\t\treturn \"security\";\n\t\tcase \"visual-qa\":\n\t\t\treturn \"visual-qa\";\n\t\tcase \"rhwp-doc\":\n\t\t\treturn \"rhwp-doc\";\n\t\tcase \"package-maintainer\":\n\t\t\treturn \"package-maintainer\";\n\t\tcase \"synthesizer\":\n\t\t\treturn \"plan\";\n\t}\n}\n\nexport function authorityWithinGrant(requested: LoadoutAuthority, grant: LoadoutAuthority): boolean {\n\treturn AUTHORITY_RANK[requested] <= AUTHORITY_RANK[grant];\n}\n\nexport function laneDefaultsForRole(role: LoadoutRole): LaneDefaults {\n\tconst loadout = inferLoadoutForRole(role);\n\tconst profile = BUILTIN_LOADOUTS[loadout];\n\treturn {\n\t\tloadout,\n\t\tauthority: profile.authority,\n\t\tparallelizable: profile.authority !== \"write-scoped\",\n\t\treadOnly:\n\t\t\tprofile.authority === \"read-only\" || profile.authority === \"review-only\" || profile.authority === \"advisory\",\n\t\twritesProductFiles: profile.authority === \"write-scoped\",\n\t};\n}\n\nexport function applyLoadoutProfile(\n\tprofile: LoadoutProfile,\n\tinventory: CapabilityInventory,\n\toptions: { grantAuthority?: LoadoutAuthority } = {},\n): AppliedLoadout {\n\tconst blockers: string[] = [];\n\tconst warnings: string[] = [];\n\t// Deterministic blocker order: authority, then tool/skill/mcp/hook requires.\n\tif (options.grantAuthority && !authorityWithinGrant(profile.authority, options.grantAuthority)) {\n\t\tblockers.push(`loadout authority ${profile.authority} exceeds grant ${options.grantAuthority}`);\n\t}\n\n\tconst activeTools = applyToolGate(profile.tools, inventory.tools, blockers, warnings);\n\tconst activeSkills = applyCapabilityGate(\"skill\", profile.skills, inventory.skills, blockers, warnings);\n\tconst activeMcp = applyCapabilityGate(\"mcp\", profile.mcp, inventory.mcp, blockers, warnings);\n\tconst activeHooks = applyCapabilityGate(\"hook\", profile.hooks, inventory.hooks, blockers, warnings);\n\n\treturn {\n\t\tprofileName: profile.name,\n\t\tauthority: profile.authority,\n\t\tactiveTools,\n\t\tactiveSkills,\n\t\tactiveMcp,\n\t\tactiveHooks,\n\t\tblockers,\n\t\twarnings,\n\t};\n}\n\n/**\n * Fail-closed structural validation of a loadout profile. Errors are returned\n * in a deterministic order: schemaVersion, name, authority, tools, skills, mcp,\n * hooks, commands.\n */\nexport function validateLoadoutProfile(profile: LoadoutProfile): LoadoutValidation {\n\tconst errors: string[] = [];\n\tif (profile.schemaVersion !== \"omk.loadout.v1\") {\n\t\terrors.push(`unknown schemaVersion: ${String(profile.schemaVersion)}`);\n\t}\n\tif (typeof profile.name !== \"string\" || profile.name.trim() === \"\") {\n\t\terrors.push(\"missing loadout name\");\n\t}\n\tif (!(profile.authority in AUTHORITY_RANK)) {\n\t\terrors.push(`unknown authority: ${String(profile.authority)}`);\n\t}\n\tvalidateToolGate(profile.tools, errors);\n\tvalidateCapabilityGate(\"skills\", \"skill\", profile.skills, errors);\n\tvalidateCapabilityGate(\"mcp\", \"mcp\", profile.mcp, errors);\n\tvalidateCapabilityGate(\"hooks\", \"hook\", profile.hooks, errors);\n\tif (profile.commands) {\n\t\tif (!KNOWN_COMMAND_MODES.has(profile.commands.mode)) {\n\t\t\terrors.push(`unknown command mode: ${String(profile.commands.mode)}`);\n\t\t} else if (profile.authority in AUTHORITY_RANK) {\n\t\t\tconst conflict = commandModeAuthorityConflict(profile.commands.mode, profile.authority);\n\t\t\tif (conflict) errors.push(conflict);\n\t\t}\n\t}\n\treturn { valid: errors.length === 0, errors };\n}\n\n/**\n * Derive scheduler readSet/writeSet/parallelizable from a lane role plus the\n * optional paths granted to that lane. Non-writing roles never produce a\n * writeSet. parallelizable is false when a write-scoped lane writes anything,\n * or when any write touches a lockfile, package config, snapshot, or git index.\n */\nexport function deriveSchedulerFields(input: SchedulerDerivationInput): SchedulerFields {\n\tconst defaults = laneDefaultsForRole(input.role);\n\tconst readSet = toAccessSet(input.assignedReadPaths);\n\tconst writeSet = WRITING_ROLES.has(input.role) ? toAccessSet(input.assignedWritePaths) : [];\n\tconst parallelizable = deriveParallelizable(defaults.authority, writeSet);\n\treturn { readSet, writeSet, parallelizable };\n}\n\nfunction deriveParallelizable(authority: LoadoutAuthority, writeSet: readonly LoadoutAccessEntry[]): boolean {\n\tif (writeSet.length === 0) return true;\n\tif (authority === \"write-scoped\") return false;\n\tif (writeSet.some((entry) => isSerializeTriggerPath(entry.path))) return false;\n\treturn true;\n}\n\n/** Lockfile, package config, snapshot, or git-index writes force serialization. */\nexport function isSerializeTriggerPath(path: string): boolean {\n\tconst normalized = path.replaceAll(\"\\\\\", \"/\");\n\tconst base = normalized.slice(normalized.lastIndexOf(\"/\") + 1);\n\tif (LOCKFILE_BASENAMES.has(base)) return true;\n\tif (base === \"package.json\") return true;\n\tif (base.endsWith(\".snap\")) return true;\n\tif (normalized === \".git/index\" || normalized.startsWith(\".git/\") || normalized.includes(\"/.git/\")) return true;\n\treturn false;\n}\n\nfunction toAccessSet(paths: readonly string[] | undefined): LoadoutAccessEntry[] {\n\tif (!paths) return [];\n\tconst seen = new Set<string>();\n\tconst entries: LoadoutAccessEntry[] = [];\n\tfor (const raw of paths) {\n\t\tconst path = raw.trim();\n\t\tif (path === \"\" || seen.has(path)) continue;\n\t\tseen.add(path);\n\t\tentries.push({ path });\n\t}\n\tentries.sort((a, b) => compareString(a.path, b.path));\n\treturn entries;\n}\n\nfunction resourceNames(resources: readonly NamedResource[]): Set<string> {\n\treturn new Set(resources.map((resource) => resource.name));\n}\n\nfunction applyToolGate(\n\tgate: ToolGate,\n\tresources: readonly NamedResource[],\n\tblockers: string[],\n\twarnings: string[],\n): string[] {\n\tconst available = resourceNames(resources);\n\tfor (const required of gate.require ?? []) {\n\t\tif (!available.has(required)) blockers.push(`missing required tool: ${required}`);\n\t}\n\tconst base = gate.defaultMode === \"no-tools\" ? [] : (gate.allow ?? resources.map((resource) => resource.name));\n\tconst excluded = new Set(gate.exclude ?? []);\n\tconst active: string[] = [];\n\tfor (const tool of base) {\n\t\tif (!available.has(tool)) {\n\t\t\twarnings.push(`optional tool not available: ${tool}`);\n\t\t\tcontinue;\n\t\t}\n\t\tif (!excluded.has(tool)) active.push(tool);\n\t}\n\treturn [...new Set(active)].sort(compareString);\n}\n\nfunction applyCapabilityGate(\n\tkind: ResourceKind,\n\tgate: CapabilityGate | undefined,\n\tresources: readonly NamedResource[],\n\tblockers: string[],\n\twarnings: string[],\n): string[] {\n\tif (!gate) return [];\n\tconst active = new Set<string>();\n\n\t// require: every required selector must resolve, else a deterministic blocker.\n\tfor (const selector of gate.require ?? []) {\n\t\tresolveRequireSelector(kind, selector, resources, blockers, active);\n\t}\n\n\t// allow: union of matches; warn on named-but-missing optional capabilities.\n\tfor (const selector of gate.allow ?? []) {\n\t\tfor (const match of matchSelector(selector, resources)) active.add(match.name);\n\t\tfor (const name of selector.names ?? []) {\n\t\t\tif (!resources.some((resource) => resource.name === name && matchesCriteria(selector, resource))) {\n\t\t\t\twarnings.push(`optional ${kind} not available: ${name}`);\n\t\t\t}\n\t\t}\n\t}\n\n\t// exclude: applied last.\n\tconst excluded = new Set<string>();\n\tfor (const selector of gate.exclude ?? []) {\n\t\tfor (const match of matchSelector(selector, resources)) excluded.add(match.name);\n\t}\n\n\tconst result = [...active].filter((name) => !excluded.has(name));\n\treturn [...new Set(result)].sort(compareString);\n}\n\nfunction resolveRequireSelector(\n\tkind: ResourceKind,\n\tselector: ResourceSelector,\n\tresources: readonly NamedResource[],\n\tblockers: string[],\n\tactive: Set<string>,\n): void {\n\tif (selector.names && selector.names.length > 0) {\n\t\tfor (const name of selector.names) {\n\t\t\tconst matched = resources.some((resource) => resource.name === name && matchesCriteria(selector, resource));\n\t\t\tif (matched) active.add(name);\n\t\t\telse blockers.push(`missing required ${kind}: ${name}`);\n\t\t}\n\t\treturn;\n\t}\n\tconst matches = matchSelector(selector, resources);\n\tif (matches.length === 0) {\n\t\tblockers.push(`missing required ${kind}: ${describeSelector(selector)}`);\n\t\treturn;\n\t}\n\tfor (const match of matches) active.add(match.name);\n}\n\nfunction matchSelector(selector: ResourceSelector, resources: readonly NamedResource[]): NamedResource[] {\n\treturn resources.filter((resource) => {\n\t\tif (selector.names && !selector.names.includes(resource.name)) return false;\n\t\treturn matchesCriteria(selector, resource);\n\t});\n}\n\nfunction matchesCriteria(selector: ResourceSelector, resource: NamedResource): boolean {\n\tif (resource.kind !== selector.kind) return false;\n\tif (selector.scopes && (resource.scope === undefined || !selector.scopes.includes(resource.scope))) return false;\n\tif (selector.origins && (resource.origin === undefined || !selector.origins.includes(resource.origin))) return false;\n\tif (selector.sources && !selector.sources.some((glob) => globMatch(glob, resource.source ?? \"\"))) return false;\n\tif (selector.paths && !selector.paths.some((glob) => globMatch(glob, resource.path ?? \"\"))) return false;\n\treturn true;\n}\n\nfunction describeSelector(selector: ResourceSelector): string {\n\tconst parts: string[] = [`kind=${selector.kind}`];\n\tif (selector.paths) parts.push(`paths=${selector.paths.join(\",\")}`);\n\tif (selector.sources) parts.push(`sources=${selector.sources.join(\",\")}`);\n\tif (selector.scopes) parts.push(`scopes=${selector.scopes.join(\",\")}`);\n\tif (selector.origins) parts.push(`origins=${selector.origins.join(\",\")}`);\n\treturn parts.join(\" \");\n}\n\nfunction validateToolGate(gate: ToolGate | undefined, errors: string[]): void {\n\tif (!gate) {\n\t\terrors.push(\"missing tools gate\");\n\t\treturn;\n\t}\n\tif (gate.defaultMode !== undefined && !KNOWN_TOOL_DEFAULT_MODES.has(gate.defaultMode)) {\n\t\terrors.push(`unknown tool defaultMode: ${String(gate.defaultMode)}`);\n\t}\n}\n\nfunction validateCapabilityGate(\n\tgateName: string,\n\texpectedKind: ResourceKind,\n\tgate: CapabilityGate | undefined,\n\terrors: string[],\n): void {\n\tif (!gate) return;\n\tfor (const group of [\"allow\", \"exclude\", \"require\"] as const) {\n\t\tconst selectors = gate[group];\n\t\tif (!selectors) continue;\n\t\tfor (const selector of selectors) {\n\t\t\tif (!KNOWN_RESOURCE_KINDS.has(selector.kind)) {\n\t\t\t\terrors.push(`unknown resource kind in ${gateName}.${group}: ${String(selector.kind)}`);\n\t\t\t} else if (selector.kind !== expectedKind) {\n\t\t\t\terrors.push(\n\t\t\t\t\t`mismatched selector kind in ${gateName}.${group}: expected ${expectedKind}, got ${selector.kind}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction commandModeAuthorityConflict(mode: CommandMode, authority: LoadoutAuthority): string | undefined {\n\tif (mode === \"scoped-shell\" && authority !== \"write-scoped\") {\n\t\treturn `command mode scoped-shell requires write-scoped authority, got ${authority}`;\n\t}\n\tif (mode === \"tests-only\" && authority !== \"execute-tests\" && authority !== \"write-scoped\") {\n\t\treturn `command mode tests-only requires execute-tests or write-scoped authority, got ${authority}`;\n\t}\n\treturn undefined;\n}\n\nfunction globMatch(glob: string, value: string): boolean {\n\treturn globToRegExp(glob).test(value);\n}\n\nfunction globToRegExp(glob: string): RegExp {\n\tlet pattern = \"\";\n\tfor (let index = 0; index < glob.length; index++) {\n\t\tconst char = glob[index];\n\t\tif (char === \"*\") {\n\t\t\tif (glob[index + 1] === \"*\") {\n\t\t\t\tpattern += \".*\";\n\t\t\t\tindex++;\n\t\t\t} else {\n\t\t\t\tpattern += \"[^/]*\";\n\t\t\t}\n\t\t} else if (char === \"?\") {\n\t\t\tpattern += \".\";\n\t\t} else {\n\t\t\tpattern += char.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\t\t}\n\t}\n\treturn new RegExp(`^${pattern}$`);\n}\n\nfunction compareString(a: string, b: string): number {\n\tif (a < b) return -1;\n\tif (a > b) return 1;\n\treturn 0;\n}\n"]}
@@ -62,31 +62,23 @@ export const BUILTIN_LOADOUTS = {
62
62
  inspect: {
63
63
  schemaVersion: "omk.loadout.v1",
64
64
  name: "inspect",
65
- authority: "read-only",
66
- tools: { allow: ["read", "grep", "find", "ls"] },
67
- skills: allowNames("skill", ["understand-chat", "analyze"]),
68
- mcp: allowNames("mcp", ["filesystem-readonly", "memory"]),
69
- hooks: allowNames("hook", ["pre-shell-guard", "protect-secrets"]),
65
+ authority: "write-scoped",
66
+ tools: { allow: ["read", "grep", "find", "ls", "edit", "write", "bash"] },
67
+ commands: { mode: "scoped-shell" },
70
68
  },
71
69
  plan: {
72
70
  schemaVersion: "omk.loadout.v1",
73
71
  name: "plan",
74
- authority: "advisory",
75
- tools: { allow: ["read", "grep", "find", "ls"] },
76
- skills: allowNames("skill", ["adaptorch-route", "writing-plans", "ddd-software-architecture"]),
77
- mcp: allowNames("mcp", ["memory", "adaptorch"]),
78
- hooks: allowNames("hook", ["session-context", "precompact-checkpoint"]),
72
+ authority: "write-scoped",
73
+ tools: { allow: ["read", "grep", "find", "ls", "edit", "write", "bash"] },
74
+ commands: { mode: "scoped-shell" },
79
75
  },
80
76
  architect: {
81
77
  schemaVersion: "omk.loadout.v1",
82
78
  name: "architect",
83
- authority: "review-only",
84
- tools: { allow: ["read", "grep", "find", "ls", "bash", "report_finding"] },
85
- skills: allowNames("skill", ["ddd-software-architecture", "code-review", "security-review"]),
86
- mcp: allowNames("mcp", ["filesystem-readonly", "memory", "context7"]),
87
- hooks: allowNames("hook", ["pre-shell-guard", "protect-secrets", "stop-verify", "subagent-stop-audit"]),
88
- commands: { mode: "read-only-shell" },
89
- evidence: { required: true, outputPattern: ".omk/runs/<goal>/architect.md" },
79
+ authority: "write-scoped",
80
+ tools: { allow: ["read", "grep", "find", "ls", "edit", "write", "bash", "report_finding"] },
81
+ commands: { mode: "scoped-shell" },
90
82
  },
91
83
  code: {
92
84
  schemaVersion: "omk.loadout.v1",
@@ -112,48 +104,36 @@ export const BUILTIN_LOADOUTS = {
112
104
  test: {
113
105
  schemaVersion: "omk.loadout.v1",
114
106
  name: "test",
115
- authority: "execute-tests",
116
- tools: { allow: ["read", "grep", "find", "ls", "bash"] },
117
- skills: allowNames("skill", ["verification-before-completion"]),
118
- mcp: allowNames("mcp", ["filesystem"]),
119
- hooks: allowNames("hook", ["pre-shell-guard", "stop-verify"]),
120
- commands: { mode: "tests-only" },
107
+ authority: "write-scoped",
108
+ tools: { allow: ["read", "grep", "find", "ls", "edit", "write", "bash"] },
109
+ commands: { mode: "scoped-shell" },
121
110
  },
122
111
  review: {
123
112
  schemaVersion: "omk.loadout.v1",
124
113
  name: "review",
125
- authority: "review-only",
126
- tools: { allow: ["read", "grep", "find", "ls"] },
127
- skills: allowNames("skill", ["code-review", "differential-review"]),
128
- mcp: allowNames("mcp", ["memory"]),
129
- hooks: allowNames("hook", ["stop-verify", "subagent-stop-audit"]),
114
+ authority: "write-scoped",
115
+ tools: { allow: ["read", "grep", "find", "ls", "edit", "write", "bash"] },
116
+ commands: { mode: "scoped-shell" },
130
117
  },
131
118
  critic: {
132
119
  schemaVersion: "omk.loadout.v1",
133
120
  name: "critic",
134
- authority: "review-only",
135
- tools: { allow: ["read", "grep", "find", "ls", "bash"] },
136
- skills: allowNames("skill", ["code-review", "verification-before-completion", "scientific-critical-thinking"]),
137
- mcp: allowNames("mcp", ["filesystem-readonly", "memory", "context7"]),
138
- hooks: allowNames("hook", ["pre-shell-guard", "protect-secrets", "stop-verify", "subagent-stop-audit"]),
139
- commands: { mode: "read-only-shell" },
140
- evidence: { required: true, outputPattern: ".omk/runs/<goal>/critic.md" },
121
+ authority: "write-scoped",
122
+ tools: { allow: ["read", "grep", "find", "ls", "edit", "write", "bash"] },
123
+ commands: { mode: "scoped-shell" },
141
124
  },
142
125
  security: {
143
126
  schemaVersion: "omk.loadout.v1",
144
127
  name: "security",
145
- authority: "security-review",
146
- tools: { allow: ["read", "grep", "find", "ls", "bash"] },
147
- skills: allowNames("skill", ["security-review", "differential-review"]),
148
- mcp: allowNames("mcp", ["filesystem-readonly", "memory"]),
149
- hooks: allowNames("hook", ["pre-shell-guard", "protect-secrets", "stop-verify"]),
150
- commands: { mode: "read-only-shell" },
128
+ authority: "write-scoped",
129
+ tools: { allow: ["read", "grep", "find", "ls", "edit", "write", "bash"] },
130
+ commands: { mode: "scoped-shell" },
151
131
  },
152
132
  "visual-qa": {
153
133
  schemaVersion: "omk.loadout.v1",
154
134
  name: "visual-qa",
155
- authority: "execute-tests",
156
- tools: { allow: ["read", "grep", "find", "ls", "bash"] },
135
+ authority: "write-scoped",
136
+ tools: { allow: ["read", "grep", "find", "ls", "edit", "write", "bash"] },
157
137
  skills: allowNames("skill", [
158
138
  "clone-website",
159
139
  "visual-qa",
@@ -171,8 +151,7 @@ export const BUILTIN_LOADOUTS = {
171
151
  "protect-secrets",
172
152
  "stop-verify",
173
153
  ]),
174
- commands: { mode: "tests-only" },
175
- evidence: { required: true, outputPattern: ".omk/runs/<goal>/visual-qa.md" },
154
+ commands: { mode: "scoped-shell" },
176
155
  },
177
156
  "rhwp-doc": {
178
157
  schemaVersion: "omk.loadout.v1",
@@ -229,9 +208,9 @@ export const BUILTIN_LOADOUTS = {
229
208
  none: {
230
209
  schemaVersion: "omk.loadout.v1",
231
210
  name: "none",
232
- authority: "advisory",
233
- tools: { allow: [], defaultMode: "no-tools" },
234
- commands: { mode: "none" },
211
+ authority: "write-scoped",
212
+ tools: { allow: ["read", "grep", "find", "ls", "edit", "write", "bash"] },
213
+ commands: { mode: "scoped-shell" },
235
214
  },
236
215
  };
237
216
  export function inferLoadoutForRole(role) {
@@ -1 +1 @@
1
- {"version":3,"file":"loadouts.js","sourceRoot":"","sources":["../../src/core/loadouts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAuJH,MAAM,cAAc,GAAqC;IACxD,QAAQ,EAAE,CAAC;IACX,WAAW,EAAE,CAAC;IACd,aAAa,EAAE,CAAC;IAChB,iBAAiB,EAAE,CAAC;IACpB,eAAe,EAAE,CAAC;IAClB,cAAc,EAAE,CAAC;CACjB,CAAC;AAEF,MAAM,oBAAoB,GAA8B,IAAI,GAAG,CAAC;IAC/D,WAAW;IACX,OAAO;IACP,QAAQ;IACR,OAAO;IACP,MAAM;IACN,KAAK;IACL,MAAM;CACN,CAAC,CAAC;AAEH,MAAM,mBAAmB,GAA6B,IAAI,GAAG,CAAC;IAC7D,MAAM;IACN,iBAAiB;IACjB,YAAY;IACZ,cAAc;CACd,CAAC,CAAC;AAEH,MAAM,wBAAwB,GAAiC,IAAI,GAAG,CAAC;IACtE,kBAAkB;IAClB,UAAU;IACV,kBAAkB;CAClB,CAAC,CAAC;AAEH,mFAAmF;AACnF,MAAM,aAAa,GAA6B,IAAI,GAAG,CAAC;IACvD,OAAO;IACP,UAAU;IACV,QAAQ;IACR,UAAU;IACV,aAAa;IACb,oBAAoB;CACpB,CAAC,CAAC;AAEH,MAAM,kBAAkB,GAAwB,IAAI,GAAG,CAAC;IACvD,mBAAmB;IACnB,qBAAqB;IACrB,WAAW;IACX,gBAAgB;CAChB,CAAC,CAAC;AAEH,SAAS,UAAU,CAAC,IAAkB,EAAE,KAAwB,EAAkB;IACjF,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;AAAA,CACpC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAA6C;IACzE,OAAO,EAAE;QACR,aAAa,EAAE,gBAAgB;QAC/B,IAAI,EAAE,SAAS;QACf,SAAS,EAAE,WAAW;QACtB,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAChD,MAAM,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAC;QAC3D,GAAG,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC,qBAAqB,EAAE,QAAQ,CAAC,CAAC;QACzD,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,CAAC;KACjE;IACD,IAAI,EAAE;QACL,aAAa,EAAE,gBAAgB;QAC/B,IAAI,EAAE,MAAM;QACZ,SAAS,EAAE,UAAU;QACrB,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAChD,MAAM,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,iBAAiB,EAAE,eAAe,EAAE,2BAA2B,CAAC,CAAC;QAC9F,GAAG,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QAC/C,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,iBAAiB,EAAE,uBAAuB,CAAC,CAAC;KACvE;IACD,SAAS,EAAE;QACV,aAAa,EAAE,gBAAgB;QAC/B,IAAI,EAAE,WAAW;QACjB,SAAS,EAAE,aAAa;QACxB,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE;QAC1E,MAAM,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,2BAA2B,EAAE,aAAa,EAAE,iBAAiB,CAAC,CAAC;QAC5F,GAAG,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC,qBAAqB,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;QACrE,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,aAAa,EAAE,qBAAqB,CAAC,CAAC;QACvG,QAAQ,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE;QACrC,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,+BAA+B,EAAE;KAC5E;IACD,IAAI,EAAE;QACL,aAAa,EAAE,gBAAgB;QAC/B,IAAI,EAAE,MAAM;QACZ,SAAS,EAAE,cAAc;QACzB,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE;QACzE,MAAM,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,yBAAyB,EAAE,kBAAkB,CAAC,CAAC;QAC5E,GAAG,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QAClD,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,sBAAsB,CAAC,CAAC;QACzF,QAAQ,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE;KAClC;IACD,QAAQ,EAAE;QACT,aAAa,EAAE,gBAAgB;QAC/B,IAAI,EAAE,UAAU;QAChB,SAAS,EAAE,cAAc;QACzB,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE;QACzE,MAAM,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,yBAAyB,EAAE,kBAAkB,EAAE,gCAAgC,CAAC,CAAC;QAC9G,GAAG,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QAClD,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,aAAa,CAAC,CAAC;QACxG,QAAQ,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE;QAClC,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,oCAAoC,EAAE;KACjF;IACD,IAAI,EAAE;QACL,aAAa,EAAE,gBAAgB;QAC/B,IAAI,EAAE,MAAM;QACZ,SAAS,EAAE,eAAe;QAC1B,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE;QACxD,MAAM,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,gCAAgC,CAAC,CAAC;QAC/D,GAAG,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC;QACtC,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAC;QAC7D,QAAQ,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE;KAChC;IACD,MAAM,EAAE;QACP,aAAa,EAAE,gBAAgB;QAC/B,IAAI,EAAE,QAAQ;QACd,SAAS,EAAE,aAAa;QACxB,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAChD,MAAM,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,aAAa,EAAE,qBAAqB,CAAC,CAAC;QACnE,GAAG,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,CAAC;QAClC,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,aAAa,EAAE,qBAAqB,CAAC,CAAC;KACjE;IACD,MAAM,EAAE;QACP,aAAa,EAAE,gBAAgB;QAC/B,IAAI,EAAE,QAAQ;QACd,SAAS,EAAE,aAAa;QACxB,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE;QACxD,MAAM,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,aAAa,EAAE,gCAAgC,EAAE,8BAA8B,CAAC,CAAC;QAC9G,GAAG,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC,qBAAqB,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;QACrE,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,aAAa,EAAE,qBAAqB,CAAC,CAAC;QACvG,QAAQ,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE;QACrC,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,4BAA4B,EAAE;KACzE;IACD,QAAQ,EAAE;QACT,aAAa,EAAE,gBAAgB;QAC/B,IAAI,EAAE,UAAU;QAChB,SAAS,EAAE,iBAAiB;QAC5B,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE;QACxD,MAAM,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,iBAAiB,EAAE,qBAAqB,CAAC,CAAC;QACvE,GAAG,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC,qBAAqB,EAAE,QAAQ,CAAC,CAAC;QACzD,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,aAAa,CAAC,CAAC;QAChF,QAAQ,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE;KACrC;IACD,WAAW,EAAE;QACZ,aAAa,EAAE,gBAAgB;QAC/B,IAAI,EAAE,WAAW;QACjB,SAAS,EAAE,eAAe;QAC1B,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE;QACxD,MAAM,EAAE,UAAU,CAAC,OAAO,EAAE;YAC3B,eAAe;YACf,WAAW;YACX,aAAa;YACb,mBAAmB;YACnB,YAAY;YACZ,mBAAmB;SACnB,CAAC;QACF,GAAG,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;QACnF,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE;YACzB,6BAA6B;YAC7B,wBAAwB;YACxB,sBAAsB;YACtB,kBAAkB;YAClB,iBAAiB;YACjB,aAAa;SACb,CAAC;QACF,QAAQ,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE;QAChC,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,+BAA+B,EAAE;KAC5E;IACD,UAAU,EAAE;QACX,aAAa,EAAE,gBAAgB;QAC/B,IAAI,EAAE,UAAU;QAChB,SAAS,EAAE,cAAc;QACzB,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE;QACzE,MAAM,EAAE,UAAU,CAAC,OAAO,EAAE;YAC3B,MAAM;YACN,UAAU;YACV,qBAAqB;YACrB,qBAAqB;YACrB,mBAAmB;SACnB,CAAC;QACF,GAAG,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC,YAAY,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;QAChE,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE;YACzB,yBAAyB;YACzB,kBAAkB;YAClB,iBAAiB;YACjB,iBAAiB;YACjB,aAAa;SACb,CAAC;QACF,QAAQ,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE;QAClC,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,8BAA8B,EAAE;KAC3E;IACD,oBAAoB,EAAE;QACrB,aAAa,EAAE,gBAAgB;QAC/B,IAAI,EAAE,oBAAoB;QAC1B,SAAS,EAAE,cAAc;QACzB,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE;QACzE,MAAM,EAAE,UAAU,CAAC,OAAO,EAAE;YAC3B,WAAW;YACX,sBAAsB;YACtB,iBAAiB;YACjB,gCAAgC;SAChC,CAAC;QACF,GAAG,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC;QACtC,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,aAAa,CAAC,CAAC;QACrG,QAAQ,EAAE;YACT,IAAI,EAAE,cAAc;YACpB,aAAa,EAAE;gBACd,+BAA+B;gBAC/B,0BAA0B;gBAC1B,mDAAmD;gBACnD,oDAAoD;aACpD;YACD,aAAa,EAAE;gBACd,WAAW;gBACX,sCAAsC;gBACtC,iCAAiC;gBACjC,cAAc;aACd;SACD;KACD;IACD,IAAI,EAAE;QACL,aAAa,EAAE,gBAAgB;QAC/B,IAAI,EAAE,MAAM;QACZ,SAAS,EAAE,UAAU;QACrB,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE;QAC7C,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;KAC1B;CACD,CAAC;AAEF,MAAM,UAAU,mBAAmB,CAAC,IAAiB,EAAU;IAC9D,QAAQ,IAAI,EAAE,CAAC;QACd,KAAK,SAAS;YACb,OAAO,MAAM,CAAC;QACf,KAAK,UAAU;YACd,OAAO,SAAS,CAAC;QAClB,KAAK,WAAW;YACf,OAAO,WAAW,CAAC;QACpB,KAAK,OAAO;YACX,OAAO,MAAM,CAAC;QACf,KAAK,UAAU;YACd,OAAO,UAAU,CAAC;QACnB,KAAK,QAAQ;YACZ,OAAO,MAAM,CAAC;QACf,KAAK,UAAU;YACd,OAAO,QAAQ,CAAC;QACjB,KAAK,QAAQ;YACZ,OAAO,QAAQ,CAAC;QACjB,KAAK,UAAU;YACd,OAAO,UAAU,CAAC;QACnB,KAAK,WAAW;YACf,OAAO,WAAW,CAAC;QACpB,KAAK,UAAU;YACd,OAAO,UAAU,CAAC;QACnB,KAAK,oBAAoB;YACxB,OAAO,oBAAoB,CAAC;QAC7B,KAAK,aAAa;YACjB,OAAO,MAAM,CAAC;IAChB,CAAC;AAAA,CACD;AAED,MAAM,UAAU,oBAAoB,CAAC,SAA2B,EAAE,KAAuB,EAAW;IACnG,OAAO,cAAc,CAAC,SAAS,CAAC,IAAI,cAAc,CAAC,KAAK,CAAC,CAAC;AAAA,CAC1D;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAiB,EAAgB;IACpE,MAAM,OAAO,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC1C,OAAO;QACN,OAAO;QACP,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,cAAc,EAAE,OAAO,CAAC,SAAS,KAAK,cAAc;QACpD,QAAQ,EACP,OAAO,CAAC,SAAS,KAAK,WAAW,IAAI,OAAO,CAAC,SAAS,KAAK,aAAa,IAAI,OAAO,CAAC,SAAS,KAAK,UAAU;QAC7G,kBAAkB,EAAE,OAAO,CAAC,SAAS,KAAK,cAAc;KACxD,CAAC;AAAA,CACF;AAED,MAAM,UAAU,mBAAmB,CAClC,OAAuB,EACvB,SAA8B,EAC9B,OAAO,GAA0C,EAAE,EAClC;IACjB,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,6EAA6E;IAC7E,IAAI,OAAO,CAAC,cAAc,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;QAChG,QAAQ,CAAC,IAAI,CAAC,qBAAqB,OAAO,CAAC,SAAS,kBAAkB,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IACjG,CAAC;IAED,MAAM,WAAW,GAAG,aAAa,CAAC,OAAO,CAAC,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACtF,MAAM,YAAY,GAAG,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACxG,MAAM,SAAS,GAAG,mBAAmB,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC7F,MAAM,WAAW,GAAG,mBAAmB,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAEpG,OAAO;QACN,WAAW,EAAE,OAAO,CAAC,IAAI;QACzB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,WAAW;QACX,YAAY;QACZ,SAAS;QACT,WAAW;QACX,QAAQ;QACR,QAAQ;KACR,CAAC;AAAA,CACF;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAuB,EAAqB;IAClF,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,OAAO,CAAC,aAAa,KAAK,gBAAgB,EAAE,CAAC;QAChD,MAAM,CAAC,IAAI,CAAC,0BAA0B,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IACxE,CAAC;IACD,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACpE,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACrC,CAAC;IACD,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,IAAI,cAAc,CAAC,EAAE,CAAC;QAC5C,MAAM,CAAC,IAAI,CAAC,sBAAsB,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,gBAAgB,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACxC,sBAAsB,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClE,sBAAsB,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC1D,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC/D,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACtB,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACrD,MAAM,CAAC,IAAI,CAAC,yBAAyB,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACvE,CAAC;aAAM,IAAI,OAAO,CAAC,SAAS,IAAI,cAAc,EAAE,CAAC;YAChD,MAAM,QAAQ,GAAG,4BAA4B,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;YACxF,IAAI,QAAQ;gBAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrC,CAAC;IACF,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;AAAA,CAC9C;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAA+B,EAAmB;IACvF,MAAM,QAAQ,GAAG,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5F,MAAM,cAAc,GAAG,oBAAoB,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC1E,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;AAAA,CAC7C;AAED,SAAS,oBAAoB,CAAC,SAA2B,EAAE,QAAuC,EAAW;IAC5G,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,IAAI,SAAS,KAAK,cAAc;QAAE,OAAO,KAAK,CAAC;IAC/C,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,sBAAsB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/E,OAAO,IAAI,CAAC;AAAA,CACZ;AAED,mFAAmF;AACnF,MAAM,UAAU,sBAAsB,CAAC,IAAY,EAAW;IAC7D,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/D,IAAI,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9C,IAAI,IAAI,KAAK,cAAc;QAAE,OAAO,IAAI,CAAC;IACzC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACxC,IAAI,UAAU,KAAK,YAAY,IAAI,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAChH,OAAO,KAAK,CAAC;AAAA,CACb;AAED,SAAS,WAAW,CAAC,KAAoC,EAAwB;IAChF,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,OAAO,GAAyB,EAAE,CAAC;IACzC,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACxB,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS;QAC5C,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACtD,OAAO,OAAO,CAAC;AAAA,CACf;AAED,SAAS,aAAa,CAAC,SAAmC,EAAe;IACxE,OAAO,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AAAA,CAC3D;AAED,SAAS,aAAa,CACrB,IAAc,EACd,SAAmC,EACnC,QAAkB,EAClB,QAAkB,EACP;IACX,MAAM,SAAS,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IAC3C,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;QAC3C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,0BAA0B,QAAQ,EAAE,CAAC,CAAC;IACnF,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/G,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;QACzB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,QAAQ,CAAC,IAAI,CAAC,gCAAgC,IAAI,EAAE,CAAC,CAAC;YACtD,SAAS;QACV,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AAAA,CAChD;AAED,SAAS,mBAAmB,CAC3B,IAAkB,EAClB,IAAgC,EAChC,SAAmC,EACnC,QAAkB,EAClB,QAAkB,EACP;IACX,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IAEjC,+EAA+E;IAC/E,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;QAC3C,sBAAsB,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IACrE,CAAC;IAED,4EAA4E;IAC5E,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;QACzC,KAAK,MAAM,KAAK,IAAI,aAAa,CAAC,QAAQ,EAAE,SAAS,CAAC;YAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC/E,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;YACzC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,IAAI,IAAI,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;gBAClG,QAAQ,CAAC,IAAI,CAAC,YAAY,IAAI,mBAAmB,IAAI,EAAE,CAAC,CAAC;YAC1D,CAAC;QACF,CAAC;IACF,CAAC;IAED,yBAAyB;IACzB,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;QAC3C,KAAK,MAAM,KAAK,IAAI,aAAa,CAAC,QAAQ,EAAE,SAAS,CAAC;YAAE,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClF,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AAAA,CAChD;AAED,SAAS,sBAAsB,CAC9B,IAAkB,EAClB,QAA0B,EAC1B,SAAmC,EACnC,QAAkB,EAClB,MAAmB,EACZ;IACP,IAAI,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjD,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,IAAI,IAAI,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;YAC5G,IAAI,OAAO;gBAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;;gBACzB,QAAQ,CAAC,IAAI,CAAC,oBAAoB,IAAI,KAAK,IAAI,EAAE,CAAC,CAAC;QACzD,CAAC;QACD,OAAO;IACR,CAAC;IACD,MAAM,OAAO,GAAG,aAAa,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACnD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,QAAQ,CAAC,IAAI,CAAC,oBAAoB,IAAI,KAAK,gBAAgB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACzE,OAAO;IACR,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,OAAO;QAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAAA,CACpD;AAED,SAAS,aAAa,CAAC,QAA0B,EAAE,SAAmC,EAAmB;IACxG,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC;QACrC,IAAI,QAAQ,CAAC,KAAK,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QAC5E,OAAO,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAAA,CAC3C,CAAC,CAAC;AAAA,CACH;AAED,SAAS,eAAe,CAAC,QAA0B,EAAE,QAAuB,EAAW;IACtF,IAAI,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IAClD,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACjH,IAAI,QAAQ,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACrH,IAAI,QAAQ,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/G,IAAI,QAAQ,CAAC,KAAK,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACzG,OAAO,IAAI,CAAC;AAAA,CACZ;AAED,SAAS,gBAAgB,CAAC,QAA0B,EAAU;IAC7D,MAAM,KAAK,GAAa,CAAC,QAAQ,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAClD,IAAI,QAAQ,CAAC,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,SAAS,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACpE,IAAI,QAAQ,CAAC,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,WAAW,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC1E,IAAI,QAAQ,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,UAAU,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACvE,IAAI,QAAQ,CAAC,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,WAAW,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC1E,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAAA,CACvB;AAED,SAAS,gBAAgB,CAAC,IAA0B,EAAE,MAAgB,EAAQ;IAC7E,IAAI,CAAC,IAAI,EAAE,CAAC;QACX,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAClC,OAAO;IACR,CAAC;IACD,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QACvF,MAAM,CAAC,IAAI,CAAC,6BAA6B,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IACtE,CAAC;AAAA,CACD;AAED,SAAS,sBAAsB,CAC9B,QAAgB,EAChB,YAA0B,EAC1B,IAAgC,EAChC,MAAgB,EACT;IACP,IAAI,CAAC,IAAI;QAAE,OAAO;IAClB,KAAK,MAAM,KAAK,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,CAAU,EAAE,CAAC;QAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC,SAAS;YAAE,SAAS;QACzB,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YAClC,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9C,MAAM,CAAC,IAAI,CAAC,4BAA4B,QAAQ,IAAI,KAAK,KAAK,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACxF,CAAC;iBAAM,IAAI,QAAQ,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAC3C,MAAM,CAAC,IAAI,CACV,+BAA+B,QAAQ,IAAI,KAAK,cAAc,YAAY,SAAS,QAAQ,CAAC,IAAI,EAAE,CAClG,CAAC;YACH,CAAC;QACF,CAAC;IACF,CAAC;AAAA,CACD;AAED,SAAS,4BAA4B,CAAC,IAAiB,EAAE,SAA2B,EAAsB;IACzG,IAAI,IAAI,KAAK,cAAc,IAAI,SAAS,KAAK,cAAc,EAAE,CAAC;QAC7D,OAAO,kEAAkE,SAAS,EAAE,CAAC;IACtF,CAAC;IACD,IAAI,IAAI,KAAK,YAAY,IAAI,SAAS,KAAK,eAAe,IAAI,SAAS,KAAK,cAAc,EAAE,CAAC;QAC5F,OAAO,iFAAiF,SAAS,EAAE,CAAC;IACrG,CAAC;IACD,OAAO,SAAS,CAAC;AAAA,CACjB;AAED,SAAS,SAAS,CAAC,IAAY,EAAE,KAAa,EAAW;IACxD,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAAA,CACtC;AAED,SAAS,YAAY,CAAC,IAAY,EAAU;IAC3C,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QAClD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QACzB,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YAClB,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBAC7B,OAAO,IAAI,IAAI,CAAC;gBAChB,KAAK,EAAE,CAAC;YACT,CAAC;iBAAM,CAAC;gBACP,OAAO,IAAI,OAAO,CAAC;YACpB,CAAC;QACF,CAAC;aAAM,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YACzB,OAAO,IAAI,GAAG,CAAC;QAChB,CAAC;aAAM,CAAC;YACP,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;QACtD,CAAC;IACF,CAAC;IACD,OAAO,IAAI,MAAM,CAAC,IAAI,OAAO,GAAG,CAAC,CAAC;AAAA,CAClC;AAED,SAAS,aAAa,CAAC,CAAS,EAAE,CAAS,EAAU;IACpD,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC,CAAC;IACrB,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC;IACpB,OAAO,CAAC,CAAC;AAAA,CACT","sourcesContent":["/**\n * Pure loadout / lane-profile algorithms for the OMK control plane.\n *\n * This module is I/O-free. It owns the loadout schema, built-in presets,\n * capability gating (allow/exclude/require selectors), profile validation, and\n * the derivation of scheduler read/write/parallelizable fields from a lane's\n * optional assigned paths. Runtime wiring (AgentSession tool registry, skill\n * prompt construction, MCP runtime, scheduler admission) lives in sibling\n * modules and consumes the decisions made here.\n *\n * Schema and presets follow the OMK package hardening loadout plan.\n *\n * Erasable TypeScript only (no enum/namespace/parameter properties).\n */\n\nimport type { HookPolicyMetadata } from \"./hooks/index.ts\";\n\nexport type LoadoutAuthority =\n\t| \"advisory\"\n\t| \"read-only\"\n\t| \"execute-tests\"\n\t| \"write-scoped\"\n\t| \"review-only\"\n\t| \"security-review\";\n\nexport type LoadoutRole =\n\t| \"planner\"\n\t| \"explorer\"\n\t| \"architect\"\n\t| \"coder\"\n\t| \"executor\"\n\t| \"tester\"\n\t| \"reviewer\"\n\t| \"critic\"\n\t| \"security\"\n\t| \"visual-qa\"\n\t| \"rhwp-doc\"\n\t| \"synthesizer\"\n\t| \"package-maintainer\";\n\n/** Resource kinds the loadout layer can describe. Only the last four are gated here. */\nexport type ResourceKind = \"extension\" | \"skill\" | \"prompt\" | \"theme\" | \"tool\" | \"mcp\" | \"hook\";\nexport type ResourceOrigin = \"package\" | \"top-level\";\nexport type SourceScope = \"user\" | \"project\" | \"temporary\" | \"builtin\";\nexport type CommandMode = \"none\" | \"read-only-shell\" | \"tests-only\" | \"scoped-shell\";\nexport type ToolDefaultMode = \"default-builtins\" | \"no-tools\" | \"no-builtin-tools\";\n\nexport interface NamedResource {\n\tkind: ResourceKind;\n\tname: string;\n\tsource?: string;\n\tscope?: SourceScope;\n\t/** Package-relative or absolute resource path, when meaningful (skills/prompts). */\n\tpath?: string;\n\torigin?: ResourceOrigin;\n\tpolicy?: HookPolicyMetadata;\n}\n\n/**\n * A selector matches inventory resources by name and/or provenance criteria.\n * A resource matches when its kind equals `kind` and every defined criterion\n * matches (names is an OR over the listed names; paths/sources are OR over globs).\n */\nexport interface ResourceSelector {\n\tkind: ResourceKind;\n\tnames?: readonly string[];\n\t/** Glob patterns matched against `NamedResource.path`. */\n\tpaths?: readonly string[];\n\t/** Glob patterns matched against `NamedResource.source`. */\n\tsources?: readonly string[];\n\tscopes?: readonly SourceScope[];\n\torigins?: readonly ResourceOrigin[];\n\t/** Marker only; requirement is expressed by placement in `CapabilityGate.require`. */\n\trequired?: boolean;\n}\n\n/** Tool gating uses flat name arrays (mapped to SDK tools / setActiveTools). */\nexport interface ToolGate {\n\tallow?: readonly string[];\n\texclude?: readonly string[];\n\trequire?: readonly string[];\n\tdefaultMode?: ToolDefaultMode;\n}\n\n/** Skills / MCP / hooks gating uses selector arrays. */\nexport interface CapabilityGate {\n\tallow?: readonly ResourceSelector[];\n\texclude?: readonly ResourceSelector[];\n\trequire?: readonly ResourceSelector[];\n}\n\nexport interface LoadoutCommands {\n\tmode: CommandMode;\n\tallowPatterns?: readonly string[];\n\tblockPatterns?: readonly string[];\n}\n\nexport interface LoadoutEvidence {\n\trequired: boolean;\n\toutputPattern: string;\n}\n\nexport interface LoadoutProfile {\n\tschemaVersion: \"omk.loadout.v1\";\n\tname: string;\n\tdescription?: string;\n\tauthority: LoadoutAuthority;\n\ttools: ToolGate;\n\tskills?: CapabilityGate;\n\tmcp?: CapabilityGate;\n\thooks?: CapabilityGate;\n\tcommands?: LoadoutCommands;\n\tevidence?: LoadoutEvidence;\n}\n\nexport interface CapabilityInventory {\n\ttools: readonly NamedResource[];\n\tskills: readonly NamedResource[];\n\tmcp: readonly NamedResource[];\n\thooks: readonly NamedResource[];\n}\n\nexport interface LaneDefaults {\n\tloadout: string;\n\tauthority: LoadoutAuthority;\n\tparallelizable: boolean;\n\treadOnly: boolean;\n\twritesProductFiles: boolean;\n}\n\nexport interface AppliedLoadout {\n\tprofileName: string;\n\tauthority: LoadoutAuthority;\n\tactiveTools: string[];\n\tactiveSkills: string[];\n\tactiveMcp: string[];\n\tactiveHooks: string[];\n\tblockers: string[];\n\twarnings: string[];\n}\n\nexport interface LoadoutValidation {\n\tvalid: boolean;\n\terrors: string[];\n}\n\n/** A scheduler access entry; shape matches `AccessSetEntry` in the orchestration layer. */\nexport interface LoadoutAccessEntry {\n\tpath: string;\n\tsymbols?: readonly string[];\n}\n\nexport interface SchedulerFields {\n\treadSet: LoadoutAccessEntry[];\n\twriteSet: LoadoutAccessEntry[];\n\tparallelizable: boolean;\n}\n\nexport interface SchedulerDerivationInput {\n\trole: LoadoutRole;\n\tassignedReadPaths?: readonly string[];\n\tassignedWritePaths?: readonly string[];\n}\n\nconst AUTHORITY_RANK: Record<LoadoutAuthority, number> = {\n\tadvisory: 0,\n\t\"read-only\": 1,\n\t\"review-only\": 1,\n\t\"security-review\": 2,\n\t\"execute-tests\": 3,\n\t\"write-scoped\": 4,\n};\n\nconst KNOWN_RESOURCE_KINDS: ReadonlySet<ResourceKind> = new Set([\n\t\"extension\",\n\t\"skill\",\n\t\"prompt\",\n\t\"theme\",\n\t\"tool\",\n\t\"mcp\",\n\t\"hook\",\n]);\n\nconst KNOWN_COMMAND_MODES: ReadonlySet<CommandMode> = new Set([\n\t\"none\",\n\t\"read-only-shell\",\n\t\"tests-only\",\n\t\"scoped-shell\",\n]);\n\nconst KNOWN_TOOL_DEFAULT_MODES: ReadonlySet<ToolDefaultMode> = new Set([\n\t\"default-builtins\",\n\t\"no-tools\",\n\t\"no-builtin-tools\",\n]);\n\n/** Roles permitted to declare a non-empty writeSet during scheduler derivation. */\nconst WRITING_ROLES: ReadonlySet<LoadoutRole> = new Set([\n\t\"coder\",\n\t\"executor\",\n\t\"tester\",\n\t\"rhwp-doc\",\n\t\"synthesizer\",\n\t\"package-maintainer\",\n]);\n\nconst LOCKFILE_BASENAMES: ReadonlySet<string> = new Set([\n\t\"package-lock.json\",\n\t\"npm-shrinkwrap.json\",\n\t\"yarn.lock\",\n\t\"pnpm-lock.yaml\",\n]);\n\nfunction allowNames(kind: ResourceKind, names: readonly string[]): CapabilityGate {\n\treturn { allow: [{ kind, names }] };\n}\n\nexport const BUILTIN_LOADOUTS: Readonly<Record<string, LoadoutProfile>> = {\n\tinspect: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"inspect\",\n\t\tauthority: \"read-only\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\"] },\n\t\tskills: allowNames(\"skill\", [\"understand-chat\", \"analyze\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem-readonly\", \"memory\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\"]),\n\t},\n\tplan: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"plan\",\n\t\tauthority: \"advisory\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\"] },\n\t\tskills: allowNames(\"skill\", [\"adaptorch-route\", \"writing-plans\", \"ddd-software-architecture\"]),\n\t\tmcp: allowNames(\"mcp\", [\"memory\", \"adaptorch\"]),\n\t\thooks: allowNames(\"hook\", [\"session-context\", \"precompact-checkpoint\"]),\n\t},\n\tarchitect: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"architect\",\n\t\tauthority: \"review-only\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"bash\", \"report_finding\"] },\n\t\tskills: allowNames(\"skill\", [\"ddd-software-architecture\", \"code-review\", \"security-review\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem-readonly\", \"memory\", \"context7\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"stop-verify\", \"subagent-stop-audit\"]),\n\t\tcommands: { mode: \"read-only-shell\" },\n\t\tevidence: { required: true, outputPattern: \".omk/runs/<goal>/architect.md\" },\n\t},\n\tcode: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"code\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\"test-driven-development\", \"coding-standards\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\", \"context7\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"typecheck-after-edit\"]),\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\texecutor: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"executor\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\"test-driven-development\", \"coding-standards\", \"verification-before-completion\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\", \"context7\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"typecheck-after-edit\", \"stop-verify\"]),\n\t\tcommands: { mode: \"scoped-shell\" },\n\t\tevidence: { required: true, outputPattern: \".omk/runs/<goal>/implementation.md\" },\n\t},\n\ttest: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"test\",\n\t\tauthority: \"execute-tests\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\"verification-before-completion\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"stop-verify\"]),\n\t\tcommands: { mode: \"tests-only\" },\n\t},\n\treview: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"review\",\n\t\tauthority: \"review-only\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\"] },\n\t\tskills: allowNames(\"skill\", [\"code-review\", \"differential-review\"]),\n\t\tmcp: allowNames(\"mcp\", [\"memory\"]),\n\t\thooks: allowNames(\"hook\", [\"stop-verify\", \"subagent-stop-audit\"]),\n\t},\n\tcritic: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"critic\",\n\t\tauthority: \"review-only\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\"code-review\", \"verification-before-completion\", \"scientific-critical-thinking\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem-readonly\", \"memory\", \"context7\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"stop-verify\", \"subagent-stop-audit\"]),\n\t\tcommands: { mode: \"read-only-shell\" },\n\t\tevidence: { required: true, outputPattern: \".omk/runs/<goal>/critic.md\" },\n\t},\n\tsecurity: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"security\",\n\t\tauthority: \"security-review\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\"security-review\", \"differential-review\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem-readonly\", \"memory\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"stop-verify\"]),\n\t\tcommands: { mode: \"read-only-shell\" },\n\t},\n\t\"visual-qa\": {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"visual-qa\",\n\t\tauthority: \"execute-tests\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\n\t\t\t\"clone-website\",\n\t\t\t\"visual-qa\",\n\t\t\t\"visual-diff\",\n\t\t\t\"visual-regression\",\n\t\t\t\"browser-qa\",\n\t\t\t\"web-quality-audit\",\n\t\t]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\", \"chrome-devtools\", \"playwright\", \"context7\"]),\n\t\thooks: allowNames(\"hook\", [\n\t\t\t\"component-spec-before-build\",\n\t\t\t\"visual-diff-after-edit\",\n\t\t\t\"typecheck-after-edit\",\n\t\t\t\"bounded-evidence\",\n\t\t\t\"protect-secrets\",\n\t\t\t\"stop-verify\",\n\t\t]),\n\t\tcommands: { mode: \"tests-only\" },\n\t\tevidence: { required: true, outputPattern: \".omk/runs/<goal>/visual-qa.md\" },\n\t},\n\t\"rhwp-doc\": {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"rhwp-doc\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\n\t\t\t\"rhwp\",\n\t\t\t\"rhwp-doc\",\n\t\t\t\"document-extraction\",\n\t\t\t\"document-conversion\",\n\t\t\t\"technical-writing\",\n\t\t]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\", \"context7\", \"playwright\"]),\n\t\thooks: allowNames(\"hook\", [\n\t\t\t\"document-artifact-guard\",\n\t\t\t\"bounded-evidence\",\n\t\t\t\"pre-shell-guard\",\n\t\t\t\"protect-secrets\",\n\t\t\t\"stop-verify\",\n\t\t]),\n\t\tcommands: { mode: \"scoped-shell\" },\n\t\tevidence: { required: true, outputPattern: \".omk/runs/<goal>/rhwp-doc.md\" },\n\t},\n\t\"package-maintainer\": {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"package-maintainer\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\n\t\t\t\"exact-pin\",\n\t\t\t\"no-lifecycle-scripts\",\n\t\t\t\"security-review\",\n\t\t\t\"verification-before-completion\",\n\t\t]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"npm-audit-summary\", \"stop-verify\"]),\n\t\tcommands: {\n\t\t\tmode: \"scoped-shell\",\n\t\t\tallowPatterns: [\n\t\t\t\t\"npm install --ignore-scripts*\",\n\t\t\t\t\"npm ci --ignore-scripts*\",\n\t\t\t\t\"npm install --package-lock-only --ignore-scripts*\",\n\t\t\t\t\"node scripts/generate-coding-agent-shrinkwrap.mjs*\",\n\t\t\t],\n\t\t\tblockPatterns: [\n\t\t\t\t\"*@latest*\",\n\t\t\t\t\"npm install *--ignore-scripts=false*\",\n\t\t\t\t\"npm ci *--ignore-scripts=false*\",\n\t\t\t\t\"npm rebuild*\",\n\t\t\t],\n\t\t},\n\t},\n\tnone: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"none\",\n\t\tauthority: \"advisory\",\n\t\ttools: { allow: [], defaultMode: \"no-tools\" },\n\t\tcommands: { mode: \"none\" },\n\t},\n};\n\nexport function inferLoadoutForRole(role: LoadoutRole): string {\n\tswitch (role) {\n\t\tcase \"planner\":\n\t\t\treturn \"plan\";\n\t\tcase \"explorer\":\n\t\t\treturn \"inspect\";\n\t\tcase \"architect\":\n\t\t\treturn \"architect\";\n\t\tcase \"coder\":\n\t\t\treturn \"code\";\n\t\tcase \"executor\":\n\t\t\treturn \"executor\";\n\t\tcase \"tester\":\n\t\t\treturn \"test\";\n\t\tcase \"reviewer\":\n\t\t\treturn \"review\";\n\t\tcase \"critic\":\n\t\t\treturn \"critic\";\n\t\tcase \"security\":\n\t\t\treturn \"security\";\n\t\tcase \"visual-qa\":\n\t\t\treturn \"visual-qa\";\n\t\tcase \"rhwp-doc\":\n\t\t\treturn \"rhwp-doc\";\n\t\tcase \"package-maintainer\":\n\t\t\treturn \"package-maintainer\";\n\t\tcase \"synthesizer\":\n\t\t\treturn \"plan\";\n\t}\n}\n\nexport function authorityWithinGrant(requested: LoadoutAuthority, grant: LoadoutAuthority): boolean {\n\treturn AUTHORITY_RANK[requested] <= AUTHORITY_RANK[grant];\n}\n\nexport function laneDefaultsForRole(role: LoadoutRole): LaneDefaults {\n\tconst loadout = inferLoadoutForRole(role);\n\tconst profile = BUILTIN_LOADOUTS[loadout];\n\treturn {\n\t\tloadout,\n\t\tauthority: profile.authority,\n\t\tparallelizable: profile.authority !== \"write-scoped\",\n\t\treadOnly:\n\t\t\tprofile.authority === \"read-only\" || profile.authority === \"review-only\" || profile.authority === \"advisory\",\n\t\twritesProductFiles: profile.authority === \"write-scoped\",\n\t};\n}\n\nexport function applyLoadoutProfile(\n\tprofile: LoadoutProfile,\n\tinventory: CapabilityInventory,\n\toptions: { grantAuthority?: LoadoutAuthority } = {},\n): AppliedLoadout {\n\tconst blockers: string[] = [];\n\tconst warnings: string[] = [];\n\t// Deterministic blocker order: authority, then tool/skill/mcp/hook requires.\n\tif (options.grantAuthority && !authorityWithinGrant(profile.authority, options.grantAuthority)) {\n\t\tblockers.push(`loadout authority ${profile.authority} exceeds grant ${options.grantAuthority}`);\n\t}\n\n\tconst activeTools = applyToolGate(profile.tools, inventory.tools, blockers, warnings);\n\tconst activeSkills = applyCapabilityGate(\"skill\", profile.skills, inventory.skills, blockers, warnings);\n\tconst activeMcp = applyCapabilityGate(\"mcp\", profile.mcp, inventory.mcp, blockers, warnings);\n\tconst activeHooks = applyCapabilityGate(\"hook\", profile.hooks, inventory.hooks, blockers, warnings);\n\n\treturn {\n\t\tprofileName: profile.name,\n\t\tauthority: profile.authority,\n\t\tactiveTools,\n\t\tactiveSkills,\n\t\tactiveMcp,\n\t\tactiveHooks,\n\t\tblockers,\n\t\twarnings,\n\t};\n}\n\n/**\n * Fail-closed structural validation of a loadout profile. Errors are returned\n * in a deterministic order: schemaVersion, name, authority, tools, skills, mcp,\n * hooks, commands.\n */\nexport function validateLoadoutProfile(profile: LoadoutProfile): LoadoutValidation {\n\tconst errors: string[] = [];\n\tif (profile.schemaVersion !== \"omk.loadout.v1\") {\n\t\terrors.push(`unknown schemaVersion: ${String(profile.schemaVersion)}`);\n\t}\n\tif (typeof profile.name !== \"string\" || profile.name.trim() === \"\") {\n\t\terrors.push(\"missing loadout name\");\n\t}\n\tif (!(profile.authority in AUTHORITY_RANK)) {\n\t\terrors.push(`unknown authority: ${String(profile.authority)}`);\n\t}\n\tvalidateToolGate(profile.tools, errors);\n\tvalidateCapabilityGate(\"skills\", \"skill\", profile.skills, errors);\n\tvalidateCapabilityGate(\"mcp\", \"mcp\", profile.mcp, errors);\n\tvalidateCapabilityGate(\"hooks\", \"hook\", profile.hooks, errors);\n\tif (profile.commands) {\n\t\tif (!KNOWN_COMMAND_MODES.has(profile.commands.mode)) {\n\t\t\terrors.push(`unknown command mode: ${String(profile.commands.mode)}`);\n\t\t} else if (profile.authority in AUTHORITY_RANK) {\n\t\t\tconst conflict = commandModeAuthorityConflict(profile.commands.mode, profile.authority);\n\t\t\tif (conflict) errors.push(conflict);\n\t\t}\n\t}\n\treturn { valid: errors.length === 0, errors };\n}\n\n/**\n * Derive scheduler readSet/writeSet/parallelizable from a lane role plus the\n * optional paths granted to that lane. Non-writing roles never produce a\n * writeSet. parallelizable is false when a write-scoped lane writes anything,\n * or when any write touches a lockfile, package config, snapshot, or git index.\n */\nexport function deriveSchedulerFields(input: SchedulerDerivationInput): SchedulerFields {\n\tconst defaults = laneDefaultsForRole(input.role);\n\tconst readSet = toAccessSet(input.assignedReadPaths);\n\tconst writeSet = WRITING_ROLES.has(input.role) ? toAccessSet(input.assignedWritePaths) : [];\n\tconst parallelizable = deriveParallelizable(defaults.authority, writeSet);\n\treturn { readSet, writeSet, parallelizable };\n}\n\nfunction deriveParallelizable(authority: LoadoutAuthority, writeSet: readonly LoadoutAccessEntry[]): boolean {\n\tif (writeSet.length === 0) return true;\n\tif (authority === \"write-scoped\") return false;\n\tif (writeSet.some((entry) => isSerializeTriggerPath(entry.path))) return false;\n\treturn true;\n}\n\n/** Lockfile, package config, snapshot, or git-index writes force serialization. */\nexport function isSerializeTriggerPath(path: string): boolean {\n\tconst normalized = path.replaceAll(\"\\\\\", \"/\");\n\tconst base = normalized.slice(normalized.lastIndexOf(\"/\") + 1);\n\tif (LOCKFILE_BASENAMES.has(base)) return true;\n\tif (base === \"package.json\") return true;\n\tif (base.endsWith(\".snap\")) return true;\n\tif (normalized === \".git/index\" || normalized.startsWith(\".git/\") || normalized.includes(\"/.git/\")) return true;\n\treturn false;\n}\n\nfunction toAccessSet(paths: readonly string[] | undefined): LoadoutAccessEntry[] {\n\tif (!paths) return [];\n\tconst seen = new Set<string>();\n\tconst entries: LoadoutAccessEntry[] = [];\n\tfor (const raw of paths) {\n\t\tconst path = raw.trim();\n\t\tif (path === \"\" || seen.has(path)) continue;\n\t\tseen.add(path);\n\t\tentries.push({ path });\n\t}\n\tentries.sort((a, b) => compareString(a.path, b.path));\n\treturn entries;\n}\n\nfunction resourceNames(resources: readonly NamedResource[]): Set<string> {\n\treturn new Set(resources.map((resource) => resource.name));\n}\n\nfunction applyToolGate(\n\tgate: ToolGate,\n\tresources: readonly NamedResource[],\n\tblockers: string[],\n\twarnings: string[],\n): string[] {\n\tconst available = resourceNames(resources);\n\tfor (const required of gate.require ?? []) {\n\t\tif (!available.has(required)) blockers.push(`missing required tool: ${required}`);\n\t}\n\tconst base = gate.defaultMode === \"no-tools\" ? [] : (gate.allow ?? resources.map((resource) => resource.name));\n\tconst excluded = new Set(gate.exclude ?? []);\n\tconst active: string[] = [];\n\tfor (const tool of base) {\n\t\tif (!available.has(tool)) {\n\t\t\twarnings.push(`optional tool not available: ${tool}`);\n\t\t\tcontinue;\n\t\t}\n\t\tif (!excluded.has(tool)) active.push(tool);\n\t}\n\treturn [...new Set(active)].sort(compareString);\n}\n\nfunction applyCapabilityGate(\n\tkind: ResourceKind,\n\tgate: CapabilityGate | undefined,\n\tresources: readonly NamedResource[],\n\tblockers: string[],\n\twarnings: string[],\n): string[] {\n\tif (!gate) return [];\n\tconst active = new Set<string>();\n\n\t// require: every required selector must resolve, else a deterministic blocker.\n\tfor (const selector of gate.require ?? []) {\n\t\tresolveRequireSelector(kind, selector, resources, blockers, active);\n\t}\n\n\t// allow: union of matches; warn on named-but-missing optional capabilities.\n\tfor (const selector of gate.allow ?? []) {\n\t\tfor (const match of matchSelector(selector, resources)) active.add(match.name);\n\t\tfor (const name of selector.names ?? []) {\n\t\t\tif (!resources.some((resource) => resource.name === name && matchesCriteria(selector, resource))) {\n\t\t\t\twarnings.push(`optional ${kind} not available: ${name}`);\n\t\t\t}\n\t\t}\n\t}\n\n\t// exclude: applied last.\n\tconst excluded = new Set<string>();\n\tfor (const selector of gate.exclude ?? []) {\n\t\tfor (const match of matchSelector(selector, resources)) excluded.add(match.name);\n\t}\n\n\tconst result = [...active].filter((name) => !excluded.has(name));\n\treturn [...new Set(result)].sort(compareString);\n}\n\nfunction resolveRequireSelector(\n\tkind: ResourceKind,\n\tselector: ResourceSelector,\n\tresources: readonly NamedResource[],\n\tblockers: string[],\n\tactive: Set<string>,\n): void {\n\tif (selector.names && selector.names.length > 0) {\n\t\tfor (const name of selector.names) {\n\t\t\tconst matched = resources.some((resource) => resource.name === name && matchesCriteria(selector, resource));\n\t\t\tif (matched) active.add(name);\n\t\t\telse blockers.push(`missing required ${kind}: ${name}`);\n\t\t}\n\t\treturn;\n\t}\n\tconst matches = matchSelector(selector, resources);\n\tif (matches.length === 0) {\n\t\tblockers.push(`missing required ${kind}: ${describeSelector(selector)}`);\n\t\treturn;\n\t}\n\tfor (const match of matches) active.add(match.name);\n}\n\nfunction matchSelector(selector: ResourceSelector, resources: readonly NamedResource[]): NamedResource[] {\n\treturn resources.filter((resource) => {\n\t\tif (selector.names && !selector.names.includes(resource.name)) return false;\n\t\treturn matchesCriteria(selector, resource);\n\t});\n}\n\nfunction matchesCriteria(selector: ResourceSelector, resource: NamedResource): boolean {\n\tif (resource.kind !== selector.kind) return false;\n\tif (selector.scopes && (resource.scope === undefined || !selector.scopes.includes(resource.scope))) return false;\n\tif (selector.origins && (resource.origin === undefined || !selector.origins.includes(resource.origin))) return false;\n\tif (selector.sources && !selector.sources.some((glob) => globMatch(glob, resource.source ?? \"\"))) return false;\n\tif (selector.paths && !selector.paths.some((glob) => globMatch(glob, resource.path ?? \"\"))) return false;\n\treturn true;\n}\n\nfunction describeSelector(selector: ResourceSelector): string {\n\tconst parts: string[] = [`kind=${selector.kind}`];\n\tif (selector.paths) parts.push(`paths=${selector.paths.join(\",\")}`);\n\tif (selector.sources) parts.push(`sources=${selector.sources.join(\",\")}`);\n\tif (selector.scopes) parts.push(`scopes=${selector.scopes.join(\",\")}`);\n\tif (selector.origins) parts.push(`origins=${selector.origins.join(\",\")}`);\n\treturn parts.join(\" \");\n}\n\nfunction validateToolGate(gate: ToolGate | undefined, errors: string[]): void {\n\tif (!gate) {\n\t\terrors.push(\"missing tools gate\");\n\t\treturn;\n\t}\n\tif (gate.defaultMode !== undefined && !KNOWN_TOOL_DEFAULT_MODES.has(gate.defaultMode)) {\n\t\terrors.push(`unknown tool defaultMode: ${String(gate.defaultMode)}`);\n\t}\n}\n\nfunction validateCapabilityGate(\n\tgateName: string,\n\texpectedKind: ResourceKind,\n\tgate: CapabilityGate | undefined,\n\terrors: string[],\n): void {\n\tif (!gate) return;\n\tfor (const group of [\"allow\", \"exclude\", \"require\"] as const) {\n\t\tconst selectors = gate[group];\n\t\tif (!selectors) continue;\n\t\tfor (const selector of selectors) {\n\t\t\tif (!KNOWN_RESOURCE_KINDS.has(selector.kind)) {\n\t\t\t\terrors.push(`unknown resource kind in ${gateName}.${group}: ${String(selector.kind)}`);\n\t\t\t} else if (selector.kind !== expectedKind) {\n\t\t\t\terrors.push(\n\t\t\t\t\t`mismatched selector kind in ${gateName}.${group}: expected ${expectedKind}, got ${selector.kind}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction commandModeAuthorityConflict(mode: CommandMode, authority: LoadoutAuthority): string | undefined {\n\tif (mode === \"scoped-shell\" && authority !== \"write-scoped\") {\n\t\treturn `command mode scoped-shell requires write-scoped authority, got ${authority}`;\n\t}\n\tif (mode === \"tests-only\" && authority !== \"execute-tests\" && authority !== \"write-scoped\") {\n\t\treturn `command mode tests-only requires execute-tests or write-scoped authority, got ${authority}`;\n\t}\n\treturn undefined;\n}\n\nfunction globMatch(glob: string, value: string): boolean {\n\treturn globToRegExp(glob).test(value);\n}\n\nfunction globToRegExp(glob: string): RegExp {\n\tlet pattern = \"\";\n\tfor (let index = 0; index < glob.length; index++) {\n\t\tconst char = glob[index];\n\t\tif (char === \"*\") {\n\t\t\tif (glob[index + 1] === \"*\") {\n\t\t\t\tpattern += \".*\";\n\t\t\t\tindex++;\n\t\t\t} else {\n\t\t\t\tpattern += \"[^/]*\";\n\t\t\t}\n\t\t} else if (char === \"?\") {\n\t\t\tpattern += \".\";\n\t\t} else {\n\t\t\tpattern += char.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\t\t}\n\t}\n\treturn new RegExp(`^${pattern}$`);\n}\n\nfunction compareString(a: string, b: string): number {\n\tif (a < b) return -1;\n\tif (a > b) return 1;\n\treturn 0;\n}\n"]}
1
+ {"version":3,"file":"loadouts.js","sourceRoot":"","sources":["../../src/core/loadouts.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure loadout / lane-profile algorithms for the OMK control plane.\n *\n * This module is I/O-free. It owns the loadout schema, built-in presets,\n * capability gating (allow/exclude/require selectors), profile validation, and\n * the derivation of scheduler read/write/parallelizable fields from a lane's\n * optional assigned paths. Runtime wiring (AgentSession tool registry, skill\n * prompt construction, MCP runtime, scheduler admission) lives in sibling\n * modules and consumes the decisions made here.\n *\n * Schema and presets follow the OMK package hardening loadout plan.\n *\n * Erasable TypeScript only (no enum/namespace/parameter properties).\n */\n\nimport type { HookPolicyMetadata } from \"./hooks/index.ts\";\n\nexport type LoadoutAuthority =\n\t| \"advisory\"\n\t| \"read-only\"\n\t| \"execute-tests\"\n\t| \"write-scoped\"\n\t| \"review-only\"\n\t| \"security-review\";\n\nexport type LoadoutRole =\n\t| \"planner\"\n\t| \"explorer\"\n\t| \"architect\"\n\t| \"coder\"\n\t| \"executor\"\n\t| \"tester\"\n\t| \"reviewer\"\n\t| \"critic\"\n\t| \"security\"\n\t| \"visual-qa\"\n\t| \"rhwp-doc\"\n\t| \"synthesizer\"\n\t| \"package-maintainer\";\n\n/** Resource kinds the loadout layer can describe. Only the last four are gated here. */\nexport type ResourceKind = \"extension\" | \"skill\" | \"prompt\" | \"theme\" | \"tool\" | \"mcp\" | \"hook\";\nexport type ResourceOrigin = \"package\" | \"top-level\";\nexport type SourceScope = \"user\" | \"project\" | \"temporary\" | \"builtin\";\nexport type CommandMode = \"none\" | \"read-only-shell\" | \"tests-only\" | \"scoped-shell\";\nexport type ToolDefaultMode = \"default-builtins\" | \"no-tools\" | \"no-builtin-tools\";\n\nexport interface NamedResource {\n\tkind: ResourceKind;\n\tname: string;\n\tsource?: string;\n\tscope?: SourceScope;\n\t/** Package-relative or absolute resource path, when meaningful (skills/prompts). */\n\tpath?: string;\n\torigin?: ResourceOrigin;\n\tpolicy?: HookPolicyMetadata;\n}\n\n/**\n * A selector matches inventory resources by name and/or provenance criteria.\n * A resource matches when its kind equals `kind` and every defined criterion\n * matches (names is an OR over the listed names; paths/sources are OR over globs).\n */\nexport interface ResourceSelector {\n\tkind: ResourceKind;\n\tnames?: readonly string[];\n\t/** Glob patterns matched against `NamedResource.path`. */\n\tpaths?: readonly string[];\n\t/** Glob patterns matched against `NamedResource.source`. */\n\tsources?: readonly string[];\n\tscopes?: readonly SourceScope[];\n\torigins?: readonly ResourceOrigin[];\n\t/** Marker only; requirement is expressed by placement in `CapabilityGate.require`. */\n\trequired?: boolean;\n}\n\n/** Tool gating uses flat name arrays (mapped to SDK tools / setActiveTools). */\nexport interface ToolGate {\n\tallow?: readonly string[];\n\texclude?: readonly string[];\n\trequire?: readonly string[];\n\tdefaultMode?: ToolDefaultMode;\n}\n\n/** Skills / MCP / hooks gating uses selector arrays. */\nexport interface CapabilityGate {\n\tallow?: readonly ResourceSelector[];\n\texclude?: readonly ResourceSelector[];\n\trequire?: readonly ResourceSelector[];\n}\n\nexport interface LoadoutCommands {\n\tmode: CommandMode;\n\tallowPatterns?: readonly string[];\n\tblockPatterns?: readonly string[];\n}\n\nexport interface LoadoutEvidence {\n\trequired: boolean;\n\toutputPattern: string;\n}\n\nexport interface LoadoutProfile {\n\tschemaVersion: \"omk.loadout.v1\";\n\tname: string;\n\tdescription?: string;\n\tauthority: LoadoutAuthority;\n\ttools: ToolGate;\n\tskills?: CapabilityGate;\n\tmcp?: CapabilityGate;\n\thooks?: CapabilityGate;\n\tcommands?: LoadoutCommands;\n\tevidence?: LoadoutEvidence;\n}\n\nexport interface CapabilityInventory {\n\ttools: readonly NamedResource[];\n\tskills: readonly NamedResource[];\n\tmcp: readonly NamedResource[];\n\thooks: readonly NamedResource[];\n}\n\nexport interface LaneDefaults {\n\tloadout: string;\n\tauthority: LoadoutAuthority;\n\tparallelizable: boolean;\n\treadOnly: boolean;\n\twritesProductFiles: boolean;\n}\n\nexport interface AppliedLoadout {\n\tprofileName: string;\n\tauthority: LoadoutAuthority;\n\tactiveTools: string[];\n\tactiveSkills: string[];\n\tactiveMcp: string[];\n\tactiveHooks: string[];\n\tblockers: string[];\n\twarnings: string[];\n}\n\nexport interface LoadoutValidation {\n\tvalid: boolean;\n\terrors: string[];\n}\n\n/** A scheduler access entry; shape matches `AccessSetEntry` in the orchestration layer. */\nexport interface LoadoutAccessEntry {\n\tpath: string;\n\tsymbols?: readonly string[];\n}\n\nexport interface SchedulerFields {\n\treadSet: LoadoutAccessEntry[];\n\twriteSet: LoadoutAccessEntry[];\n\tparallelizable: boolean;\n}\n\nexport interface SchedulerDerivationInput {\n\trole: LoadoutRole;\n\tassignedReadPaths?: readonly string[];\n\tassignedWritePaths?: readonly string[];\n}\n\nconst AUTHORITY_RANK: Record<LoadoutAuthority, number> = {\n\tadvisory: 0,\n\t\"read-only\": 1,\n\t\"review-only\": 1,\n\t\"security-review\": 2,\n\t\"execute-tests\": 3,\n\t\"write-scoped\": 4,\n};\n\nconst KNOWN_RESOURCE_KINDS: ReadonlySet<ResourceKind> = new Set([\n\t\"extension\",\n\t\"skill\",\n\t\"prompt\",\n\t\"theme\",\n\t\"tool\",\n\t\"mcp\",\n\t\"hook\",\n]);\n\nconst KNOWN_COMMAND_MODES: ReadonlySet<CommandMode> = new Set([\n\t\"none\",\n\t\"read-only-shell\",\n\t\"tests-only\",\n\t\"scoped-shell\",\n]);\n\nconst KNOWN_TOOL_DEFAULT_MODES: ReadonlySet<ToolDefaultMode> = new Set([\n\t\"default-builtins\",\n\t\"no-tools\",\n\t\"no-builtin-tools\",\n]);\n\n/** Roles permitted to declare a non-empty writeSet during scheduler derivation. */\nconst WRITING_ROLES: ReadonlySet<LoadoutRole> = new Set([\n\t\"coder\",\n\t\"executor\",\n\t\"tester\",\n\t\"rhwp-doc\",\n\t\"synthesizer\",\n\t\"package-maintainer\",\n]);\n\nconst LOCKFILE_BASENAMES: ReadonlySet<string> = new Set([\n\t\"package-lock.json\",\n\t\"npm-shrinkwrap.json\",\n\t\"yarn.lock\",\n\t\"pnpm-lock.yaml\",\n]);\n\nfunction allowNames(kind: ResourceKind, names: readonly string[]): CapabilityGate {\n\treturn { allow: [{ kind, names }] };\n}\n\nexport const BUILTIN_LOADOUTS: Readonly<Record<string, LoadoutProfile>> = {\n\tinspect: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"inspect\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\tplan: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"plan\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\tarchitect: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"architect\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\", \"report_finding\"] },\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\tcode: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"code\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\"test-driven-development\", \"coding-standards\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\", \"context7\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"typecheck-after-edit\"]),\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\texecutor: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"executor\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\"test-driven-development\", \"coding-standards\", \"verification-before-completion\"]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\", \"context7\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"typecheck-after-edit\", \"stop-verify\"]),\n\t\tcommands: { mode: \"scoped-shell\" },\n\t\tevidence: { required: true, outputPattern: \".omk/runs/<goal>/implementation.md\" },\n\t},\n\ttest: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"test\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\treview: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"review\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\tcritic: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"critic\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\tsecurity: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"security\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\t\"visual-qa\": {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"visual-qa\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\n\t\t\t\"clone-website\",\n\t\t\t\"visual-qa\",\n\t\t\t\"visual-diff\",\n\t\t\t\"visual-regression\",\n\t\t\t\"browser-qa\",\n\t\t\t\"web-quality-audit\",\n\t\t]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\", \"chrome-devtools\", \"playwright\", \"context7\"]),\n\t\thooks: allowNames(\"hook\", [\n\t\t\t\"component-spec-before-build\",\n\t\t\t\"visual-diff-after-edit\",\n\t\t\t\"typecheck-after-edit\",\n\t\t\t\"bounded-evidence\",\n\t\t\t\"protect-secrets\",\n\t\t\t\"stop-verify\",\n\t\t]),\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n\t\"rhwp-doc\": {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"rhwp-doc\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\n\t\t\t\"rhwp\",\n\t\t\t\"rhwp-doc\",\n\t\t\t\"document-extraction\",\n\t\t\t\"document-conversion\",\n\t\t\t\"technical-writing\",\n\t\t]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\", \"context7\", \"playwright\"]),\n\t\thooks: allowNames(\"hook\", [\n\t\t\t\"document-artifact-guard\",\n\t\t\t\"bounded-evidence\",\n\t\t\t\"pre-shell-guard\",\n\t\t\t\"protect-secrets\",\n\t\t\t\"stop-verify\",\n\t\t]),\n\t\tcommands: { mode: \"scoped-shell\" },\n\t\tevidence: { required: true, outputPattern: \".omk/runs/<goal>/rhwp-doc.md\" },\n\t},\n\t\"package-maintainer\": {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"package-maintainer\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tskills: allowNames(\"skill\", [\n\t\t\t\"exact-pin\",\n\t\t\t\"no-lifecycle-scripts\",\n\t\t\t\"security-review\",\n\t\t\t\"verification-before-completion\",\n\t\t]),\n\t\tmcp: allowNames(\"mcp\", [\"filesystem\"]),\n\t\thooks: allowNames(\"hook\", [\"pre-shell-guard\", \"protect-secrets\", \"npm-audit-summary\", \"stop-verify\"]),\n\t\tcommands: {\n\t\t\tmode: \"scoped-shell\",\n\t\t\tallowPatterns: [\n\t\t\t\t\"npm install --ignore-scripts*\",\n\t\t\t\t\"npm ci --ignore-scripts*\",\n\t\t\t\t\"npm install --package-lock-only --ignore-scripts*\",\n\t\t\t\t\"node scripts/generate-coding-agent-shrinkwrap.mjs*\",\n\t\t\t],\n\t\t\tblockPatterns: [\n\t\t\t\t\"*@latest*\",\n\t\t\t\t\"npm install *--ignore-scripts=false*\",\n\t\t\t\t\"npm ci *--ignore-scripts=false*\",\n\t\t\t\t\"npm rebuild*\",\n\t\t\t],\n\t\t},\n\t},\n\tnone: {\n\t\tschemaVersion: \"omk.loadout.v1\",\n\t\tname: \"none\",\n\t\tauthority: \"write-scoped\",\n\t\ttools: { allow: [\"read\", \"grep\", \"find\", \"ls\", \"edit\", \"write\", \"bash\"] },\n\t\tcommands: { mode: \"scoped-shell\" },\n\t},\n};\n\nexport function inferLoadoutForRole(role: LoadoutRole): string {\n\tswitch (role) {\n\t\tcase \"planner\":\n\t\t\treturn \"plan\";\n\t\tcase \"explorer\":\n\t\t\treturn \"inspect\";\n\t\tcase \"architect\":\n\t\t\treturn \"architect\";\n\t\tcase \"coder\":\n\t\t\treturn \"code\";\n\t\tcase \"executor\":\n\t\t\treturn \"executor\";\n\t\tcase \"tester\":\n\t\t\treturn \"test\";\n\t\tcase \"reviewer\":\n\t\t\treturn \"review\";\n\t\tcase \"critic\":\n\t\t\treturn \"critic\";\n\t\tcase \"security\":\n\t\t\treturn \"security\";\n\t\tcase \"visual-qa\":\n\t\t\treturn \"visual-qa\";\n\t\tcase \"rhwp-doc\":\n\t\t\treturn \"rhwp-doc\";\n\t\tcase \"package-maintainer\":\n\t\t\treturn \"package-maintainer\";\n\t\tcase \"synthesizer\":\n\t\t\treturn \"plan\";\n\t}\n}\n\nexport function authorityWithinGrant(requested: LoadoutAuthority, grant: LoadoutAuthority): boolean {\n\treturn AUTHORITY_RANK[requested] <= AUTHORITY_RANK[grant];\n}\n\nexport function laneDefaultsForRole(role: LoadoutRole): LaneDefaults {\n\tconst loadout = inferLoadoutForRole(role);\n\tconst profile = BUILTIN_LOADOUTS[loadout];\n\treturn {\n\t\tloadout,\n\t\tauthority: profile.authority,\n\t\tparallelizable: profile.authority !== \"write-scoped\",\n\t\treadOnly:\n\t\t\tprofile.authority === \"read-only\" || profile.authority === \"review-only\" || profile.authority === \"advisory\",\n\t\twritesProductFiles: profile.authority === \"write-scoped\",\n\t};\n}\n\nexport function applyLoadoutProfile(\n\tprofile: LoadoutProfile,\n\tinventory: CapabilityInventory,\n\toptions: { grantAuthority?: LoadoutAuthority } = {},\n): AppliedLoadout {\n\tconst blockers: string[] = [];\n\tconst warnings: string[] = [];\n\t// Deterministic blocker order: authority, then tool/skill/mcp/hook requires.\n\tif (options.grantAuthority && !authorityWithinGrant(profile.authority, options.grantAuthority)) {\n\t\tblockers.push(`loadout authority ${profile.authority} exceeds grant ${options.grantAuthority}`);\n\t}\n\n\tconst activeTools = applyToolGate(profile.tools, inventory.tools, blockers, warnings);\n\tconst activeSkills = applyCapabilityGate(\"skill\", profile.skills, inventory.skills, blockers, warnings);\n\tconst activeMcp = applyCapabilityGate(\"mcp\", profile.mcp, inventory.mcp, blockers, warnings);\n\tconst activeHooks = applyCapabilityGate(\"hook\", profile.hooks, inventory.hooks, blockers, warnings);\n\n\treturn {\n\t\tprofileName: profile.name,\n\t\tauthority: profile.authority,\n\t\tactiveTools,\n\t\tactiveSkills,\n\t\tactiveMcp,\n\t\tactiveHooks,\n\t\tblockers,\n\t\twarnings,\n\t};\n}\n\n/**\n * Fail-closed structural validation of a loadout profile. Errors are returned\n * in a deterministic order: schemaVersion, name, authority, tools, skills, mcp,\n * hooks, commands.\n */\nexport function validateLoadoutProfile(profile: LoadoutProfile): LoadoutValidation {\n\tconst errors: string[] = [];\n\tif (profile.schemaVersion !== \"omk.loadout.v1\") {\n\t\terrors.push(`unknown schemaVersion: ${String(profile.schemaVersion)}`);\n\t}\n\tif (typeof profile.name !== \"string\" || profile.name.trim() === \"\") {\n\t\terrors.push(\"missing loadout name\");\n\t}\n\tif (!(profile.authority in AUTHORITY_RANK)) {\n\t\terrors.push(`unknown authority: ${String(profile.authority)}`);\n\t}\n\tvalidateToolGate(profile.tools, errors);\n\tvalidateCapabilityGate(\"skills\", \"skill\", profile.skills, errors);\n\tvalidateCapabilityGate(\"mcp\", \"mcp\", profile.mcp, errors);\n\tvalidateCapabilityGate(\"hooks\", \"hook\", profile.hooks, errors);\n\tif (profile.commands) {\n\t\tif (!KNOWN_COMMAND_MODES.has(profile.commands.mode)) {\n\t\t\terrors.push(`unknown command mode: ${String(profile.commands.mode)}`);\n\t\t} else if (profile.authority in AUTHORITY_RANK) {\n\t\t\tconst conflict = commandModeAuthorityConflict(profile.commands.mode, profile.authority);\n\t\t\tif (conflict) errors.push(conflict);\n\t\t}\n\t}\n\treturn { valid: errors.length === 0, errors };\n}\n\n/**\n * Derive scheduler readSet/writeSet/parallelizable from a lane role plus the\n * optional paths granted to that lane. Non-writing roles never produce a\n * writeSet. parallelizable is false when a write-scoped lane writes anything,\n * or when any write touches a lockfile, package config, snapshot, or git index.\n */\nexport function deriveSchedulerFields(input: SchedulerDerivationInput): SchedulerFields {\n\tconst defaults = laneDefaultsForRole(input.role);\n\tconst readSet = toAccessSet(input.assignedReadPaths);\n\tconst writeSet = WRITING_ROLES.has(input.role) ? toAccessSet(input.assignedWritePaths) : [];\n\tconst parallelizable = deriveParallelizable(defaults.authority, writeSet);\n\treturn { readSet, writeSet, parallelizable };\n}\n\nfunction deriveParallelizable(authority: LoadoutAuthority, writeSet: readonly LoadoutAccessEntry[]): boolean {\n\tif (writeSet.length === 0) return true;\n\tif (authority === \"write-scoped\") return false;\n\tif (writeSet.some((entry) => isSerializeTriggerPath(entry.path))) return false;\n\treturn true;\n}\n\n/** Lockfile, package config, snapshot, or git-index writes force serialization. */\nexport function isSerializeTriggerPath(path: string): boolean {\n\tconst normalized = path.replaceAll(\"\\\\\", \"/\");\n\tconst base = normalized.slice(normalized.lastIndexOf(\"/\") + 1);\n\tif (LOCKFILE_BASENAMES.has(base)) return true;\n\tif (base === \"package.json\") return true;\n\tif (base.endsWith(\".snap\")) return true;\n\tif (normalized === \".git/index\" || normalized.startsWith(\".git/\") || normalized.includes(\"/.git/\")) return true;\n\treturn false;\n}\n\nfunction toAccessSet(paths: readonly string[] | undefined): LoadoutAccessEntry[] {\n\tif (!paths) return [];\n\tconst seen = new Set<string>();\n\tconst entries: LoadoutAccessEntry[] = [];\n\tfor (const raw of paths) {\n\t\tconst path = raw.trim();\n\t\tif (path === \"\" || seen.has(path)) continue;\n\t\tseen.add(path);\n\t\tentries.push({ path });\n\t}\n\tentries.sort((a, b) => compareString(a.path, b.path));\n\treturn entries;\n}\n\nfunction resourceNames(resources: readonly NamedResource[]): Set<string> {\n\treturn new Set(resources.map((resource) => resource.name));\n}\n\nfunction applyToolGate(\n\tgate: ToolGate,\n\tresources: readonly NamedResource[],\n\tblockers: string[],\n\twarnings: string[],\n): string[] {\n\tconst available = resourceNames(resources);\n\tfor (const required of gate.require ?? []) {\n\t\tif (!available.has(required)) blockers.push(`missing required tool: ${required}`);\n\t}\n\tconst base = gate.defaultMode === \"no-tools\" ? [] : (gate.allow ?? resources.map((resource) => resource.name));\n\tconst excluded = new Set(gate.exclude ?? []);\n\tconst active: string[] = [];\n\tfor (const tool of base) {\n\t\tif (!available.has(tool)) {\n\t\t\twarnings.push(`optional tool not available: ${tool}`);\n\t\t\tcontinue;\n\t\t}\n\t\tif (!excluded.has(tool)) active.push(tool);\n\t}\n\treturn [...new Set(active)].sort(compareString);\n}\n\nfunction applyCapabilityGate(\n\tkind: ResourceKind,\n\tgate: CapabilityGate | undefined,\n\tresources: readonly NamedResource[],\n\tblockers: string[],\n\twarnings: string[],\n): string[] {\n\tif (!gate) return [];\n\tconst active = new Set<string>();\n\n\t// require: every required selector must resolve, else a deterministic blocker.\n\tfor (const selector of gate.require ?? []) {\n\t\tresolveRequireSelector(kind, selector, resources, blockers, active);\n\t}\n\n\t// allow: union of matches; warn on named-but-missing optional capabilities.\n\tfor (const selector of gate.allow ?? []) {\n\t\tfor (const match of matchSelector(selector, resources)) active.add(match.name);\n\t\tfor (const name of selector.names ?? []) {\n\t\t\tif (!resources.some((resource) => resource.name === name && matchesCriteria(selector, resource))) {\n\t\t\t\twarnings.push(`optional ${kind} not available: ${name}`);\n\t\t\t}\n\t\t}\n\t}\n\n\t// exclude: applied last.\n\tconst excluded = new Set<string>();\n\tfor (const selector of gate.exclude ?? []) {\n\t\tfor (const match of matchSelector(selector, resources)) excluded.add(match.name);\n\t}\n\n\tconst result = [...active].filter((name) => !excluded.has(name));\n\treturn [...new Set(result)].sort(compareString);\n}\n\nfunction resolveRequireSelector(\n\tkind: ResourceKind,\n\tselector: ResourceSelector,\n\tresources: readonly NamedResource[],\n\tblockers: string[],\n\tactive: Set<string>,\n): void {\n\tif (selector.names && selector.names.length > 0) {\n\t\tfor (const name of selector.names) {\n\t\t\tconst matched = resources.some((resource) => resource.name === name && matchesCriteria(selector, resource));\n\t\t\tif (matched) active.add(name);\n\t\t\telse blockers.push(`missing required ${kind}: ${name}`);\n\t\t}\n\t\treturn;\n\t}\n\tconst matches = matchSelector(selector, resources);\n\tif (matches.length === 0) {\n\t\tblockers.push(`missing required ${kind}: ${describeSelector(selector)}`);\n\t\treturn;\n\t}\n\tfor (const match of matches) active.add(match.name);\n}\n\nfunction matchSelector(selector: ResourceSelector, resources: readonly NamedResource[]): NamedResource[] {\n\treturn resources.filter((resource) => {\n\t\tif (selector.names && !selector.names.includes(resource.name)) return false;\n\t\treturn matchesCriteria(selector, resource);\n\t});\n}\n\nfunction matchesCriteria(selector: ResourceSelector, resource: NamedResource): boolean {\n\tif (resource.kind !== selector.kind) return false;\n\tif (selector.scopes && (resource.scope === undefined || !selector.scopes.includes(resource.scope))) return false;\n\tif (selector.origins && (resource.origin === undefined || !selector.origins.includes(resource.origin))) return false;\n\tif (selector.sources && !selector.sources.some((glob) => globMatch(glob, resource.source ?? \"\"))) return false;\n\tif (selector.paths && !selector.paths.some((glob) => globMatch(glob, resource.path ?? \"\"))) return false;\n\treturn true;\n}\n\nfunction describeSelector(selector: ResourceSelector): string {\n\tconst parts: string[] = [`kind=${selector.kind}`];\n\tif (selector.paths) parts.push(`paths=${selector.paths.join(\",\")}`);\n\tif (selector.sources) parts.push(`sources=${selector.sources.join(\",\")}`);\n\tif (selector.scopes) parts.push(`scopes=${selector.scopes.join(\",\")}`);\n\tif (selector.origins) parts.push(`origins=${selector.origins.join(\",\")}`);\n\treturn parts.join(\" \");\n}\n\nfunction validateToolGate(gate: ToolGate | undefined, errors: string[]): void {\n\tif (!gate) {\n\t\terrors.push(\"missing tools gate\");\n\t\treturn;\n\t}\n\tif (gate.defaultMode !== undefined && !KNOWN_TOOL_DEFAULT_MODES.has(gate.defaultMode)) {\n\t\terrors.push(`unknown tool defaultMode: ${String(gate.defaultMode)}`);\n\t}\n}\n\nfunction validateCapabilityGate(\n\tgateName: string,\n\texpectedKind: ResourceKind,\n\tgate: CapabilityGate | undefined,\n\terrors: string[],\n): void {\n\tif (!gate) return;\n\tfor (const group of [\"allow\", \"exclude\", \"require\"] as const) {\n\t\tconst selectors = gate[group];\n\t\tif (!selectors) continue;\n\t\tfor (const selector of selectors) {\n\t\t\tif (!KNOWN_RESOURCE_KINDS.has(selector.kind)) {\n\t\t\t\terrors.push(`unknown resource kind in ${gateName}.${group}: ${String(selector.kind)}`);\n\t\t\t} else if (selector.kind !== expectedKind) {\n\t\t\t\terrors.push(\n\t\t\t\t\t`mismatched selector kind in ${gateName}.${group}: expected ${expectedKind}, got ${selector.kind}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction commandModeAuthorityConflict(mode: CommandMode, authority: LoadoutAuthority): string | undefined {\n\tif (mode === \"scoped-shell\" && authority !== \"write-scoped\") {\n\t\treturn `command mode scoped-shell requires write-scoped authority, got ${authority}`;\n\t}\n\tif (mode === \"tests-only\" && authority !== \"execute-tests\" && authority !== \"write-scoped\") {\n\t\treturn `command mode tests-only requires execute-tests or write-scoped authority, got ${authority}`;\n\t}\n\treturn undefined;\n}\n\nfunction globMatch(glob: string, value: string): boolean {\n\treturn globToRegExp(glob).test(value);\n}\n\nfunction globToRegExp(glob: string): RegExp {\n\tlet pattern = \"\";\n\tfor (let index = 0; index < glob.length; index++) {\n\t\tconst char = glob[index];\n\t\tif (char === \"*\") {\n\t\t\tif (glob[index + 1] === \"*\") {\n\t\t\t\tpattern += \".*\";\n\t\t\t\tindex++;\n\t\t\t} else {\n\t\t\t\tpattern += \"[^/]*\";\n\t\t\t}\n\t\t} else if (char === \"?\") {\n\t\t\tpattern += \".\";\n\t\t} else {\n\t\t\tpattern += char.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\t\t}\n\t}\n\treturn new RegExp(`^${pattern}$`);\n}\n\nfunction compareString(a: string, b: string): number {\n\tif (a < b) return -1;\n\tif (a > b) return 1;\n\treturn 0;\n}\n"]}
@@ -2,10 +2,48 @@
2
2
  * Model resolution, scoping, and initial selection
3
3
  */
4
4
  import type { ThinkingLevel } from "omk-agent-core";
5
- import { type Api, type KnownProvider, type Model } from "omk-ai";
5
+ import { type Api, type Model } from "omk-ai";
6
6
  import type { ModelRegistry } from "./model-registry.ts";
7
- /** Default model IDs for each known provider */
8
- export declare const defaultModelPerProvider: Record<KnownProvider, string>;
7
+ /** Default model IDs for built-in and recommended custom providers. */
8
+ export declare const defaultModelPerProvider: {
9
+ readonly "amazon-bedrock": string;
10
+ readonly "ant-ling": string;
11
+ readonly anthropic: string;
12
+ readonly openai: string;
13
+ readonly "azure-openai-responses": string;
14
+ readonly "openai-codex": string;
15
+ readonly nvidia: string;
16
+ readonly deepseek: string;
17
+ readonly google: string;
18
+ readonly "google-vertex": string;
19
+ readonly "github-copilot": string;
20
+ readonly openrouter: string;
21
+ readonly "vercel-ai-gateway": string;
22
+ readonly xai: string;
23
+ readonly groq: string;
24
+ readonly cerebras: string;
25
+ readonly zai: string;
26
+ readonly "zai-coding-cn": string;
27
+ readonly mistral: string;
28
+ readonly minimax: string;
29
+ readonly "minimax-cn": string;
30
+ readonly moonshotai: string;
31
+ readonly "moonshotai-cn": string;
32
+ readonly huggingface: string;
33
+ readonly fireworks: string;
34
+ readonly together: string;
35
+ readonly opencode: string;
36
+ readonly "opencode-go": string;
37
+ readonly "kimi-coding": string;
38
+ readonly "cloudflare-workers-ai": string;
39
+ readonly "cloudflare-ai-gateway": string;
40
+ readonly xiaomi: string;
41
+ readonly "xiaomi-token-plan-cn": string;
42
+ readonly "xiaomi-token-plan-ams": string;
43
+ readonly "xiaomi-token-plan-sgp": string;
44
+ readonly zyloo: string;
45
+ readonly "modelstudio-maas": "qwen3.8-max-preview";
46
+ };
9
47
  export interface ScopedModel {
10
48
  model: Model<Api>;
11
49
  /** Thinking level if explicitly specified in pattern (e.g., "model:high"), undefined otherwise */