@ngocsangairvds/vsaf 4.1.9 → 4.1.11

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 (1053) hide show
  1. package/package.json +1 -1
  2. package/packages/cli/dist/commands/install.d.ts +1 -1
  3. package/packages/cli/dist/commands/install.d.ts.map +1 -1
  4. package/packages/cli/dist/commands/install.js +25 -13
  5. package/packages/cli/dist/commands/install.js.map +1 -1
  6. package/packages/cli/dist/commands/skill.d.ts.map +1 -1
  7. package/packages/cli/dist/commands/skill.js +5 -1
  8. package/packages/cli/dist/commands/skill.js.map +1 -1
  9. package/skills/vds-skill/install-deps.mjs +252 -0
  10. package/skills/vds-skill/pack.yaml +8 -0
  11. package/skills/vds-skill/runtime/.claude/phase7-CLOSURE.md +100 -0
  12. package/skills/vds-skill/runtime/.dockerignore +62 -0
  13. package/skills/vds-skill/runtime/.github/ISSUE_TEMPLATE/cli-change.md +92 -0
  14. package/skills/vds-skill/runtime/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +48 -0
  15. package/skills/vds-skill/runtime/.github/workflows/chaos-smoke.yml +266 -0
  16. package/skills/vds-skill/runtime/.github/workflows/confluence-sync.yml +44 -0
  17. package/skills/vds-skill/runtime/.github/workflows/docs-confluence-evidence.yml +170 -0
  18. package/skills/vds-skill/runtime/.github/workflows/docs-quality.yml +59 -0
  19. package/skills/vds-skill/runtime/.github/workflows/lint-and-test.yml +90 -0
  20. package/skills/vds-skill/runtime/.github/workflows/scheduler-load-smoke.yml +104 -0
  21. package/skills/vds-skill/runtime/.github/workflows/telegram-bridge-ci.yml +131 -0
  22. package/skills/vds-skill/runtime/.graphifyignore +29 -0
  23. package/skills/vds-skill/runtime/.importlinter +86 -0
  24. package/skills/vds-skill/runtime/.mcp.json +11 -0
  25. package/skills/vds-skill/runtime/.pre-commit-config.yaml +62 -0
  26. package/skills/vds-skill/runtime/.ruffignore +3 -0
  27. package/skills/vds-skill/runtime/AGENTS.md +250 -0
  28. package/skills/vds-skill/runtime/AGENTS.vi.md +92 -0
  29. package/skills/vds-skill/runtime/ECOSYSTEM-CHANGELOG.md +52 -0
  30. package/skills/vds-skill/runtime/ECOSYSTEM-DOCS.md +602 -0
  31. package/skills/vds-skill/runtime/ECOSYSTEM_ALIGNMENT.md +133 -0
  32. package/skills/vds-skill/runtime/Makefile +119 -0
  33. package/skills/vds-skill/runtime/README.md +103 -0
  34. package/skills/vds-skill/runtime/bitbucket_manifest_mapping.toml +34 -0
  35. package/skills/vds-skill/runtime/bitbucket_orchestrator/ARCHITECTURE_ANALYSIS.md +258 -0
  36. package/skills/vds-skill/runtime/bitbucket_orchestrator/BITBUCKET_API_PRACTICES.md +393 -0
  37. package/skills/vds-skill/runtime/bitbucket_orchestrator/EVALUATION_REPORT.md +61 -0
  38. package/skills/vds-skill/runtime/bitbucket_orchestrator/FEATURES.md +908 -0
  39. package/skills/vds-skill/runtime/bitbucket_orchestrator/README.md +817 -0
  40. package/skills/vds-skill/runtime/bitbucket_orchestrator/pyproject.toml +49 -0
  41. package/skills/vds-skill/runtime/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/__init__.py +50 -0
  42. package/skills/vds-skill/runtime/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/async_client.py +641 -0
  43. package/skills/vds-skill/runtime/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/cli.py +2271 -0
  44. package/skills/vds-skill/runtime/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/client.py +2693 -0
  45. package/skills/vds-skill/runtime/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/config.py +185 -0
  46. package/skills/vds-skill/runtime/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/errors.py +34 -0
  47. package/skills/vds-skill/runtime/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/factory.py +185 -0
  48. package/skills/vds-skill/runtime/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/parsers.py +113 -0
  49. package/skills/vds-skill/runtime/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/protocols.py +244 -0
  50. package/skills/vds-skill/runtime/bitbucket_orchestrator/src/vds_bitbucket_orchestrator/repo_ops.py +325 -0
  51. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/__init__.py +8 -0
  52. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/conftest.py +65 -0
  53. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_advanced_search.py +155 -0
  54. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_async_client.py +505 -0
  55. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_branch_permissions.py +172 -0
  56. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_cli.py +113 -0
  57. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_cli_archive.py +122 -0
  58. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_cli_clone.py +131 -0
  59. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_client.py +207 -0
  60. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_client_archive.py +73 -0
  61. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_client_branch_conditions.py +101 -0
  62. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_client_code_advanced.py +180 -0
  63. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_client_code_file.py +33 -0
  64. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_client_deployment_environments.py +193 -0
  65. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_client_issues.py +163 -0
  66. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_client_pipelines_advanced.py +171 -0
  67. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_client_pr_blockers.py +118 -0
  68. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_client_repository_variables.py +155 -0
  69. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_code.py +98 -0
  70. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_code_advanced.py +279 -0
  71. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_code_insights.py +334 -0
  72. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_conditions.py +149 -0
  73. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_config.py +297 -0
  74. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_deployment_env.py +352 -0
  75. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_errors.py +67 -0
  76. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_factory.py +352 -0
  77. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_fork_operations.py +203 -0
  78. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_issue_cli.py +262 -0
  79. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_pipeline_advanced.py +265 -0
  80. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_pr_blocker.py +206 -0
  81. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_protocols.py +336 -0
  82. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_repo_ops_archive.py +169 -0
  83. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_repo_ops_clone.py +115 -0
  84. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_repo_ops_parsing.py +149 -0
  85. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_repo_settings.py +336 -0
  86. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_repo_variables.py +266 -0
  87. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_webhooks.py +188 -0
  88. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/test_workspace.py +234 -0
  89. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/unit/__init__.py +0 -0
  90. package/skills/vds-skill/runtime/bitbucket_orchestrator/tests/unit/test_parsers.py +254 -0
  91. package/skills/vds-skill/runtime/brd_orchestrator/README.md +29 -0
  92. package/skills/vds-skill/runtime/brd_orchestrator/pyproject.toml +63 -0
  93. package/skills/vds-skill/runtime/brd_orchestrator/src/vds_brd_orchestrator/__init__.py +17 -0
  94. package/skills/vds-skill/runtime/brd_orchestrator/src/vds_brd_orchestrator/cli.py +187 -0
  95. package/skills/vds-skill/runtime/brd_orchestrator/src/vds_brd_orchestrator/validator.py +121 -0
  96. package/skills/vds-skill/runtime/brd_orchestrator/tests/__init__.py +0 -0
  97. package/skills/vds-skill/runtime/brd_orchestrator/tests/test_cli.py +62 -0
  98. package/skills/vds-skill/runtime/brd_orchestrator/tests/test_validator.py +33 -0
  99. package/skills/vds-skill/runtime/code/code_evidence_pack.json +435 -0
  100. package/skills/vds-skill/runtime/confluence_orchestrator/Dockerfile +19 -0
  101. package/skills/vds-skill/runtime/confluence_orchestrator/README.md +479 -0
  102. package/skills/vds-skill/runtime/confluence_orchestrator/SYNC_SCRIPTS.md +127 -0
  103. package/skills/vds-skill/runtime/confluence_orchestrator/SYNC_STANDARDIZATION.md +108 -0
  104. package/skills/vds-skill/runtime/confluence_orchestrator/pyproject.toml +50 -0
  105. package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/__init__.py +56 -0
  106. package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/async_client.py +100 -0
  107. package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/cli.py +3160 -0
  108. package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/config.py +213 -0
  109. package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/content.py +368 -0
  110. package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/content_v2.py +144 -0
  111. package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/crawl_tree.py +1833 -0
  112. package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/errors.py +44 -0
  113. package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/eventing.py +111 -0
  114. package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/http.py +1850 -0
  115. package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/orchestration.py +166 -0
  116. package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/protocols.py +61 -0
  117. package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/reporting.py +78 -0
  118. package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/tree.py +122 -0
  119. package/skills/vds-skill/runtime/confluence_orchestrator/src/confluence_orchestrator/tree_copier.py +431 -0
  120. package/skills/vds-skill/runtime/confluence_orchestrator/sync_pdfs_from_markdown.py +203 -0
  121. package/skills/vds-skill/runtime/confluence_orchestrator/sync_pdfs_to_confluence.py +299 -0
  122. package/skills/vds-skill/runtime/confluence_orchestrator/sync_png_attachments.py +299 -0
  123. package/skills/vds-skill/runtime/confluence_orchestrator/tests/conftest.py +46 -0
  124. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_advanced_content.py +252 -0
  125. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_advanced_search.py +193 -0
  126. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_async_client.py +104 -0
  127. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_cache_management.py +246 -0
  128. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_cli.py +716 -0
  129. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_config.py +130 -0
  130. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_content.py +192 -0
  131. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_content_flags.py +27 -0
  132. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_content_labels.py +94 -0
  133. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_crawl_tree.py +2252 -0
  134. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_degraded_write_safety.py +176 -0
  135. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_draft_management.py +225 -0
  136. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_errors.py +75 -0
  137. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_eventing.py +73 -0
  138. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_eventing_chaos.py +37 -0
  139. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_eventing_rate_limit.py +44 -0
  140. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_eventing_timeout.py +49 -0
  141. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_export.py +231 -0
  142. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_history.py +217 -0
  143. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_http.py +375 -0
  144. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_orchestration.py +93 -0
  145. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_reporting.py +24 -0
  146. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_search_cql.py +36 -0
  147. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_space_management.py +236 -0
  148. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_space_permissions.py +384 -0
  149. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_tree_copier.py +644 -0
  150. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_tree_copier_remap.py +289 -0
  151. package/skills/vds-skill/runtime/confluence_orchestrator/tests/test_user_group_management.py +387 -0
  152. package/skills/vds-skill/runtime/diagram_generator/README.md +663 -0
  153. package/skills/vds-skill/runtime/diagram_generator/ci_validate.sh +16 -0
  154. package/skills/vds-skill/runtime/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-component.png +0 -0
  155. package/skills/vds-skill/runtime/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-component.puml +23 -0
  156. package/skills/vds-skill/runtime/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-sequence.png +0 -0
  157. package/skills/vds-skill/runtime/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-sequence.puml +21 -0
  158. package/skills/vds-skill/runtime/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-usecase.png +0 -0
  159. package/skills/vds-skill/runtime/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-usecase.puml +14 -0
  160. package/skills/vds-skill/runtime/diagram_generator/examples/github-actions-validate.yml +39 -0
  161. package/skills/vds-skill/runtime/diagram_generator/generate_all_diagrams.py +827 -0
  162. package/skills/vds-skill/runtime/diagram_generator/generate_insurance_c4_diagrams.py +261 -0
  163. package/skills/vds-skill/runtime/diagram_generator/generate_insurance_c4_quick.py +486 -0
  164. package/skills/vds-skill/runtime/diagram_generator/pyproject.toml +28 -0
  165. package/skills/vds-skill/runtime/diagram_generator/render_png.py +59 -0
  166. package/skills/vds-skill/runtime/diagram_generator/src/vds_diagram_generator/__init__.py +3 -0
  167. package/skills/vds-skill/runtime/diagram_generator/src/vds_diagram_generator/cli.py +50 -0
  168. package/skills/vds-skill/runtime/diagram_generator/test_c4_hierarchical.py +142 -0
  169. package/skills/vds-skill/runtime/diagram_generator/test_c4_quick.py +131 -0
  170. package/skills/vds-skill/runtime/diagram_generator/tests/__init__.py +0 -0
  171. package/skills/vds-skill/runtime/diagram_generator/tests/test_analyzer_completeness.py +260 -0
  172. package/skills/vds-skill/runtime/diagram_generator/tests/test_c4_syntax_correctness.py +138 -0
  173. package/skills/vds-skill/runtime/diagram_generator/tests/test_component_coverage.py +182 -0
  174. package/skills/vds-skill/runtime/diagram_generator/tests/test_mermaid_output.py +80 -0
  175. package/skills/vds-skill/runtime/diagram_generator/tests/test_png_generation.py +112 -0
  176. package/skills/vds-skill/runtime/diagram_generator/tests/test_scenario_templates.py +15 -0
  177. package/skills/vds-skill/runtime/diagram_generator/tests/test_sequence_accuracy.py +93 -0
  178. package/skills/vds-skill/runtime/diagram_generator/tests/test_structurizr_export.py +177 -0
  179. package/skills/vds-skill/runtime/diagram_generator/tests/test_style_consistency.py +174 -0
  180. package/skills/vds-skill/runtime/diagram_generator/tests/test_usecase_generator.py +201 -0
  181. package/skills/vds-skill/runtime/diagram_generator/tests/test_usecase_integration.py +124 -0
  182. package/skills/vds-skill/runtime/docker/.dockerignore +38 -0
  183. package/skills/vds-skill/runtime/docker/ADR.md +392 -0
  184. package/skills/vds-skill/runtime/docker/Dockerfile +68 -0
  185. package/skills/vds-skill/runtime/docker/MIGRATION.md +453 -0
  186. package/skills/vds-skill/runtime/docker/README.md +347 -0
  187. package/skills/vds-skill/runtime/docker/ROLLBACK.md +596 -0
  188. package/skills/vds-skill/runtime/docker/compose.phase2-verification.yml +31 -0
  189. package/skills/vds-skill/runtime/docker/docker-compose.cli.yml +206 -0
  190. package/skills/vds-skill/runtime/docker/docker-compose.infra.yml +276 -0
  191. package/skills/vds-skill/runtime/docker/docker-compose.services.yml +425 -0
  192. package/skills/vds-skill/runtime/docker/infrastructure/init-schemas.sql +177 -0
  193. package/skills/vds-skill/runtime/docker/infrastructure/pgbouncer/pgbouncer.ini +75 -0
  194. package/skills/vds-skill/runtime/docker/infrastructure/pgbouncer/userlist.txt +50 -0
  195. package/skills/vds-skill/runtime/docker/infrastructure/pgbouncer/userlist.txt.template +36 -0
  196. package/skills/vds-skill/runtime/docs/.confluence-evidence/.gitkeep +0 -0
  197. package/skills/vds-skill/runtime/docs/.confluence-evidence/PREFLIGHT.md +132 -0
  198. package/skills/vds-skill/runtime/docs/.confluence-evidence/README.md +84 -0
  199. package/skills/vds-skill/runtime/docs/.confluence.yaml +156 -0
  200. package/skills/vds-skill/runtime/docs/.freshness.yaml +54 -0
  201. package/skills/vds-skill/runtime/docs/README.md +235 -0
  202. package/skills/vds-skill/runtime/docs/agents/README.md +33 -0
  203. package/skills/vds-skill/runtime/docs/agents/explanation/data-flow.md +132 -0
  204. package/skills/vds-skill/runtime/docs/agents/explanation/development-roadmap.md +49 -0
  205. package/skills/vds-skill/runtime/docs/agents/explanation/features-overview.md +62 -0
  206. package/skills/vds-skill/runtime/docs/agents/explanation/index.md +36 -0
  207. package/skills/vds-skill/runtime/docs/agents/explanation/runtime-verification-and-gap-reporting.md +127 -0
  208. package/skills/vds-skill/runtime/docs/agents/explanation/system-architecture.md +139 -0
  209. package/skills/vds-skill/runtime/docs/agents/explanation/whats-new.md +75 -0
  210. package/skills/vds-skill/runtime/docs/agents/explanation/who-ecosystem-introduction.md +65 -0
  211. package/skills/vds-skill/runtime/docs/agents/explanation/who-ecosystem-model.md +41 -0
  212. package/skills/vds-skill/runtime/docs/agents/how-to/02-using-vds-ai-memory.md +98 -0
  213. package/skills/vds-skill/runtime/docs/agents/how-to/03-memory-cross-agent.md +241 -0
  214. package/skills/vds-skill/runtime/docs/agents/how-to/04-using-progress-reports.md +240 -0
  215. package/skills/vds-skill/runtime/docs/agents/how-to/08-semantic-search.md +46 -0
  216. package/skills/vds-skill/runtime/docs/agents/how-to/apply-phase3-migration.md +148 -0
  217. package/skills/vds-skill/runtime/docs/agents/how-to/choose-the-right-command-or-skill.md +34 -0
  218. package/skills/vds-skill/runtime/docs/agents/how-to/contribute-new-orchestrator.md +149 -0
  219. package/skills/vds-skill/runtime/docs/agents/how-to/decision-tree.md +63 -0
  220. package/skills/vds-skill/runtime/docs/agents/how-to/first-audit-run.md +83 -0
  221. package/skills/vds-skill/runtime/docs/agents/how-to/index.md +49 -0
  222. package/skills/vds-skill/runtime/docs/agents/how-to/install-and-bootstrap-who-scripts-and-skills.md +314 -0
  223. package/skills/vds-skill/runtime/docs/agents/how-to/orchestrator-workflows/analytics-pipeline-workflow.md +165 -0
  224. package/skills/vds-skill/runtime/docs/agents/how-to/orchestrator-workflows/code-quality-gate-workflow.md +138 -0
  225. package/skills/vds-skill/runtime/docs/agents/how-to/orchestrator-workflows/confluence-bitbucket-sync-workflow.md +130 -0
  226. package/skills/vds-skill/runtime/docs/agents/how-to/orchestrator-workflows/document-delivery-workflow.md +142 -0
  227. package/skills/vds-skill/runtime/docs/agents/how-to/orchestrator-workflows/memory-progress-workflow.md +140 -0
  228. package/skills/vds-skill/runtime/docs/agents/how-to/orchestrator-workflows/research-spec-audit-workflow.md +135 -0
  229. package/skills/vds-skill/runtime/docs/agents/how-to/phase131-all-project-preparation.md +211 -0
  230. package/skills/vds-skill/runtime/docs/agents/how-to/phase131-bounded-parallel-analysis.md +123 -0
  231. package/skills/vds-skill/runtime/docs/agents/how-to/phase131-confluence-upload-recovery.md +204 -0
  232. package/skills/vds-skill/runtime/docs/agents/how-to/phase132-department-preparation.md +144 -0
  233. package/skills/vds-skill/runtime/docs/agents/how-to/run-ecosystem-daily-report.md +213 -0
  234. package/skills/vds-skill/runtime/docs/agents/how-to/tips-and-tricks.md +138 -0
  235. package/skills/vds-skill/runtime/docs/agents/how-to/troubleshooting-guide.md +221 -0
  236. package/skills/vds-skill/runtime/docs/agents/reference/agent-operational-contract.md +162 -0
  237. package/skills/vds-skill/runtime/docs/agents/reference/alignment-phase179-report.md +144 -0
  238. package/skills/vds-skill/runtime/docs/agents/reference/audit-triage-playbook.md +256 -0
  239. package/skills/vds-skill/runtime/docs/agents/reference/backup-restore.md +132 -0
  240. package/skills/vds-skill/runtime/docs/agents/reference/bitbucket-orchestrator.md +56 -0
  241. package/skills/vds-skill/runtime/docs/agents/reference/brd-orchestrator.md +52 -0
  242. package/skills/vds-skill/runtime/docs/agents/reference/capability-coverage-review.md +51 -0
  243. package/skills/vds-skill/runtime/docs/agents/reference/ci-workflows.md +98 -0
  244. package/skills/vds-skill/runtime/docs/agents/reference/circular-dependency-orchestrator.md +55 -0
  245. package/skills/vds-skill/runtime/docs/agents/reference/cli-commands.md +583 -0
  246. package/skills/vds-skill/runtime/docs/agents/reference/cli-development-standards.md +41 -0
  247. package/skills/vds-skill/runtime/docs/agents/reference/cli-help-matrix.md +84 -0
  248. package/skills/vds-skill/runtime/docs/agents/reference/common-errors.md +126 -0
  249. package/skills/vds-skill/runtime/docs/agents/reference/configuration-reference.md +128 -0
  250. package/skills/vds-skill/runtime/docs/agents/reference/confluence-orchestrator.md +56 -0
  251. package/skills/vds-skill/runtime/docs/agents/reference/confluence-sync-target.md +111 -0
  252. package/skills/vds-skill/runtime/docs/agents/reference/confluence-sync.md +46 -0
  253. package/skills/vds-skill/runtime/docs/agents/reference/db-query-orchestrator.md +93 -0
  254. package/skills/vds-skill/runtime/docs/agents/reference/diagrams-orchestrator.md +52 -0
  255. package/skills/vds-skill/runtime/docs/agents/reference/ecosystem-daily-report.md +229 -0
  256. package/skills/vds-skill/runtime/docs/agents/reference/elastic-orchestrator.md +57 -0
  257. package/skills/vds-skill/runtime/docs/agents/reference/env-git-helper.md +216 -0
  258. package/skills/vds-skill/runtime/docs/agents/reference/evolution-orchestrator.md +113 -0
  259. package/skills/vds-skill/runtime/docs/agents/reference/excel-orchestrator.md +51 -0
  260. package/skills/vds-skill/runtime/docs/agents/reference/git-orchestrator.md +62 -0
  261. package/skills/vds-skill/runtime/docs/agents/reference/google-sheets-orchestrator.md +51 -0
  262. package/skills/vds-skill/runtime/docs/agents/reference/grafana-orchestrator.md +52 -0
  263. package/skills/vds-skill/runtime/docs/agents/reference/hexagonal-orchestrator.md +64 -0
  264. package/skills/vds-skill/runtime/docs/agents/reference/index.md +36 -0
  265. package/skills/vds-skill/runtime/docs/agents/reference/infrastructure-v2.15.md +67 -0
  266. package/skills/vds-skill/runtime/docs/agents/reference/intellij-orchestrator.md +50 -0
  267. package/skills/vds-skill/runtime/docs/agents/reference/jira-orchestrator.md +60 -0
  268. package/skills/vds-skill/runtime/docs/agents/reference/links-orchestrator.md +57 -0
  269. package/skills/vds-skill/runtime/docs/agents/reference/lint-cli.md +99 -0
  270. package/skills/vds-skill/runtime/docs/agents/reference/lsp-orchestrator.md +51 -0
  271. package/skills/vds-skill/runtime/docs/agents/reference/markdown-orchestrator.md +53 -0
  272. package/skills/vds-skill/runtime/docs/agents/reference/mcp-orchestrator.md +88 -0
  273. package/skills/vds-skill/runtime/docs/agents/reference/memory-orchestrator.md +53 -0
  274. package/skills/vds-skill/runtime/docs/agents/reference/metabase-orchestrator.md +51 -0
  275. package/skills/vds-skill/runtime/docs/agents/reference/migration-playbook.md +71 -0
  276. package/skills/vds-skill/runtime/docs/agents/reference/multi-agent-orchestrator.md +52 -0
  277. package/skills/vds-skill/runtime/docs/agents/reference/openapi-orchestrator.md +57 -0
  278. package/skills/vds-skill/runtime/docs/agents/reference/orchestrator-architecture.md +194 -0
  279. package/skills/vds-skill/runtime/docs/agents/reference/orchestrator-comparison-matrix.md +79 -0
  280. package/skills/vds-skill/runtime/docs/agents/reference/orchestrator-index.md +73 -0
  281. package/skills/vds-skill/runtime/docs/agents/reference/pdf-orchestrator.md +57 -0
  282. package/skills/vds-skill/runtime/docs/agents/reference/portable-paths-and-config.md +0 -0
  283. package/skills/vds-skill/runtime/docs/agents/reference/portable-paths-validation-matrix.md +129 -0
  284. package/skills/vds-skill/runtime/docs/agents/reference/progress-orchestrator.md +51 -0
  285. package/skills/vds-skill/runtime/docs/agents/reference/progress-report-cli.md +215 -0
  286. package/skills/vds-skill/runtime/docs/agents/reference/public-interface-orchestrator.md +73 -0
  287. package/skills/vds-skill/runtime/docs/agents/reference/research-orchestrator.md +53 -0
  288. package/skills/vds-skill/runtime/docs/agents/reference/schema-orchestrator.md +57 -0
  289. package/skills/vds-skill/runtime/docs/agents/reference/search-tools.md +34 -0
  290. package/skills/vds-skill/runtime/docs/agents/reference/skills-commands.md +256 -0
  291. package/skills/vds-skill/runtime/docs/agents/reference/skills-reference.md +32 -0
  292. package/skills/vds-skill/runtime/docs/agents/reference/sonarqube-orchestrator.md +62 -0
  293. package/skills/vds-skill/runtime/docs/agents/reference/spec-orchestrator.md +56 -0
  294. package/skills/vds-skill/runtime/docs/agents/reference/structure-orchestrator.md +69 -0
  295. package/skills/vds-skill/runtime/docs/agents/reference/system-requirements.md +76 -0
  296. package/skills/vds-skill/runtime/docs/agents/reference/tasks-orchestrator.md +53 -0
  297. package/skills/vds-skill/runtime/docs/agents/reference/validation-and-sync-notes.md +54 -0
  298. package/skills/vds-skill/runtime/docs/agents/reference/vds-ai-memory-api.md +51 -0
  299. package/skills/vds-skill/runtime/docs/agents/reference/vds-cli-reference.md +34 -0
  300. package/skills/vds-skill/runtime/docs/agents/reference/who-capability-inventory.md +96 -0
  301. package/skills/vds-skill/runtime/docs/agents/reference/who-capability-routing-matrix.md +14 -0
  302. package/skills/vds-skill/runtime/docs/agents/tutorials/feature-progression-guide.md +112 -0
  303. package/skills/vds-skill/runtime/docs/agents/tutorials/index.md +36 -0
  304. package/skills/vds-skill/runtime/docs/agents/tutorials/quick-start.md +50 -0
  305. package/skills/vds-skill/runtime/docs/agents/tutorials/who-skills-and-scripts-onboarding.md +47 -0
  306. package/skills/vds-skill/runtime/docs/agents/tutorials/zero-to-productive-developer.md +339 -0
  307. package/skills/vds-skill/runtime/docs/confluence/IMPLEMENTATION-SUMMARY.md +78 -0
  308. package/skills/vds-skill/runtime/docs/confluence/SYNC-GUIDE.md +47 -0
  309. package/skills/vds-skill/runtime/docs/deployment/offline-docker-image-load.md +59 -0
  310. package/skills/vds-skill/runtime/docs/evolution-auto-run-rollout.md +325 -0
  311. package/skills/vds-skill/runtime/docs/evolution-loop-deep-integration.md +496 -0
  312. package/skills/vds-skill/runtime/docs/evolution-loop-integration-guide.md +359 -0
  313. package/skills/vds-skill/runtime/docs/openspace-schema-snapshot.md +73 -0
  314. package/skills/vds-skill/runtime/docs/operations/sla-mttr-policy.md +44 -0
  315. package/skills/vds-skill/runtime/docs/p0-closure-evidence/SUMMARY.md +58 -0
  316. package/skills/vds-skill/runtime/docs/p4-closure-evidence/.gitkeep +0 -0
  317. package/skills/vds-skill/runtime/docs/p4-closure-evidence/smoke-20260427T024137Z-b95b586b.json +15 -0
  318. package/skills/vds-skill/runtime/docs/p8-preflight-evidence/alembic-and-runtime-advisory-locks.md +45 -0
  319. package/skills/vds-skill/runtime/docs/p8-preflight-evidence/dbos-listen-notify.md +54 -0
  320. package/skills/vds-skill/runtime/docs/p8-preflight-evidence/pgbouncer-search-path-empirical.md +110 -0
  321. package/skills/vds-skill/runtime/docs/p8-preflight-evidence/pgvector-set-local-audit.md +51 -0
  322. package/skills/vds-skill/runtime/docs/p8-preflight-evidence/topology-decision-session-mode.md +57 -0
  323. package/skills/vds-skill/runtime/docs/phases/CHANGELOG.md +103 -0
  324. package/skills/vds-skill/runtime/docs/phases/PHASE_125_COMPLETION_AND_MERGE.md +212 -0
  325. package/skills/vds-skill/runtime/docs/phases/phase125/IMPLEMENTATION_REPORT.md +227 -0
  326. package/skills/vds-skill/runtime/docs/phases/phase125/TSK-125.10-11-implementation-summary.md +196 -0
  327. package/skills/vds-skill/runtime/docs/phases/phase125/profile-patch-ollama-local-anthropic.md +122 -0
  328. package/skills/vds-skill/runtime/docs/phases/phase125_completion_summary.md +369 -0
  329. package/skills/vds-skill/runtime/docs/phases/phase125_llm_analysis_skill.md +164 -0
  330. package/skills/vds-skill/runtime/docs/phases/phase125_merge_complete.md +147 -0
  331. package/skills/vds-skill/runtime/docs/phases/phase125_skill_runtime_closure_20260321.md +91 -0
  332. package/skills/vds-skill/runtime/docs/phases/phase2-portable-paths/closure-handoff-summary-2026-03-23.md +290 -0
  333. package/skills/vds-skill/runtime/docs/phases/phase2-portable-paths/remaining-risk-register-2026-03-25.md +143 -0
  334. package/skills/vds-skill/runtime/docs/phases/phase2-portable-paths/verification-evidence-2026-03-23.md +135 -0
  335. package/skills/vds-skill/runtime/docs/v0-sunset-known-issues.md +88 -0
  336. package/skills/vds-skill/runtime/docs/vi/TRANSLATION-BACKLOG.md +72 -0
  337. package/skills/vds-skill/runtime/docs/vi/agents/README.md +41 -0
  338. package/skills/vds-skill/runtime/docs/vi/agents/explanation/features-overview.md +29 -0
  339. package/skills/vds-skill/runtime/docs/vi/agents/explanation/index.md +14 -0
  340. package/skills/vds-skill/runtime/docs/vi/agents/explanation/runtime-verification-and-gap-reporting.md +129 -0
  341. package/skills/vds-skill/runtime/docs/vi/agents/explanation/whats-new.md +37 -0
  342. package/skills/vds-skill/runtime/docs/vi/agents/explanation/who-ecosystem-introduction.md +21 -0
  343. package/skills/vds-skill/runtime/docs/vi/agents/explanation/who-ecosystem-model.md +36 -0
  344. package/skills/vds-skill/runtime/docs/vi/agents/how-to/02-using-vds-ai-memory.md +100 -0
  345. package/skills/vds-skill/runtime/docs/vi/agents/how-to/03-memory-cross-agent.md +243 -0
  346. package/skills/vds-skill/runtime/docs/vi/agents/how-to/04-using-progress-reports.md +242 -0
  347. package/skills/vds-skill/runtime/docs/vi/agents/how-to/08-semantic-search.md +16 -0
  348. package/skills/vds-skill/runtime/docs/vi/agents/how-to/choose-the-right-command-or-skill.md +36 -0
  349. package/skills/vds-skill/runtime/docs/vi/agents/how-to/decision-tree.md +77 -0
  350. package/skills/vds-skill/runtime/docs/vi/agents/how-to/first-audit-run.md +85 -0
  351. package/skills/vds-skill/runtime/docs/vi/agents/how-to/index.md +21 -0
  352. package/skills/vds-skill/runtime/docs/vi/agents/how-to/install-and-bootstrap-who-scripts-and-skills.md +156 -0
  353. package/skills/vds-skill/runtime/docs/vi/agents/how-to/orchestrator-workflows/analytics-pipeline-workflow.md +174 -0
  354. package/skills/vds-skill/runtime/docs/vi/agents/how-to/orchestrator-workflows/code-quality-gate-workflow.md +147 -0
  355. package/skills/vds-skill/runtime/docs/vi/agents/how-to/orchestrator-workflows/confluence-bitbucket-sync-workflow.md +139 -0
  356. package/skills/vds-skill/runtime/docs/vi/agents/how-to/orchestrator-workflows/document-delivery-workflow.md +151 -0
  357. package/skills/vds-skill/runtime/docs/vi/agents/how-to/orchestrator-workflows/memory-progress-workflow.md +149 -0
  358. package/skills/vds-skill/runtime/docs/vi/agents/how-to/orchestrator-workflows/research-spec-audit-workflow.md +144 -0
  359. package/skills/vds-skill/runtime/docs/vi/agents/how-to/phase131-all-project-preparation.md +213 -0
  360. package/skills/vds-skill/runtime/docs/vi/agents/how-to/phase131-bounded-parallel-analysis.md +125 -0
  361. package/skills/vds-skill/runtime/docs/vi/agents/how-to/phase131-confluence-upload-recovery.md +206 -0
  362. package/skills/vds-skill/runtime/docs/vi/agents/how-to/phase132-department-preparation.md +146 -0
  363. package/skills/vds-skill/runtime/docs/vi/agents/how-to/tips-and-tricks.md +34 -0
  364. package/skills/vds-skill/runtime/docs/vi/agents/how-to/troubleshooting-guide.md +36 -0
  365. package/skills/vds-skill/runtime/docs/vi/agents/reference/agent-operational-contract.md +98 -0
  366. package/skills/vds-skill/runtime/docs/vi/agents/reference/audit-triage-playbook.md +258 -0
  367. package/skills/vds-skill/runtime/docs/vi/agents/reference/bitbucket-orchestrator.md +30 -0
  368. package/skills/vds-skill/runtime/docs/vi/agents/reference/brd-orchestrator.md +29 -0
  369. package/skills/vds-skill/runtime/docs/vi/agents/reference/capability-coverage-review.md +46 -0
  370. package/skills/vds-skill/runtime/docs/vi/agents/reference/circular-dependency-orchestrator.md +29 -0
  371. package/skills/vds-skill/runtime/docs/vi/agents/reference/cli-commands.md +409 -0
  372. package/skills/vds-skill/runtime/docs/vi/agents/reference/cli-development-standards.md +19 -0
  373. package/skills/vds-skill/runtime/docs/vi/agents/reference/cli-help-matrix.md +71 -0
  374. package/skills/vds-skill/runtime/docs/vi/agents/reference/common-errors.md +133 -0
  375. package/skills/vds-skill/runtime/docs/vi/agents/reference/configuration-reference.md +25 -0
  376. package/skills/vds-skill/runtime/docs/vi/agents/reference/confluence-orchestrator.md +30 -0
  377. package/skills/vds-skill/runtime/docs/vi/agents/reference/db-query-orchestrator.md +34 -0
  378. package/skills/vds-skill/runtime/docs/vi/agents/reference/diagrams-orchestrator.md +31 -0
  379. package/skills/vds-skill/runtime/docs/vi/agents/reference/elastic-orchestrator.md +30 -0
  380. package/skills/vds-skill/runtime/docs/vi/agents/reference/evolution-orchestrator.md +31 -0
  381. package/skills/vds-skill/runtime/docs/vi/agents/reference/excel-orchestrator.md +60 -0
  382. package/skills/vds-skill/runtime/docs/vi/agents/reference/git-orchestrator.md +31 -0
  383. package/skills/vds-skill/runtime/docs/vi/agents/reference/google-sheets-orchestrator.md +60 -0
  384. package/skills/vds-skill/runtime/docs/vi/agents/reference/grafana-orchestrator.md +30 -0
  385. package/skills/vds-skill/runtime/docs/vi/agents/reference/hexagonal-orchestrator.md +73 -0
  386. package/skills/vds-skill/runtime/docs/vi/agents/reference/index.md +25 -0
  387. package/skills/vds-skill/runtime/docs/vi/agents/reference/intellij-orchestrator.md +59 -0
  388. package/skills/vds-skill/runtime/docs/vi/agents/reference/jira-orchestrator.md +32 -0
  389. package/skills/vds-skill/runtime/docs/vi/agents/reference/links-orchestrator.md +66 -0
  390. package/skills/vds-skill/runtime/docs/vi/agents/reference/lsp-orchestrator.md +60 -0
  391. package/skills/vds-skill/runtime/docs/vi/agents/reference/markdown-orchestrator.md +62 -0
  392. package/skills/vds-skill/runtime/docs/vi/agents/reference/mcp-orchestrator.md +34 -0
  393. package/skills/vds-skill/runtime/docs/vi/agents/reference/memory-orchestrator.md +45 -0
  394. package/skills/vds-skill/runtime/docs/vi/agents/reference/metabase-orchestrator.md +30 -0
  395. package/skills/vds-skill/runtime/docs/vi/agents/reference/multi-agent-orchestrator.md +61 -0
  396. package/skills/vds-skill/runtime/docs/vi/agents/reference/openapi-orchestrator.md +66 -0
  397. package/skills/vds-skill/runtime/docs/vi/agents/reference/orchestrator-architecture.md +24 -0
  398. package/skills/vds-skill/runtime/docs/vi/agents/reference/orchestrator-index.md +73 -0
  399. package/skills/vds-skill/runtime/docs/vi/agents/reference/pdf-orchestrator.md +30 -0
  400. package/skills/vds-skill/runtime/docs/vi/agents/reference/portable-paths-and-config.md +123 -0
  401. package/skills/vds-skill/runtime/docs/vi/agents/reference/portable-paths-validation-matrix.md +131 -0
  402. package/skills/vds-skill/runtime/docs/vi/agents/reference/progress-orchestrator.md +43 -0
  403. package/skills/vds-skill/runtime/docs/vi/agents/reference/progress-report-cli.md +217 -0
  404. package/skills/vds-skill/runtime/docs/vi/agents/reference/public-interface-orchestrator.md +82 -0
  405. package/skills/vds-skill/runtime/docs/vi/agents/reference/research-orchestrator.md +45 -0
  406. package/skills/vds-skill/runtime/docs/vi/agents/reference/schema-orchestrator.md +66 -0
  407. package/skills/vds-skill/runtime/docs/vi/agents/reference/search-tools.md +19 -0
  408. package/skills/vds-skill/runtime/docs/vi/agents/reference/skills-reference.md +27 -0
  409. package/skills/vds-skill/runtime/docs/vi/agents/reference/sonarqube-orchestrator.md +71 -0
  410. package/skills/vds-skill/runtime/docs/vi/agents/reference/spec-orchestrator.md +56 -0
  411. package/skills/vds-skill/runtime/docs/vi/agents/reference/structure-orchestrator.md +78 -0
  412. package/skills/vds-skill/runtime/docs/vi/agents/reference/system-requirements.md +30 -0
  413. package/skills/vds-skill/runtime/docs/vi/agents/reference/tasks-orchestrator.md +45 -0
  414. package/skills/vds-skill/runtime/docs/vi/agents/reference/validation-and-sync-notes.md +26 -0
  415. package/skills/vds-skill/runtime/docs/vi/agents/reference/vds-ai-memory-api.md +53 -0
  416. package/skills/vds-skill/runtime/docs/vi/agents/reference/vds-cli-reference.md +34 -0
  417. package/skills/vds-skill/runtime/docs/vi/agents/reference/who-capability-inventory.md +98 -0
  418. package/skills/vds-skill/runtime/docs/vi/agents/reference/who-capability-routing-matrix.md +16 -0
  419. package/skills/vds-skill/runtime/docs/vi/agents/tutorials/feature-progression-guide.md +124 -0
  420. package/skills/vds-skill/runtime/docs/vi/agents/tutorials/index.md +13 -0
  421. package/skills/vds-skill/runtime/docs/vi/agents/tutorials/quick-start.md +30 -0
  422. package/skills/vds-skill/runtime/docs/vi/agents/tutorials/who-skills-and-scripts-onboarding.md +42 -0
  423. package/skills/vds-skill/runtime/docs/vi/agents/tutorials/zero-to-productive-developer.md +137 -0
  424. package/skills/vds-skill/runtime/elastic_orchestrator/README.md +450 -0
  425. package/skills/vds-skill/runtime/elastic_orchestrator/pyproject.toml +97 -0
  426. package/skills/vds-skill/runtime/elastic_orchestrator/src/vds_elastic_orchestrator/__init__.py +81 -0
  427. package/skills/vds-skill/runtime/elastic_orchestrator/src/vds_elastic_orchestrator/cli.py +652 -0
  428. package/skills/vds-skill/runtime/elastic_orchestrator/src/vds_elastic_orchestrator/client.py +743 -0
  429. package/skills/vds-skill/runtime/elastic_orchestrator/src/vds_elastic_orchestrator/config.py +208 -0
  430. package/skills/vds-skill/runtime/elastic_orchestrator/src/vds_elastic_orchestrator/errors.py +34 -0
  431. package/skills/vds-skill/runtime/elastic_orchestrator/src/vds_elastic_orchestrator/py.typed +0 -0
  432. package/skills/vds-skill/runtime/elastic_orchestrator/tests/__init__.py +0 -0
  433. package/skills/vds-skill/runtime/elastic_orchestrator/tests/conftest.py +227 -0
  434. package/skills/vds-skill/runtime/elastic_orchestrator/tests/test_client.py +990 -0
  435. package/skills/vds-skill/runtime/elastic_orchestrator/tests/test_config.py +268 -0
  436. package/skills/vds-skill/runtime/elastic_orchestrator/tests/test_e2e_verification.py +272 -0
  437. package/skills/vds-skill/runtime/elastic_orchestrator/tests/test_errors.py +78 -0
  438. package/skills/vds-skill/runtime/excel_orchestrator/README.md +288 -0
  439. package/skills/vds-skill/runtime/excel_orchestrator/RESEARCH_BASED_UPDATES_REPORT.md +261 -0
  440. package/skills/vds-skill/runtime/excel_orchestrator/add_essential_missing_effort.py +255 -0
  441. package/skills/vds-skill/runtime/excel_orchestrator/adjust_effort_complexity.py +184 -0
  442. package/skills/vds-skill/runtime/excel_orchestrator/brd_analysis_and_task_breakdown.py +632 -0
  443. package/skills/vds-skill/runtime/excel_orchestrator/brd_analysis_comprehensive.py +1029 -0
  444. package/skills/vds-skill/runtime/excel_orchestrator/check_overlaps_and_brd_coverage.py +570 -0
  445. package/skills/vds-skill/runtime/excel_orchestrator/clean_remarks_column.py +127 -0
  446. package/skills/vds-skill/runtime/excel_orchestrator/comprehensive_brd_check.py +322 -0
  447. package/skills/vds-skill/runtime/excel_orchestrator/create_buffered_summary.py +119 -0
  448. package/skills/vds-skill/runtime/excel_orchestrator/create_service_totals_sheet.py +118 -0
  449. package/skills/vds-skill/runtime/excel_orchestrator/examples/basic_operations.py +85 -0
  450. package/skills/vds-skill/runtime/excel_orchestrator/expand_all_tasks.py +341 -0
  451. package/skills/vds-skill/runtime/excel_orchestrator/expand_tasks.py +304 -0
  452. package/skills/vds-skill/runtime/excel_orchestrator/fill_brd_references.py +347 -0
  453. package/skills/vds-skill/runtime/excel_orchestrator/fill_remarks_and_colors.py +132 -0
  454. package/skills/vds-skill/runtime/excel_orchestrator/finalize_brd_and_cleanup.py +295 -0
  455. package/skills/vds-skill/runtime/excel_orchestrator/finalize_brd_coverage.py +327 -0
  456. package/skills/vds-skill/runtime/excel_orchestrator/fix_all_formulas.py +99 -0
  457. package/skills/vds-skill/runtime/excel_orchestrator/fix_detail_presentation.py +113 -0
  458. package/skills/vds-skill/runtime/excel_orchestrator/fix_presentation_and_effort.py +116 -0
  459. package/skills/vds-skill/runtime/excel_orchestrator/fix_presentation_consistency.py +231 -0
  460. package/skills/vds-skill/runtime/excel_orchestrator/fix_remarks_matching.py +179 -0
  461. package/skills/vds-skill/runtime/excel_orchestrator/group_tasks_by_service_id.py +210 -0
  462. package/skills/vds-skill/runtime/excel_orchestrator/increase_brd_coverage.py +497 -0
  463. package/skills/vds-skill/runtime/excel_orchestrator/increase_effort_complexity.py +155 -0
  464. package/skills/vds-skill/runtime/excel_orchestrator/organize_and_deduplicate.py +273 -0
  465. package/skills/vds-skill/runtime/excel_orchestrator/pyproject.toml +64 -0
  466. package/skills/vds-skill/runtime/excel_orchestrator/rebuild_all_formulas.py +146 -0
  467. package/skills/vds-skill/runtime/excel_orchestrator/remove_base_multiplier_and_check_duplicates.py +310 -0
  468. package/skills/vds-skill/runtime/excel_orchestrator/remove_duplicate_brd_tasks.py +137 -0
  469. package/skills/vds-skill/runtime/excel_orchestrator/research_based_updates.py +457 -0
  470. package/skills/vds-skill/runtime/excel_orchestrator/restore_e_values.py +172 -0
  471. package/skills/vds-skill/runtime/excel_orchestrator/src/vds_excel_orchestrator/__init__.py +5 -0
  472. package/skills/vds-skill/runtime/excel_orchestrator/src/vds_excel_orchestrator/cli.py +746 -0
  473. package/skills/vds-skill/runtime/excel_orchestrator/src/vds_excel_orchestrator/config.py +74 -0
  474. package/skills/vds-skill/runtime/excel_orchestrator/src/vds_excel_orchestrator/converters.py +226 -0
  475. package/skills/vds-skill/runtime/excel_orchestrator/src/vds_excel_orchestrator/errors.py +88 -0
  476. package/skills/vds-skill/runtime/excel_orchestrator/src/vds_excel_orchestrator/excel_client.py +443 -0
  477. package/skills/vds-skill/runtime/excel_orchestrator/src/vds_excel_orchestrator/formatters.py +211 -0
  478. package/skills/vds-skill/runtime/excel_orchestrator/src/vds_excel_orchestrator/logging.py +57 -0
  479. package/skills/vds-skill/runtime/excel_orchestrator/src/vds_excel_orchestrator/source_contract.py +29 -0
  480. package/skills/vds-skill/runtime/excel_orchestrator/src/vds_excel_orchestrator/target_state_status.py +837 -0
  481. package/skills/vds-skill/runtime/excel_orchestrator/src/vds_excel_orchestrator/ulnc_alignment.py +1291 -0
  482. package/skills/vds-skill/runtime/excel_orchestrator/src/vds_excel_orchestrator/validators.py +164 -0
  483. package/skills/vds-skill/runtime/excel_orchestrator/sync_detail_and_total_sheets.py +211 -0
  484. package/skills/vds-skill/runtime/excel_orchestrator/tests/__init__.py +1 -0
  485. package/skills/vds-skill/runtime/excel_orchestrator/tests/conftest.py +36 -0
  486. package/skills/vds-skill/runtime/excel_orchestrator/tests/test_cli.py +383 -0
  487. package/skills/vds-skill/runtime/excel_orchestrator/tests/test_excel_client.py +129 -0
  488. package/skills/vds-skill/runtime/excel_orchestrator/tests/test_ulnc_alignment.py +373 -0
  489. package/skills/vds-skill/runtime/excel_orchestrator/tests/test_validators.py +64 -0
  490. package/skills/vds-skill/runtime/excel_orchestrator/update_api_database_effort.py +261 -0
  491. package/skills/vds-skill/runtime/excel_orchestrator/update_buffers_inline.py +115 -0
  492. package/skills/vds-skill/runtime/excel_orchestrator/update_complex_services_and_add_new.py +336 -0
  493. package/skills/vds-skill/runtime/excel_orchestrator/update_responsibility_and_fix_rows.py +208 -0
  494. package/skills/vds-skill/runtime/excel_orchestrator/update_task_breakdown_vietnamese.py +309 -0
  495. package/skills/vds-skill/runtime/excel_orchestrator/update_vietnamese_and_responsibility.py +415 -0
  496. package/skills/vds-skill/runtime/excel_orchestrator/verify_brd_coverage_comprehensive.py +401 -0
  497. package/skills/vds-skill/runtime/git_orchestrator/ENHANCEMENT_SUMMARY.md +119 -0
  498. package/skills/vds-skill/runtime/git_orchestrator/README.md +286 -0
  499. package/skills/vds-skill/runtime/git_orchestrator/VERIFICATION_REPORT.md +152 -0
  500. package/skills/vds-skill/runtime/git_orchestrator/pyproject.toml +37 -0
  501. package/skills/vds-skill/runtime/git_orchestrator/src/vds_git_orchestrator/__init__.py +30 -0
  502. package/skills/vds-skill/runtime/git_orchestrator/src/vds_git_orchestrator/__main__.py +4 -0
  503. package/skills/vds-skill/runtime/git_orchestrator/src/vds_git_orchestrator/branch_probe.py +271 -0
  504. package/skills/vds-skill/runtime/git_orchestrator/src/vds_git_orchestrator/cli.py +892 -0
  505. package/skills/vds-skill/runtime/git_orchestrator/src/vds_git_orchestrator/logging_config.py +63 -0
  506. package/skills/vds-skill/runtime/git_orchestrator/src/vds_git_orchestrator/manifest.py +249 -0
  507. package/skills/vds-skill/runtime/git_orchestrator/src/vds_git_orchestrator/orchestrator.py +1647 -0
  508. package/skills/vds-skill/runtime/git_orchestrator/src/vds_git_orchestrator/protocols.py +35 -0
  509. package/skills/vds-skill/runtime/git_orchestrator/src/vds_git_orchestrator/reporting.py +55 -0
  510. package/skills/vds-skill/runtime/git_orchestrator/tests/__init__.py +0 -0
  511. package/skills/vds-skill/runtime/git_orchestrator/tests/test_cli_settings.py +19 -0
  512. package/skills/vds-skill/runtime/git_orchestrator/tests/test_integration.py +79 -0
  513. package/skills/vds-skill/runtime/git_orchestrator/tests/test_manifest.py +79 -0
  514. package/skills/vds-skill/runtime/git_orchestrator/tests/test_orchestrator.py +207 -0
  515. package/skills/vds-skill/runtime/git_orchestrator/tests/test_public_api.py +235 -0
  516. package/skills/vds-skill/runtime/git_orchestrator/tests/test_resilience.py +343 -0
  517. package/skills/vds-skill/runtime/git_orchestrator/tests/unit/__init__.py +0 -0
  518. package/skills/vds-skill/runtime/git_orchestrator/tests/unit/test_branch_probe.py +327 -0
  519. package/skills/vds-skill/runtime/git_orchestrator/tests/unit/test_protocols.py +132 -0
  520. package/skills/vds-skill/runtime/google_sheets_orchestrator/README.md +241 -0
  521. package/skills/vds-skill/runtime/google_sheets_orchestrator/pyproject.toml +45 -0
  522. package/skills/vds-skill/runtime/google_sheets_orchestrator/src/vds_google_sheets_orchestrator/__init__.py +69 -0
  523. package/skills/vds-skill/runtime/google_sheets_orchestrator/src/vds_google_sheets_orchestrator/cli.py +568 -0
  524. package/skills/vds-skill/runtime/google_sheets_orchestrator/src/vds_google_sheets_orchestrator/client.py +186 -0
  525. package/skills/vds-skill/runtime/google_sheets_orchestrator/src/vds_google_sheets_orchestrator/config.py +46 -0
  526. package/skills/vds-skill/runtime/google_sheets_orchestrator/src/vds_google_sheets_orchestrator/errors.py +41 -0
  527. package/skills/vds-skill/runtime/google_sheets_orchestrator/tests/__init__.py +1 -0
  528. package/skills/vds-skill/runtime/google_sheets_orchestrator/tests/conftest.py +1 -0
  529. package/skills/vds-skill/runtime/google_sheets_orchestrator/tests/unit/__init__.py +1 -0
  530. package/skills/vds-skill/runtime/google_sheets_orchestrator/tests/unit/test_cli.py +212 -0
  531. package/skills/vds-skill/runtime/google_sheets_orchestrator/tests/unit/test_client.py +24 -0
  532. package/skills/vds-skill/runtime/google_sheets_orchestrator/tests/unit/test_config.py +16 -0
  533. package/skills/vds-skill/runtime/grafana_orchestrator/README.md +572 -0
  534. package/skills/vds-skill/runtime/grafana_orchestrator/pyproject.toml +102 -0
  535. package/skills/vds-skill/runtime/grafana_orchestrator/src/vds_grafana_orchestrator/__init__.py +78 -0
  536. package/skills/vds-skill/runtime/grafana_orchestrator/src/vds_grafana_orchestrator/cli.py +455 -0
  537. package/skills/vds-skill/runtime/grafana_orchestrator/src/vds_grafana_orchestrator/client.py +700 -0
  538. package/skills/vds-skill/runtime/grafana_orchestrator/src/vds_grafana_orchestrator/config.py +243 -0
  539. package/skills/vds-skill/runtime/grafana_orchestrator/src/vds_grafana_orchestrator/errors.py +34 -0
  540. package/skills/vds-skill/runtime/grafana_orchestrator/src/vds_grafana_orchestrator/py.typed +1 -0
  541. package/skills/vds-skill/runtime/grafana_orchestrator/tests/__init__.py +1 -0
  542. package/skills/vds-skill/runtime/grafana_orchestrator/tests/conftest.py +308 -0
  543. package/skills/vds-skill/runtime/grafana_orchestrator/tests/test_client.py +458 -0
  544. package/skills/vds-skill/runtime/grafana_orchestrator/tests/test_config.py +203 -0
  545. package/skills/vds-skill/runtime/grafana_orchestrator/tests/test_errors.py +78 -0
  546. package/skills/vds-skill/runtime/jira_orchestrator/README.md +864 -0
  547. package/skills/vds-skill/runtime/jira_orchestrator/pyproject.toml +43 -0
  548. package/skills/vds-skill/runtime/jira_orchestrator/src/vds_jira_orchestrator/__init__.py +65 -0
  549. package/skills/vds-skill/runtime/jira_orchestrator/src/vds_jira_orchestrator/adapter.py +1685 -0
  550. package/skills/vds-skill/runtime/jira_orchestrator/src/vds_jira_orchestrator/cli.py +2806 -0
  551. package/skills/vds-skill/runtime/jira_orchestrator/src/vds_jira_orchestrator/config.py +168 -0
  552. package/skills/vds-skill/runtime/jira_orchestrator/src/vds_jira_orchestrator/errors.py +34 -0
  553. package/skills/vds-skill/runtime/jira_orchestrator/src/vds_jira_orchestrator/reporting.py +66 -0
  554. package/skills/vds-skill/runtime/jira_orchestrator/tests/__init__.py +1 -0
  555. package/skills/vds-skill/runtime/jira_orchestrator/tests/conftest.py +86 -0
  556. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_agile_list_payloads.py +54 -0
  557. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_bulk_operations.py +91 -0
  558. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_components.py +56 -0
  559. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_createmeta.py +45 -0
  560. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_dashboard.py +119 -0
  561. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_issue_properties.py +53 -0
  562. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_permissions_compat.py +41 -0
  563. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_reindex.py +42 -0
  564. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_remote_links.py +75 -0
  565. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_transitions.py +90 -0
  566. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_user_management.py +116 -0
  567. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_version_management.py +181 -0
  568. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_adapter_watchers.py +43 -0
  569. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_advanced_search.py +179 -0
  570. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_agile.py +304 -0
  571. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_application_properties.py +243 -0
  572. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_backlog.py +91 -0
  573. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_bulk_operations.py +403 -0
  574. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_cli.py +108 -0
  575. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_components.py +119 -0
  576. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_config.py +166 -0
  577. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_dashboard.py +122 -0
  578. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_discover_fields.py +207 -0
  579. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_errors.py +72 -0
  580. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_filter_management.py +411 -0
  581. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_issue_archiving.py +179 -0
  582. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_issue_links.py +257 -0
  583. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_issue_properties.py +189 -0
  584. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_link_types.py +407 -0
  585. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_parse_set.py +37 -0
  586. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_permissions.py +343 -0
  587. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_reindex.py +81 -0
  588. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_remote_links.py +269 -0
  589. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_security_schemes.py +202 -0
  590. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_transitions_changelog.py +109 -0
  591. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_user_management.py +246 -0
  592. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_version_management.py +503 -0
  593. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_watchers.py +116 -0
  594. package/skills/vds-skill/runtime/jira_orchestrator/tests/test_worklog.py +243 -0
  595. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/README.md +864 -0
  596. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/pyproject.toml +43 -0
  597. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/src/vds_jira_viettelmoney_orchestrator/__init__.py +65 -0
  598. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/src/vds_jira_viettelmoney_orchestrator/adapter.py +1689 -0
  599. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/src/vds_jira_viettelmoney_orchestrator/cli.py +2799 -0
  600. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/src/vds_jira_viettelmoney_orchestrator/config.py +135 -0
  601. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/src/vds_jira_viettelmoney_orchestrator/errors.py +34 -0
  602. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/src/vds_jira_viettelmoney_orchestrator/reporting.py +65 -0
  603. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/__init__.py +1 -0
  604. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/conftest.py +86 -0
  605. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_agile_list_payloads.py +54 -0
  606. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_bulk_operations.py +101 -0
  607. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_components.py +64 -0
  608. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_createmeta.py +45 -0
  609. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_dashboard.py +135 -0
  610. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_issue_properties.py +63 -0
  611. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_permissions_compat.py +42 -0
  612. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_reindex.py +42 -0
  613. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_remote_links.py +89 -0
  614. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_transitions.py +91 -0
  615. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_user_management.py +130 -0
  616. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_version_management.py +189 -0
  617. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_adapter_watchers.py +49 -0
  618. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_advanced_search.py +213 -0
  619. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_agile.py +334 -0
  620. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_application_properties.py +261 -0
  621. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_backlog.py +91 -0
  622. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_bulk_operations.py +443 -0
  623. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_cli.py +106 -0
  624. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_components.py +133 -0
  625. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_config.py +166 -0
  626. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_dashboard.py +130 -0
  627. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_discover_fields.py +207 -0
  628. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_errors.py +61 -0
  629. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_filter_management.py +478 -0
  630. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_issue_archiving.py +181 -0
  631. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_issue_links.py +257 -0
  632. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_issue_properties.py +203 -0
  633. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_link_types.py +426 -0
  634. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_parse_set.py +37 -0
  635. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_permissions.py +358 -0
  636. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_reindex.py +81 -0
  637. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_remote_links.py +292 -0
  638. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_security_schemes.py +218 -0
  639. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_transitions_changelog.py +121 -0
  640. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_user_management.py +283 -0
  641. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_version_management.py +561 -0
  642. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_watchers.py +128 -0
  643. package/skills/vds-skill/runtime/jira_viettelmoney_orchestrator/tests/test_worklog.py +265 -0
  644. package/skills/vds-skill/runtime/llms.txt +159 -0
  645. package/skills/vds-skill/runtime/markdown_orchestrator/README.md +72 -0
  646. package/skills/vds-skill/runtime/markdown_orchestrator/pyproject.toml +39 -0
  647. package/skills/vds-skill/runtime/markdown_orchestrator/src/vds_markdown_orchestrator/__init__.py +5 -0
  648. package/skills/vds-skill/runtime/markdown_orchestrator/src/vds_markdown_orchestrator/cli.py +102 -0
  649. package/skills/vds-skill/runtime/mcp_server/Dockerfile +63 -0
  650. package/skills/vds-skill/runtime/mcp_server/README.md +140 -0
  651. package/skills/vds-skill/runtime/mcp_server/pyproject.toml +41 -0
  652. package/skills/vds-skill/runtime/mcp_server/src/vds_mcp_server/__init__.py +3 -0
  653. package/skills/vds-skill/runtime/mcp_server/src/vds_mcp_server/config.py +36 -0
  654. package/skills/vds-skill/runtime/mcp_server/src/vds_mcp_server/server.py +111 -0
  655. package/skills/vds-skill/runtime/mcp_server/src/vds_mcp_server/tools/__init__.py +15 -0
  656. package/skills/vds-skill/runtime/mcp_server/src/vds_mcp_server/tools/bitbucket_tools.py +47 -0
  657. package/skills/vds-skill/runtime/mcp_server/src/vds_mcp_server/tools/confluence_tools.py +53 -0
  658. package/skills/vds-skill/runtime/mcp_server/src/vds_mcp_server/tools/git_tools.py +71 -0
  659. package/skills/vds-skill/runtime/mcp_server/src/vds_mcp_server/tools/jira_tools.py +63 -0
  660. package/skills/vds-skill/runtime/mcp_server/src/vds_mcp_server/tools/vidp_tools.py +64 -0
  661. package/skills/vds-skill/runtime/mcp_server/tests/__init__.py +1 -0
  662. package/skills/vds-skill/runtime/mcp_server/tests/conftest.py +31 -0
  663. package/skills/vds-skill/runtime/mcp_server/tests/unit/__init__.py +1 -0
  664. package/skills/vds-skill/runtime/mcp_server/tests/unit/test_bitbucket_tools.py +28 -0
  665. package/skills/vds-skill/runtime/mcp_server/tests/unit/test_confluence_tools.py +28 -0
  666. package/skills/vds-skill/runtime/mcp_server/tests/unit/test_git_tools.py +35 -0
  667. package/skills/vds-skill/runtime/mcp_server/tests/unit/test_jira_tools.py +35 -0
  668. package/skills/vds-skill/runtime/mcp_server/tests/verification/__init__.py +6 -0
  669. package/skills/vds-skill/runtime/mcp_server/tests/verification/conftest.py +51 -0
  670. package/skills/vds-skill/runtime/mcp_server/tests/verification/test_mcp_confluence_tools.py +40 -0
  671. package/skills/vds-skill/runtime/mcp_server/tests/verification/test_mcp_jira_tools.py +39 -0
  672. package/skills/vds-skill/runtime/mcp_server/tests/verification/test_mcp_tool_registration.py +50 -0
  673. package/skills/vds-skill/runtime/pdf_orchestrator/.dockerignore +93 -0
  674. package/skills/vds-skill/runtime/pdf_orchestrator/.env.example +40 -0
  675. package/skills/vds-skill/runtime/pdf_orchestrator/.ruff_rules.py +350 -0
  676. package/skills/vds-skill/runtime/pdf_orchestrator/.yamllint.yml +43 -0
  677. package/skills/vds-skill/runtime/pdf_orchestrator/DEVELOPMENT_PLAN.md +80 -0
  678. package/skills/vds-skill/runtime/pdf_orchestrator/Dockerfile +87 -0
  679. package/skills/vds-skill/runtime/pdf_orchestrator/README.md +608 -0
  680. package/skills/vds-skill/runtime/pdf_orchestrator/cli_verification_test/test.md +6 -0
  681. package/skills/vds-skill/runtime/pdf_orchestrator/cli_verification_test/test.pdf +0 -0
  682. package/skills/vds-skill/runtime/pdf_orchestrator/config/alertmanager.yml +83 -0
  683. package/skills/vds-skill/runtime/pdf_orchestrator/config/prometheus.prod.yml +98 -0
  684. package/skills/vds-skill/runtime/pdf_orchestrator/config/prometheus.yml +40 -0
  685. package/skills/vds-skill/runtime/pdf_orchestrator/config/redis.conf +78 -0
  686. package/skills/vds-skill/runtime/pdf_orchestrator/docs/COMPETITIVE_ANALYSIS_REPORT.md +309 -0
  687. package/skills/vds-skill/runtime/pdf_orchestrator/docs/FEATURES_GUIDE.md +518 -0
  688. package/skills/vds-skill/runtime/pdf_orchestrator/docs/MULTI_USER_DEPLOYMENT_GUIDE.md +615 -0
  689. package/skills/vds-skill/runtime/pdf_orchestrator/docs/USER_GUIDE.md +829 -0
  690. package/skills/vds-skill/runtime/pdf_orchestrator/pyproject.toml +87 -0
  691. package/skills/vds-skill/runtime/pdf_orchestrator/pytest.ini +71 -0
  692. package/skills/vds-skill/runtime/pdf_orchestrator/ruff.toml +6 -0
  693. package/skills/vds-skill/runtime/pdf_orchestrator/scripts/debug_security_report.py +59 -0
  694. package/skills/vds-skill/runtime/pdf_orchestrator/scripts/demo_library_selector.py +109 -0
  695. package/skills/vds-skill/runtime/pdf_orchestrator/scripts/generate_project_stats.py +52 -0
  696. package/skills/vds-skill/runtime/pdf_orchestrator/scripts/generate_styled_pdf.py +95 -0
  697. package/skills/vds-skill/runtime/pdf_orchestrator/scripts/migrate_render_pdfs.py +285 -0
  698. package/skills/vds-skill/runtime/pdf_orchestrator/scripts/setup_team.bat +283 -0
  699. package/skills/vds-skill/runtime/pdf_orchestrator/scripts/setup_team.sh +324 -0
  700. package/skills/vds-skill/runtime/pdf_orchestrator/src/vds_pdf_orchestrator/__init__.py +5 -0
  701. package/skills/vds-skill/runtime/pdf_orchestrator/src/vds_pdf_orchestrator/cli.py +542 -0
  702. package/skills/vds-skill/runtime/pdf_orchestrator/src/vds_pdf_orchestrator/config.py +33 -0
  703. package/skills/vds-skill/runtime/pdf_orchestrator/tests/README.md +650 -0
  704. package/skills/vds-skill/runtime/pdf_orchestrator/tests/__init__.py +0 -0
  705. package/skills/vds-skill/runtime/pdf_orchestrator/tests/conftest.py +520 -0
  706. package/skills/vds-skill/runtime/pdf_orchestrator/tests/requirements.txt +51 -0
  707. package/skills/vds-skill/runtime/pdf_orchestrator/tests/run_tests.py +659 -0
  708. package/skills/vds-skill/runtime/pdf_orchestrator/tests/test_config.py +36 -0
  709. package/skills/vds-skill/runtime/platform_core/pyproject.toml +49 -0
  710. package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/__init__.py +16 -0
  711. package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/alembic/__init__.py +18 -0
  712. package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/alembic/runtime.py +139 -0
  713. package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/config.py +88 -0
  714. package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/credentials.py +40 -0
  715. package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/env.py +24 -0
  716. package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/errors.py +127 -0
  717. package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/http/__init__.py +18 -0
  718. package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/http/auth.py +32 -0
  719. package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/http/errors.py +47 -0
  720. package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/http/pagination.py +65 -0
  721. package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/http/retry.py +62 -0
  722. package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/http/stack.py +61 -0
  723. package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/logging.py +132 -0
  724. package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/protocols.py +77 -0
  725. package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/serialization.py +80 -0
  726. package/skills/vds-skill/runtime/platform_core/src/vds_platform_core/severity.py +175 -0
  727. package/skills/vds-skill/runtime/platform_core/tests/__init__.py +0 -0
  728. package/skills/vds-skill/runtime/platform_core/tests/conftest.py +1 -0
  729. package/skills/vds-skill/runtime/platform_core/tests/test_alembic_runtime.py +300 -0
  730. package/skills/vds-skill/runtime/platform_core/tests/test_auth.py +84 -0
  731. package/skills/vds-skill/runtime/platform_core/tests/test_config.py +83 -0
  732. package/skills/vds-skill/runtime/platform_core/tests/test_credentials.py +73 -0
  733. package/skills/vds-skill/runtime/platform_core/tests/test_env.py +56 -0
  734. package/skills/vds-skill/runtime/platform_core/tests/test_errors.py +201 -0
  735. package/skills/vds-skill/runtime/platform_core/tests/test_errors_http.py +74 -0
  736. package/skills/vds-skill/runtime/platform_core/tests/test_http_settings.py +116 -0
  737. package/skills/vds-skill/runtime/platform_core/tests/test_logging.py +148 -0
  738. package/skills/vds-skill/runtime/platform_core/tests/test_pagination.py +153 -0
  739. package/skills/vds-skill/runtime/platform_core/tests/test_protocols.py +132 -0
  740. package/skills/vds-skill/runtime/platform_core/tests/test_retry.py +151 -0
  741. package/skills/vds-skill/runtime/platform_core/tests/test_serialization.py +92 -0
  742. package/skills/vds-skill/runtime/platform_core/tests/test_severity.py +178 -0
  743. package/skills/vds-skill/runtime/platform_core/tests/test_stack.py +130 -0
  744. package/skills/vds-skill/runtime/platform_core/uv.lock +341 -0
  745. package/skills/vds-skill/runtime/pyproject.toml +145 -0
  746. package/skills/vds-skill/runtime/pyrightconfig.json +82 -0
  747. package/skills/vds-skill/runtime/repo-manifest.yaml +380 -0
  748. package/skills/vds-skill/runtime/repo-manifest.yaml.example +25 -0
  749. package/skills/vds-skill/runtime/ruff.toml +100 -0
  750. package/skills/vds-skill/runtime/scripts/BRD-Validation-API.postman_collection.json +706 -0
  751. package/skills/vds-skill/runtime/scripts/BRD-Validation-README.md +308 -0
  752. package/skills/vds-skill/runtime/scripts/README.md +271 -0
  753. package/skills/vds-skill/runtime/scripts/_validate_alias_phase2.py +137 -0
  754. package/skills/vds-skill/runtime/scripts/audit-cli-patterns.sh +135 -0
  755. package/skills/vds-skill/runtime/scripts/audit-dashboard.sh +525 -0
  756. package/skills/vds-skill/runtime/scripts/backup.sh +123 -0
  757. package/skills/vds-skill/runtime/scripts/bootstrap_uv.sh +69 -0
  758. package/skills/vds-skill/runtime/scripts/brd-validation-environment.json +51 -0
  759. package/skills/vds-skill/runtime/scripts/brd-validation-test-results.json +13023 -0
  760. package/skills/vds-skill/runtime/scripts/brd_coverage_report.json +276 -0
  761. package/skills/vds-skill/runtime/scripts/check-future-annotations.py +22 -0
  762. package/skills/vds-skill/runtime/scripts/check-invalid-symlinks.py +183 -0
  763. package/skills/vds-skill/runtime/scripts/check-no-debug-markers.py +21 -0
  764. package/skills/vds-skill/runtime/scripts/check-no-unittest.py +21 -0
  765. package/skills/vds-skill/runtime/scripts/ci/assert_no_openspace_commits.sh +37 -0
  766. package/skills/vds-skill/runtime/scripts/ci/verify_branch_protection.sh +64 -0
  767. package/skills/vds-skill/runtime/scripts/closure/phase1_check.sh +483 -0
  768. package/skills/vds-skill/runtime/scripts/closure/phase2_check.sh +500 -0
  769. package/skills/vds-skill/runtime/scripts/create_memory_session.py +36 -0
  770. package/skills/vds-skill/runtime/scripts/deploy-bootstrap.sh +201 -0
  771. package/skills/vds-skill/runtime/scripts/deployment/load_docker_images_offline.sh +90 -0
  772. package/skills/vds-skill/runtime/scripts/dev/cli_smoke.sh +259 -0
  773. package/skills/vds-skill/runtime/scripts/final_completion_report.md +139 -0
  774. package/skills/vds-skill/runtime/scripts/folder_structure_report.json +321 -0
  775. package/skills/vds-skill/runtime/scripts/generate_completion_report.py +132 -0
  776. package/skills/vds-skill/runtime/scripts/generate_intellij_modules.py +154 -0
  777. package/skills/vds-skill/runtime/scripts/init-pgbouncer-userlist.sh +154 -0
  778. package/skills/vds-skill/runtime/scripts/link_integrity_report.json +807 -0
  779. package/skills/vds-skill/runtime/scripts/move_audit_artifact_pages.py +252 -0
  780. package/skills/vds-skill/runtime/scripts/move_audit_artifact_pages_rest.py +165 -0
  781. package/skills/vds-skill/runtime/scripts/move_wrong_dept_pages.py +235 -0
  782. package/skills/vds-skill/runtime/scripts/openspace_bootstrap.sh +56 -0
  783. package/skills/vds-skill/runtime/scripts/openspace_common.sh +75 -0
  784. package/skills/vds-skill/runtime/scripts/openspace_doctor.sh +61 -0
  785. package/skills/vds-skill/runtime/scripts/openspace_sync_shadow.sh +65 -0
  786. package/skills/vds-skill/runtime/scripts/phase7-baseline.sh +77 -0
  787. package/skills/vds-skill/runtime/scripts/preflight/env_check.sh +102 -0
  788. package/skills/vds-skill/runtime/scripts/repair_autopay_reports.sh +173 -0
  789. package/skills/vds-skill/runtime/scripts/rollback_drill.sh +659 -0
  790. package/skills/vds-skill/runtime/scripts/run-audit-in-tmux.sh +286 -0
  791. package/skills/vds-skill/runtime/scripts/run-department-audit.sh +495 -0
  792. package/skills/vds-skill/runtime/scripts/run-project-audit.sh +267 -0
  793. package/skills/vds-skill/runtime/scripts/save_intellij_memories.py +112 -0
  794. package/skills/vds-skill/runtime/scripts/save_memories_to_vds_ai.py +81 -0
  795. package/skills/vds-skill/runtime/scripts/save_memories_vds_style.py +133 -0
  796. package/skills/vds-skill/runtime/scripts/search_intellij_memories.py +48 -0
  797. package/skills/vds-skill/runtime/scripts/setup_intellij_workspace.py +71 -0
  798. package/skills/vds-skill/runtime/scripts/smoke-test-deploy.sh +137 -0
  799. package/skills/vds-skill/runtime/scripts/smoke_deploy_lib.py +205 -0
  800. package/skills/vds-skill/runtime/scripts/target-state-automation/README.md +89 -0
  801. package/skills/vds-skill/runtime/scripts/target-state-automation/confluence_sync_coordinator.sh +27 -0
  802. package/skills/vds-skill/runtime/scripts/target-state-automation/coordination.sh +114 -0
  803. package/skills/vds-skill/runtime/scripts/target-state-automation/diagram_coordinator.sh +25 -0
  804. package/skills/vds-skill/runtime/scripts/target-state-automation/docs_root.sh +22 -0
  805. package/skills/vds-skill/runtime/scripts/target-state-automation/generate_diagrams.sh +22 -0
  806. package/skills/vds-skill/runtime/scripts/target-state-automation/markdown_coordinator.sh +25 -0
  807. package/skills/vds-skill/runtime/scripts/target-state-automation/progress_dashboard.sh +17 -0
  808. package/skills/vds-skill/runtime/scripts/target-state-automation/schema_coordinator.sh +25 -0
  809. package/skills/vds-skill/runtime/scripts/target-state-automation/sync_confluence.sh +30 -0
  810. package/skills/vds-skill/runtime/scripts/target-state-automation/update_dependencies.sh +19 -0
  811. package/skills/vds-skill/runtime/scripts/target-state-automation/validate_links.sh +86 -0
  812. package/skills/vds-skill/runtime/scripts/target-state-automation/validate_markdown.sh +52 -0
  813. package/skills/vds-skill/runtime/scripts/target-state-automation/validate_schemas.sh +26 -0
  814. package/skills/vds-skill/runtime/scripts/target-state-automation/validate_structure.sh +98 -0
  815. package/skills/vds-skill/runtime/scripts/tests/__init__.py +1 -0
  816. package/skills/vds-skill/runtime/scripts/tests/test_dockerfile_correctness.py +815 -0
  817. package/skills/vds-skill/runtime/scripts/tests/test_makefile_loadouts.py +560 -0
  818. package/skills/vds-skill/runtime/scripts/tests/test_smoke_deploy.py +313 -0
  819. package/skills/vds-skill/runtime/scripts/tests/test_verify_alembic.py +581 -0
  820. package/skills/vds-skill/runtime/scripts/tests/test_verify_infra_topology.py +254 -0
  821. package/skills/vds-skill/runtime/scripts/update_modules_xml.py +194 -0
  822. package/skills/vds-skill/runtime/scripts/uv-workspace-alignment-verification-2026-03-25.md +128 -0
  823. package/skills/vds-skill/runtime/scripts/uv-workspace-alignment-verification-2026-04-18.md +100 -0
  824. package/skills/vds-skill/runtime/scripts/validate-cli-standardization.sh +188 -0
  825. package/skills/vds-skill/runtime/scripts/validate_brd_coverage.py +197 -0
  826. package/skills/vds-skill/runtime/scripts/validate_folder_structure.py +234 -0
  827. package/skills/vds-skill/runtime/scripts/validate_link_integrity.py +274 -0
  828. package/skills/vds-skill/runtime/scripts/vami017-caller-compat-report.md +62 -0
  829. package/skills/vds-skill/runtime/scripts/vami017-phase-b-scaffold-notes.md +79 -0
  830. package/skills/vds-skill/runtime/scripts/vds_sh_helpers.sh +180 -0
  831. package/skills/vds-skill/runtime/scripts/verification/phase2_portable_paths_ubuntu_docker.sh +26 -0
  832. package/skills/vds-skill/runtime/scripts/verify-infra-topology.py +868 -0
  833. package/skills/vds-skill/runtime/scripts/verify-memory-cli-e2e.sh +598 -0
  834. package/skills/vds-skill/runtime/scripts/verify-worktree-features.sh +306 -0
  835. package/skills/vds-skill/runtime/scripts/worktree-add.sh +128 -0
  836. package/skills/vds-skill/runtime/scripts/worktree-remove.sh +112 -0
  837. package/skills/vds-skill/runtime/scripts/worktree_compose.sh +269 -0
  838. package/skills/vds-skill/runtime/scripts/worktree_uv.sh +77 -0
  839. package/skills/vds-skill/runtime/sonarqube_orchestrator/IMPLEMENTATION_AUDIT.md +376 -0
  840. package/skills/vds-skill/runtime/sonarqube_orchestrator/README.md +507 -0
  841. package/skills/vds-skill/runtime/sonarqube_orchestrator/pyproject.toml +106 -0
  842. package/skills/vds-skill/runtime/sonarqube_orchestrator/scripts/ensure_symlink.sh +38 -0
  843. package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/__init__.py +164 -0
  844. package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/batch.py +212 -0
  845. package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/cli.py +1407 -0
  846. package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/client.py +608 -0
  847. package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/config.py +260 -0
  848. package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/diff.py +220 -0
  849. package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/errors.py +34 -0
  850. package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/external_sca.py +932 -0
  851. package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/portfolio.py +225 -0
  852. package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/pr.py +505 -0
  853. package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/reports.py +342 -0
  854. package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/scanner.py +351 -0
  855. package/skills/vds-skill/runtime/sonarqube_orchestrator/src/vds_sonarqube_orchestrator/webhooks.py +269 -0
  856. package/skills/vds-skill/runtime/sonarqube_orchestrator/tests/__init__.py +0 -0
  857. package/skills/vds-skill/runtime/sonarqube_orchestrator/tests/conftest.py +134 -0
  858. package/skills/vds-skill/runtime/sonarqube_orchestrator/tests/test_batch.py +419 -0
  859. package/skills/vds-skill/runtime/sonarqube_orchestrator/tests/test_config.py +145 -0
  860. package/skills/vds-skill/runtime/sonarqube_orchestrator/tests/test_errors.py +78 -0
  861. package/skills/vds-skill/runtime/sonarqube_orchestrator/tests/test_external_sca.py +466 -0
  862. package/skills/vds-skill/runtime/sonarqube_orchestrator/tests/test_pr.py +471 -0
  863. package/skills/vds-skill/runtime/sonarqube_orchestrator/tests/test_reports.py +511 -0
  864. package/skills/vds-skill/runtime/sonarqube_orchestrator/tests/test_webhooks.py +660 -0
  865. package/skills/vds-skill/runtime/uv.lock +5046 -0
  866. package/skills/vds-skill/runtime/vds_agent_core/CHANGELOG.md +36 -0
  867. package/skills/vds-skill/runtime/vds_agent_core/README.md +453 -0
  868. package/skills/vds-skill/runtime/vds_agent_core/docs/PHASE9A_ASSESSMENT.md +50 -0
  869. package/skills/vds-skill/runtime/vds_agent_core/docs/embedding.md +468 -0
  870. package/skills/vds-skill/runtime/vds_agent_core/pyproject.toml +51 -0
  871. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/__init__.py +29 -0
  872. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/agents/__init__.py +26 -0
  873. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/agents/hooks.py +119 -0
  874. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/agents/loop.py +864 -0
  875. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/agents/tools.py +41 -0
  876. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/config.py +252 -0
  877. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/llm/__init__.py +55 -0
  878. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/llm/_cascade.py +143 -0
  879. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/llm/budget.py +353 -0
  880. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/llm/cache.py +373 -0
  881. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/llm/embedding.py +815 -0
  882. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/llm/provider.py +173 -0
  883. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/llm/schemas.py +45 -0
  884. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/observability/__init__.py +77 -0
  885. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/observability/decorators.py +258 -0
  886. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/observability/jsonl_exporter.py +236 -0
  887. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/observability/tracer.py +497 -0
  888. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/profiles.py +2015 -0
  889. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/runtime/__init__.py +0 -0
  890. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/runtime/agent_id.py +60 -0
  891. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/security/__init__.py +13 -0
  892. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/security/credentials.py +106 -0
  893. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/skills/__init__.py +1 -0
  894. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/skills/executor.py +238 -0
  895. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/skills/manager.py +381 -0
  896. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/skills/policy.py +568 -0
  897. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/workflows/__init__.py +19 -0
  898. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/workflows/langgraph_runner.py +102 -0
  899. package/skills/vds-skill/runtime/vds_agent_core/src/vds_agent_core/workflows/protocols.py +81 -0
  900. package/skills/vds-skill/runtime/vds_agent_core/tests/__init__.py +0 -0
  901. package/skills/vds-skill/runtime/vds_agent_core/tests/conftest.py +62 -0
  902. package/skills/vds-skill/runtime/vds_agent_core/tests/integration/__init__.py +0 -0
  903. package/skills/vds-skill/runtime/vds_agent_core/tests/integration/test_audit_loop_hooks_integration.py +135 -0
  904. package/skills/vds-skill/runtime/vds_agent_core/tests/integration/test_audit_observability_integration.py +246 -0
  905. package/skills/vds-skill/runtime/vds_agent_core/tests/integration/test_public_api_stability.py +91 -0
  906. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/__init__.py +0 -0
  907. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/llm/__init__.py +0 -0
  908. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/llm/test_call_site_parallelism.py +30 -0
  909. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/llm/test_dimension_guardrail.py +25 -0
  910. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/llm/test_drop_in_provider_extensibility.py +76 -0
  911. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/llm/test_embedding.py +393 -0
  912. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/llm/test_embedding_cache.py +302 -0
  913. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/llm/test_embedding_extra.py +696 -0
  914. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/llm/test_embedding_subclass.py +49 -0
  915. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/llm/test_no_provider_leakage_in_env.py +34 -0
  916. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/llm/test_provider_auto_route.py +48 -0
  917. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/llm/test_runtime_log_clean.py +111 -0
  918. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/llm/test_w7_logic_fixes.py +219 -0
  919. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/profiles/__init__.py +0 -0
  920. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/profiles/test_embedding_block_parser.py +194 -0
  921. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/profiles/test_env_resolver_allowlist.py +141 -0
  922. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/profiles/test_profile_authorization.py +158 -0
  923. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/profiles/test_profiles_w3_extra.py +547 -0
  924. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/profiles/test_real_audit_profile_compat.py +129 -0
  925. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/runtime/__init__.py +0 -0
  926. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/runtime/test_for_agent.py +322 -0
  927. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/runtime/test_w9_cascade_edges.py +369 -0
  928. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/security/__init__.py +0 -0
  929. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/security/test_credentials.py +132 -0
  930. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_agent_loop.py +663 -0
  931. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_agent_loop_coverage.py +429 -0
  932. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_agents_hooks_defaults.py +22 -0
  933. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_budget.py +155 -0
  934. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_budget_coverage.py +264 -0
  935. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_budget_tracking_only.py +71 -0
  936. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_cache.py +251 -0
  937. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_cache_context.py +62 -0
  938. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_config.py +155 -0
  939. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_langgraph_runner.py +45 -0
  940. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_langgraph_runner_coverage.py +98 -0
  941. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_llm_cache_deep.py +113 -0
  942. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_observability_decorators.py +697 -0
  943. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_observability_hooks.py +217 -0
  944. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_observability_jsonl_exporter.py +542 -0
  945. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_observability_jsonl_wiring.py +313 -0
  946. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_observability_tracer.py +896 -0
  947. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_profiles.py +1571 -0
  948. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_profiles_coverage.py +444 -0
  949. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_provider.py +316 -0
  950. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_schemas.py +63 -0
  951. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_skill_executor.py +297 -0
  952. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_skill_manager.py +370 -0
  953. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_skill_manager_coverage.py +364 -0
  954. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_skill_policy.py +402 -0
  955. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_skill_rubric.py +47 -0
  956. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_tools.py +51 -0
  957. package/skills/vds-skill/runtime/vds_agent_core/tests/unit/test_workflow_protocols.py +136 -0
  958. package/skills/vds-skill/runtime/vds_cli/README.md +201 -0
  959. package/skills/vds-skill/runtime/vds_cli/VERIFICATION_REPORT.md +41 -0
  960. package/skills/vds-skill/runtime/vds_cli/pyproject.toml +50 -0
  961. package/skills/vds-skill/runtime/vds_cli/src/vds_cli/__init__.py +3 -0
  962. package/skills/vds-skill/runtime/vds_cli/src/vds_cli/assets/git-credential-helper.py +235 -0
  963. package/skills/vds-skill/runtime/vds_cli/src/vds_cli/cli.py +1126 -0
  964. package/skills/vds-skill/runtime/vds_cli/src/vds_cli/commands/__init__.py +1 -0
  965. package/skills/vds-skill/runtime/vds_cli/src/vds_cli/commands/lint_cli.py +389 -0
  966. package/skills/vds-skill/runtime/vds_cli/src/vds_cli/confluence_sync.py +855 -0
  967. package/skills/vds-skill/runtime/vds_cli/src/vds_cli/docs/consumption/__init__.py +7 -0
  968. package/skills/vds-skill/runtime/vds_cli/src/vds_cli/docs/consumption/funnel.py +105 -0
  969. package/skills/vds-skill/runtime/vds_cli/src/vds_cli/docs/consumption/scanner.py +211 -0
  970. package/skills/vds-skill/runtime/vds_cli/src/vds_cli/docs/freshness/report.py +90 -0
  971. package/skills/vds-skill/runtime/vds_cli/src/vds_cli/docs/types.py +27 -0
  972. package/skills/vds-skill/runtime/vds_cli/src/vds_cli/docs_cmd.py +672 -0
  973. package/skills/vds-skill/runtime/vds_cli/src/vds_cli/docs_metrics.py +75 -0
  974. package/skills/vds-skill/runtime/vds_cli/src/vds_cli/docs_sync.py +1171 -0
  975. package/skills/vds-skill/runtime/vds_cli/src/vds_cli/ecosystem/__init__.py +39 -0
  976. package/skills/vds-skill/runtime/vds_cli/src/vds_cli/ecosystem/report.py +439 -0
  977. package/skills/vds-skill/runtime/vds_cli/src/vds_cli/ecosystem_docs.py +164 -0
  978. package/skills/vds-skill/runtime/vds_cli/src/vds_cli/env.py +111 -0
  979. package/skills/vds-skill/runtime/vds_cli/src/vds_cli/env_git_helper.py +281 -0
  980. package/skills/vds-skill/runtime/vds_cli/src/vds_cli/google_sheets_orchestrator/__init__.py +3 -0
  981. package/skills/vds-skill/runtime/vds_cli/src/vds_cli/google_sheets_orchestrator/google_sheets_orchestrator.py +173 -0
  982. package/skills/vds-skill/runtime/vds_cli/src/vds_cli/router.py +232 -0
  983. package/skills/vds-skill/runtime/vds_cli/src/vds_cli/skills_cmd.py +274 -0
  984. package/skills/vds-skill/runtime/vds_cli/src/vds_cli/sync_api.py +613 -0
  985. package/skills/vds-skill/runtime/vds_cli/src/vds_cli/sync_service.py +283 -0
  986. package/skills/vds-skill/runtime/vds_cli/tests/conftest.py +62 -0
  987. package/skills/vds-skill/runtime/vds_cli/tests/test_env_git_helper_lifecycle.py +261 -0
  988. package/skills/vds-skill/runtime/vds_cli/tests/test_git_credential_helper.py +240 -0
  989. package/skills/vds-skill/runtime/vds_cli/tests/test_router_help_proxy.py +43 -0
  990. package/skills/vds-skill/runtime/vds_cli/tests/unit/test_cli.py +241 -0
  991. package/skills/vds-skill/runtime/vds_cli/tests/unit/test_cli_DOC004.py +110 -0
  992. package/skills/vds-skill/runtime/vds_cli/tests/unit/test_confluence_sync.py +315 -0
  993. package/skills/vds-skill/runtime/vds_cli/tests/unit/test_confluence_sync_wave7.py +375 -0
  994. package/skills/vds-skill/runtime/vds_cli/tests/unit/test_consumption_funnel.py +106 -0
  995. package/skills/vds-skill/runtime/vds_cli/tests/unit/test_consumption_scanner.py +144 -0
  996. package/skills/vds-skill/runtime/vds_cli/tests/unit/test_docs_cmd.py +89 -0
  997. package/skills/vds-skill/runtime/vds_cli/tests/unit/test_docs_cmd_wave8.py +161 -0
  998. package/skills/vds-skill/runtime/vds_cli/tests/unit/test_docs_metrics.py +16 -0
  999. package/skills/vds-skill/runtime/vds_cli/tests/unit/test_docs_quality_score.py +61 -0
  1000. package/skills/vds-skill/runtime/vds_cli/tests/unit/test_docs_sync.py +417 -0
  1001. package/skills/vds-skill/runtime/vds_cli/tests/unit/test_ecosystem_cli_dashboard.py +667 -0
  1002. package/skills/vds-skill/runtime/vds_cli/tests/unit/test_ecosystem_cli_dashboard_rendering.py +143 -0
  1003. package/skills/vds-skill/runtime/vds_cli/tests/unit/test_ecosystem_docs.py +63 -0
  1004. package/skills/vds-skill/runtime/vds_cli/tests/unit/test_env.py +85 -0
  1005. package/skills/vds-skill/runtime/vds_cli/tests/unit/test_freshness_report.py +125 -0
  1006. package/skills/vds-skill/runtime/vds_cli/tests/unit/test_lint_cli.py +224 -0
  1007. package/skills/vds-skill/runtime/vds_cli/tests/unit/test_router.py +101 -0
  1008. package/skills/vds-skill/runtime/vds_cli/tests/unit/test_skills_cmd.py +419 -0
  1009. package/skills/vds-skill/runtime/vds_cli/tests/unit/test_sync_api.py +357 -0
  1010. package/skills/vds-skill/runtime/vds_cli/tests/unit/test_sync_service.py +170 -0
  1011. package/skills/vds-skill/runtime/vds_cli/tests/verification/conftest.py +51 -0
  1012. package/skills/vds-skill/runtime/vds_cli/tests/verification/test_bitbucket_real.py +32 -0
  1013. package/skills/vds-skill/runtime/vds_cli/tests/verification/test_confluence_real.py +32 -0
  1014. package/skills/vds-skill/runtime/vds_cli/tests/verification/test_jira_real.py +40 -0
  1015. package/skills/vds-skill/runtime/vds_cli_common/README.md +190 -0
  1016. package/skills/vds-skill/runtime/vds_cli_common/pyproject.toml +96 -0
  1017. package/skills/vds-skill/runtime/vds_cli_common/src/vds_cli_common/__init__.py +36 -0
  1018. package/skills/vds-skill/runtime/vds_cli_common/src/vds_cli_common/app.py +55 -0
  1019. package/skills/vds-skill/runtime/vds_cli_common/src/vds_cli_common/completers.py +139 -0
  1020. package/skills/vds-skill/runtime/vds_cli_common/src/vds_cli_common/context.py +201 -0
  1021. package/skills/vds-skill/runtime/vds_cli_common/src/vds_cli_common/env.py +163 -0
  1022. package/skills/vds-skill/runtime/vds_cli_common/src/vds_cli_common/errors.py +440 -0
  1023. package/skills/vds-skill/runtime/vds_cli_common/src/vds_cli_common/output.py +284 -0
  1024. package/skills/vds-skill/runtime/vds_cli_common/src/vds_cli_common/paths.py +78 -0
  1025. package/skills/vds-skill/runtime/vds_cli_common/src/vds_cli_common/testing.py +211 -0
  1026. package/skills/vds-skill/runtime/vds_cli_common/src/vds_cli_common/version.py +85 -0
  1027. package/skills/vds-skill/runtime/vds_cli_common/tests/__init__.py +0 -0
  1028. package/skills/vds-skill/runtime/vds_cli_common/tests/test_app.py +126 -0
  1029. package/skills/vds-skill/runtime/vds_cli_common/tests/test_completers.py +148 -0
  1030. package/skills/vds-skill/runtime/vds_cli_common/tests/test_context.py +192 -0
  1031. package/skills/vds-skill/runtime/vds_cli_common/tests/test_env.py +235 -0
  1032. package/skills/vds-skill/runtime/vds_cli_common/tests/test_errors.py +275 -0
  1033. package/skills/vds-skill/runtime/vds_cli_common/tests/test_output.py +229 -0
  1034. package/skills/vds-skill/runtime/vds_cli_common/tests/test_paths.py +61 -0
  1035. package/skills/vds-skill/runtime/vds_cli_common/tests/test_testing.py +138 -0
  1036. package/skills/vds-skill/runtime/vds_cli_common/tests/test_version.py +64 -0
  1037. package/skills/vds-skill/runtime/vidp_orchestrator/README.md +31 -0
  1038. package/skills/vds-skill/runtime/vidp_orchestrator/pyproject.toml +50 -0
  1039. package/skills/vds-skill/runtime/vidp_orchestrator/src/vds_vidp_orchestrator/__init__.py +26 -0
  1040. package/skills/vds-skill/runtime/vidp_orchestrator/src/vds_vidp_orchestrator/cli.py +246 -0
  1041. package/skills/vds-skill/runtime/vidp_orchestrator/src/vds_vidp_orchestrator/client.py +104 -0
  1042. package/skills/vds-skill/runtime/vidp_orchestrator/src/vds_vidp_orchestrator/config.py +82 -0
  1043. package/skills/vds-skill/runtime/vidp_orchestrator/src/vds_vidp_orchestrator/workflows.json +3 -0
  1044. package/skills/vds-skill/runtime/vidp_orchestrator/src/vds_vidp_orchestrator/workflows.py +130 -0
  1045. package/skills/vds-skill/vds-scripts-skill/SKILL.md +129 -0
  1046. package/skills/vds-skill/vds-scripts-skill/references/audit-commands.md +171 -0
  1047. package/skills/vds-skill/vds-scripts-skill/references/capability-index.md +34 -0
  1048. package/skills/vds-skill/vds-scripts-skill/references/development-commands.md +12 -0
  1049. package/skills/vds-skill/vds-scripts-skill/references/google-sheets.md +71 -0
  1050. package/skills/vds-skill/vds-scripts-skill/references/integration-commands.md +17 -0
  1051. package/skills/vds-skill/vds-scripts-skill/references/platform-bootstrap.md +25 -0
  1052. package/skills/vds-skill/vds-scripts-skill/references/specialist-routing.md +14 -0
  1053. package/skills/vds-skill/vds-scripts-skill/references/validation-commands.md +15 -0
@@ -0,0 +1,2015 @@
1
+ """Runtime profile activation — extracted core mechanics.
2
+
3
+ Loads YAML-based runtime profiles and applies env-var overrides for LLM,
4
+ retry, timeout, skill, backend, and agentic policies. The ``env_prefix``
5
+ parameter makes env-key mapping injectable so non-audit agents can reuse the
6
+ same profile engine with their own prefix.
7
+
8
+ The optional ``ConfigHooks`` and ``CodexCredentialResolver`` protocols allow
9
+ callers to inject config access and Codex credential resolution behavior
10
+ without importing audit-specific modules into ``vds_agent_core``.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import contextlib
16
+ import contextvars
17
+ import copy
18
+ import fnmatch
19
+ import json
20
+ import os
21
+ import re
22
+ import threading
23
+ from dataclasses import dataclass
24
+ from pathlib import Path
25
+ from typing import Any, Literal, Protocol, runtime_checkable
26
+
27
+ import structlog
28
+ import yaml
29
+ from vds_cli_common.env import load_shared_env
30
+ from vds_cli_common.paths import get_vds_config_root
31
+
32
+ logger = structlog.get_logger(__name__)
33
+
34
+ DEFAULT_RUNTIME_PROFILES_FILE = get_vds_config_root() / "audit.profiles.yaml"
35
+
36
+
37
+ # ---------------------------------------------------------------------------
38
+ # ConfigHooks Protocol
39
+ # ---------------------------------------------------------------------------
40
+
41
+
42
+ @runtime_checkable
43
+ class ConfigHooks(Protocol):
44
+ """Injectable config access for profile build operations.
45
+
46
+ Implementations provide get/set/reset for the caller's config system,
47
+ allowing build_llm_settings_for_profile to snapshot and restore config
48
+ without importing a specific config module.
49
+ """
50
+
51
+ def get_config(self) -> Any: ...
52
+ def set_config(self, cfg: Any) -> None: ...
53
+ def reset_config(self) -> None: ...
54
+
55
+
56
+ # ---------------------------------------------------------------------------
57
+ # Env-map tables — parameterized by _make_env_key(prefix, suffix)
58
+ # ---------------------------------------------------------------------------
59
+
60
+
61
+ def _make_env_map(prefix: str, mapping: dict[str, str]) -> dict[str, str]:
62
+ """Replace the default VDS_AUDIT_ prefix in env keys with the given prefix."""
63
+ result: dict[str, str] = {}
64
+ for key, env_key in mapping.items():
65
+ result[key] = env_key.replace("VDS_AUDIT_", prefix) if prefix != "VDS_AUDIT_" else env_key
66
+ return result
67
+
68
+
69
+ # Default env maps (VDS_AUDIT_ prefix) — used as templates
70
+ _DEFAULT_RETRY_POLICY_ENV_MAP: dict[str, str] = {
71
+ "agent_retries": "VDS_AUDIT_LLM__AGENT_RETRIES",
72
+ "output_retries": "VDS_AUDIT_LLM__OUTPUT_RETRIES",
73
+ }
74
+ _RETRY_POLICY_BOUNDS: dict[str, tuple[float, float, type[int] | type[float]]] = {
75
+ "agent_retries": (0, 6, int),
76
+ "output_retries": (0, 6, int),
77
+ }
78
+ _DEFAULT_TIMEOUT_POLICY_ENV_MAP: dict[str, str] = {
79
+ "agent_timeout_seconds": "VDS_AUDIT_LLM__AGENT_TIMEOUT_SECONDS",
80
+ "agent_timeout_max_seconds": "VDS_AUDIT_LLM__AGENT_TIMEOUT_MAX_SECONDS",
81
+ "agent_timeout_extension_seconds": "VDS_AUDIT_LLM__AGENT_TIMEOUT_EXTENSION_SECONDS",
82
+ "agent_timeout_extension_attempts": "VDS_AUDIT_LLM__AGENT_TIMEOUT_EXTENSION_ATTEMPTS",
83
+ "agent_timeout_heartbeat_seconds": "VDS_AUDIT_LLM__AGENT_TIMEOUT_HEARTBEAT_SECONDS",
84
+ "agent_idle_timeout_seconds": "VDS_AUDIT_LLM__AGENT_IDLE_TIMEOUT_SECONDS",
85
+ "row_timeout_ms": "VDS_AUDIT_ROW_TIMEOUT_MS",
86
+ "batch_timeout_ms": "VDS_AUDIT_BATCH_TIMEOUT_MS",
87
+ "row_progress_lease_seconds": "VDS_AUDIT_TIMEOUT_POLICY__ROW_PROGRESS_LEASE_SECONDS",
88
+ "row_stall_detection_seconds": "VDS_AUDIT_TIMEOUT_POLICY__ROW_STALL_DETECTION_SECONDS",
89
+ "row_absolute_timeout_ms": "VDS_AUDIT_TIMEOUT_POLICY__ROW_ABSOLUTE_TIMEOUT_MS",
90
+ "row_timeout_progress_extension_enabled": "VDS_AUDIT_ROW_TIMEOUT_PROGRESS_EXTENSION_ENABLED",
91
+ "row_timeout_progress_retry_attempts": "VDS_AUDIT_ROW_TIMEOUT_PROGRESS_RETRY_ATTEMPTS",
92
+ "row_timeout_progress_extension_ms": "VDS_AUDIT_ROW_TIMEOUT_PROGRESS_EXTENSION_MS",
93
+ "row_timeout_progress_max_ms": "VDS_AUDIT_ROW_TIMEOUT_PROGRESS_MAX_MS",
94
+ }
95
+ _TIMEOUT_POLICY_BOUNDS: dict[str, tuple[float, float, type[int] | type[float]]] = {
96
+ "agent_timeout_seconds": (30.0, 3600.0, float),
97
+ "agent_timeout_max_seconds": (60.0, 7200.0, float),
98
+ "agent_timeout_extension_seconds": (0.0, 1800.0, float),
99
+ "agent_timeout_extension_attempts": (0, 10, int),
100
+ "agent_timeout_heartbeat_seconds": (5.0, 300.0, float),
101
+ "agent_idle_timeout_seconds": (30.0, 1800.0, float),
102
+ "row_timeout_ms": (1000, 600000, int),
103
+ "batch_timeout_ms": (1000, 7200000, int),
104
+ "row_progress_lease_seconds": (0, 1800, int),
105
+ "row_stall_detection_seconds": (1, 900, int),
106
+ "row_absolute_timeout_ms": (1000, 3600000, int),
107
+ "row_timeout_progress_extension_enabled": (0, 1, int),
108
+ "row_timeout_progress_retry_attempts": (0, 5, int),
109
+ "row_timeout_progress_extension_ms": (1000, 300000, int),
110
+ "row_timeout_progress_max_ms": (1000, 1800000, int),
111
+ }
112
+ _SKILL_TRUST_TIERS: tuple[str, ...] = ("internal", "external-verified", "external-unverified")
113
+ _DEFAULT_SKILL_POLICY_ENV_MAP: dict[str, str] = {
114
+ "enabled": "VDS_AUDIT_LLM__SKILLS_TOOLSET_ENABLED",
115
+ "directories": "VDS_AUDIT_LLM__SKILLS_DIRECTORIES",
116
+ "allow_script_execution": "VDS_AUDIT_LLM__SKILLS_ALLOW_SCRIPT_EXECUTION",
117
+ "default_trust_tier": "VDS_AUDIT_LLM__SKILLS_DEFAULT_TRUST_TIER",
118
+ "allowed_trust_tiers": "VDS_AUDIT_LLM__SKILLS_ALLOWED_TRUST_TIERS",
119
+ "allowlist": "VDS_AUDIT_LLM__SKILLS_ALLOWLIST",
120
+ "trust_tiers": "VDS_AUDIT_LLM__SKILLS_TRUST_TIERS",
121
+ "strict_require_effective_skill": "VDS_AUDIT_AGENTIC_STRICT_REQUIRE_EFFECTIVE_SKILL",
122
+ }
123
+ _SKILL_POLICY_MAX_LIST_ITEMS = 200
124
+ _SKILL_POLICY_MAX_MAP_ITEMS = 200
125
+ _DEFAULT_ROW_BACKEND_POLICY_ENV_MAP: dict[str, str] = {
126
+ "backend": "VDS_AUDIT_LLM__ROW_EVALUATION_BACKEND",
127
+ "source": "VDS_AUDIT_LLM__ROW_EVALUATION_BACKEND_SOURCE",
128
+ "locked": "VDS_AUDIT_LLM__ROW_EVALUATION_BACKEND_LOCKED",
129
+ "allow_override": "VDS_AUDIT_LLM__ROW_EVALUATION_BACKEND_ALLOW_OVERRIDE",
130
+ }
131
+ _DEFAULT_ROW_BACKEND_OVERRIDE_REQUEST_ENV = "VDS_AUDIT_LLM__ROW_EVALUATION_BACKEND_OVERRIDE"
132
+ _ROW_EVALUATION_BACKENDS: tuple[str, ...] = ("prompt_evaluator", "dspy")
133
+ _DEFAULT_AGENT_RUNTIME_MODE_ENV = "VDS_AUDIT_LLM__AGENT_RUNTIME_MODE"
134
+ _AGENT_RUNTIME_MODES: tuple[str, ...] = ("pydanticai",)
135
+ _DEFAULT_AGENT_RUNTIME_POLICY_ENV_MAP: dict[str, str] = {
136
+ "tool_allowlists": "VDS_AUDIT_AGENTIC_TOOL_ALLOWLISTS",
137
+ "non_progress_policy": "VDS_AUDIT_AGENTIC_NON_PROGRESS_POLICY",
138
+ }
139
+ _DEFAULT_AGENTIC_POLICY_ENV_MAP: dict[str, str] = {
140
+ "non_progress_preset": "VDS_AUDIT_AGENTIC_NON_PROGRESS_PRESET",
141
+ "strict_no_fallback": "VDS_AUDIT_AGENTIC_STRICT_NO_FALLBACK",
142
+ }
143
+ _DEFAULT_AGENTIC_TOOL_FIRST_ENV_MAP: dict[str, str] = {
144
+ "tool_first_max_steps": "VDS_AUDIT_AGENTIC_TOOL_FIRST_MAX_STEPS",
145
+ "tool_first_timeout_seconds": "VDS_AUDIT_AGENTIC_TOOL_FIRST_TIMEOUT_SECONDS",
146
+ "tool_first_budget_units": "VDS_AUDIT_AGENTIC_TOOL_FIRST_BUDGET_UNITS",
147
+ "tool_first_max_route_transitions": "VDS_AUDIT_AGENTIC_TOOL_FIRST_MAX_ROUTE_TRANSITIONS",
148
+ "tool_first_max_route_transitions_per_pair": "VDS_AUDIT_AGENTIC_TOOL_FIRST_MAX_ROUTE_TRANSITIONS_PER_PAIR",
149
+ "tool_calls_limit": "VDS_AUDIT_AGENTIC_TOOL_CALLS_LIMIT",
150
+ "security_tool_calls_limit": "VDS_AUDIT_AGENTIC_SECURITY_TOOL_CALLS_LIMIT",
151
+ }
152
+ _AGENTIC_TOOL_FIRST_BOUNDS: dict[str, tuple[float, float, type[int] | type[float]]] = {
153
+ "tool_first_max_steps": (1, 50, int),
154
+ "tool_first_timeout_seconds": (1.0, 120.0, float),
155
+ "tool_first_budget_units": (1, 100, int),
156
+ "tool_first_max_route_transitions": (1, 12, int),
157
+ "tool_first_max_route_transitions_per_pair": (1, 12, int),
158
+ "tool_calls_limit": (1, 50, int),
159
+ "security_tool_calls_limit": (1, 100, int),
160
+ }
161
+ _NON_PROGRESS_PRESETS: tuple[str, ...] = ("strict", "balanced", "permissive")
162
+ _DEFAULT_MODEL_POLICY_LLM_ENV_MAP: dict[str, str] = {
163
+ "type": "VDS_AUDIT_LLM_PROTOCOL",
164
+ "base_url": "VDS_AUDIT_LLM__BASE_URL",
165
+ "api_key": "VDS_AUDIT_LLM__API_KEY",
166
+ "stream": "VDS_AUDIT_LLM__STREAM",
167
+ "agent_stream": "VDS_AUDIT_LLM__AGENT_STREAM",
168
+ "row_failover_profiles": "VDS_AUDIT_LLM__ROW_FAILOVER_PROFILES",
169
+ "row_failover_max_provider_hops": "VDS_AUDIT_LLM__ROW_FAILOVER_MAX_PROVIDER_HOPS",
170
+ "reasoning_effort": "VDS_AUDIT_LLM__REASONING_EFFORT",
171
+ "simple": "VDS_AUDIT_LLM__MODEL_SIMPLE",
172
+ "standard": "VDS_AUDIT_LLM__MODEL_STANDARD",
173
+ "complex": "VDS_AUDIT_LLM__MODEL_COMPLEX",
174
+ }
175
+ _DEFAULT_MODEL_POLICY_DSPY_ENV_MAP: dict[str, str] = {
176
+ "type": "VDS_AUDIT_DSPY_PROTOCOL",
177
+ "model": "VDS_AUDIT_DSPY_MODEL",
178
+ "api_key": "VDS_AUDIT_DSPY_API_KEY",
179
+ "max_tokens": "VDS_AUDIT_DSPY_MAX_TOKENS",
180
+ "temperature": "VDS_AUDIT_DSPY_TEMPERATURE",
181
+ "base_url": "VDS_AUDIT_DSPY_BASE_URL",
182
+ "system_role_compat": "VDS_AUDIT_DSPY_SYSTEM_ROLE_COMPAT",
183
+ }
184
+ _DEFAULT_MODEL_POLICY_EMBEDDING_ENV_MAP: dict[str, str] = {
185
+ "base_url": "VDS_AUDIT_EMBEDDING__BASE_URL",
186
+ "model": "VDS_AUDIT_EMBEDDING__MODEL",
187
+ "api_key": "VDS_AUDIT_EMBEDDING__API_KEY",
188
+ }
189
+ _SUPPORTED_PROFILE_PROTOCOLS: tuple[str, ...] = ("anthropic", "openai", "gemini", "openai-codex")
190
+ _LLM_REASONING_EFFORT_VALUES: tuple[str, ...] = ("none", "minimal", "low", "medium", "high", "xhigh")
191
+ _ENV_REF_PATTERN = re.compile(r"^\$\{([A-Za-z_][A-Za-z0-9_]*)\}$")
192
+ _ENV_SCHEME_PATTERN = re.compile(r"^\$\{env:([A-Za-z_][A-Za-z0-9_]*)\}$")
193
+ _CODEX_REF_PATTERN = re.compile(r"^\$\{codex:([a-z_]+)\}$")
194
+
195
+ # NFR-225.12: Compile-time allowlist for ${env:VAR} credential references.
196
+ # Operators may extend via VDS_AGENT_CORE__CREDENTIAL_ENV_ALLOWLIST (JSON array).
197
+ _DEFAULT_ENV_CREDENTIAL_ALLOWLIST: frozenset[str] = frozenset(
198
+ {
199
+ "OPENAI_API_KEY",
200
+ "ANTHROPIC_API_KEY",
201
+ "COHERE_API_KEY",
202
+ "VOYAGE_API_KEY",
203
+ "MISTRAL_API_KEY",
204
+ "JINA_API_KEY",
205
+ "HF_TOKEN",
206
+ "INTERNAL_EMBED_API_KEY",
207
+ }
208
+ )
209
+ _ENV_CREDENTIAL_ALLOWLIST_ENV = "VDS_AGENT_CORE__CREDENTIAL_ENV_ALLOWLIST"
210
+
211
+ # NFR-226.1: One-shot dedup for `profile_embedding_resolved` log emission.
212
+ _EMBEDDING_PROFILE_RESOLUTION_SEEN: set[str] = set()
213
+ _EMBEDDING_PROFILE_RESOLUTION_LOCK = threading.Lock()
214
+ _CODEX_REF_FIELDS: tuple[str, ...] = ("access_token", "account_id", "refresh_token")
215
+ _CODEX_CHATGPT_PROFILE_NAME = "codex-chatgpt"
216
+ _RUNTIME_PROFILE_BUILD_LOCK = threading.Lock()
217
+ _CODEX_CHATGPT_BASELINE_ENV_DEFAULTS: dict[str, str] = {
218
+ "VDS_AUDIT_LLM__SKILLS_TOOLSET_ENABLED": "false",
219
+ "VDS_AUDIT_AGENTIC_ENABLE_SKILLS_TOOLSET": "false",
220
+ "VDS_AUDIT_AGENTIC_SECURITY_ENABLE_SKILLS_TOOLSET": "false",
221
+ "VDS_AUDIT_AGENTIC_STRICT_REQUIRE_EFFECTIVE_SKILL": "false",
222
+ "VDS_AUDIT_AGENTIC_STRICT_NO_FALLBACK": "true",
223
+ "VDS_AUDIT_LLM__ROW_EVALUATION_BACKEND": "prompt_evaluator",
224
+ "VDS_AUDIT_LLM__ROW_EVALUATION_BACKEND_SOURCE": "profile_codex_baseline",
225
+ "VDS_AUDIT_LLM__ROW_EVALUATION_BACKEND_LOCKED": "false",
226
+ "VDS_AUDIT_LLM__ROW_EVALUATION_BACKEND_ALLOW_OVERRIDE": "false",
227
+ "VDS_AUDIT_LLM__AGENT_RETRIES": "2",
228
+ "VDS_AUDIT_LLM__OUTPUT_RETRIES": "4",
229
+ "VDS_AUDIT_AGENTIC_TOOL_FIRST_MAX_ROUTE_TRANSITIONS": "6",
230
+ "VDS_AUDIT_AGENTIC_TOOL_FIRST_MAX_ROUTE_TRANSITIONS_PER_PAIR": "2",
231
+ "VDS_AUDIT_LLM__CODE_REVIEW_MAX_TOTAL_CHARS": "200000",
232
+ }
233
+ _RUNTIME_LLM_POLICY_FIELDS: tuple[str, ...] = (
234
+ "stream",
235
+ "agent_stream",
236
+ "reasoning_effort",
237
+ "max_tokens_per_request",
238
+ "agent_retries",
239
+ "output_retries",
240
+ "agent_timeout_seconds",
241
+ "agent_timeout_max_seconds",
242
+ "agent_timeout_extension_seconds",
243
+ "agent_timeout_extension_attempts",
244
+ "agent_timeout_heartbeat_seconds",
245
+ "agent_rate_limit_retry_attempts",
246
+ "agent_rate_limit_retry_backoff_seconds",
247
+ "agent_idle_timeout_seconds",
248
+ "row_failover_profiles",
249
+ "row_failover_max_provider_hops",
250
+ "row_progress_lease_seconds",
251
+ "row_stall_detection_seconds",
252
+ "row_absolute_timeout_ms",
253
+ "agent_event_stream_enabled",
254
+ )
255
+ _PROFILE_PROTECTED_ENV_EXTRA_KEYS: tuple[str, ...] = (
256
+ "VDS_AUDIT_LLM__MAX_TOKENS_PER_REQUEST",
257
+ "VDS_AUDIT_AGENTIC_ENABLE_SKILLS_TOOLSET",
258
+ "VDS_AUDIT_AGENTIC_SECURITY_ENABLE_SKILLS_TOOLSET",
259
+ )
260
+
261
+
262
+ # ---------------------------------------------------------------------------
263
+ # Public dataclass
264
+ # ---------------------------------------------------------------------------
265
+
266
+
267
+ @dataclass(slots=True)
268
+ class RuntimeProfileActivation:
269
+ """Resolved runtime profile activation details."""
270
+
271
+ profile_name: str | None
272
+ source: Literal["cli", "default", "none"]
273
+ profile_path: Path
274
+ applied_env_keys: tuple[str, ...]
275
+
276
+
277
+ # ---------------------------------------------------------------------------
278
+ # Exceptions (Phase 225 W3 — FR-226.13, FR-226.15, NFR-225.12, NFR-225.13)
279
+ # ---------------------------------------------------------------------------
280
+
281
+
282
+ class ProfileValidationError(ValueError):
283
+ """Raised when a profile YAML field fails structural validation (FR-226.13)."""
284
+
285
+
286
+ class CredentialResolutionError(ValueError):
287
+ """Raised when a ``${env:VAR}`` reference targets a non-allowlisted env var (NFR-225.12)."""
288
+
289
+
290
+ class ProfileAuthorizationError(PermissionError):
291
+ """Raised when an agent_id is not allowed to activate a profile (NFR-225.13)."""
292
+
293
+
294
+ # ---------------------------------------------------------------------------
295
+ # Env-map builder for custom prefix
296
+ # ---------------------------------------------------------------------------
297
+
298
+
299
+ class _EnvMaps:
300
+ """Lazily-built env maps for a given prefix."""
301
+
302
+ def __init__(self, prefix: str) -> None:
303
+ self.prefix = prefix
304
+ self.retry = _make_env_map(prefix, _DEFAULT_RETRY_POLICY_ENV_MAP)
305
+ self.timeout = _make_env_map(prefix, _DEFAULT_TIMEOUT_POLICY_ENV_MAP)
306
+ self.skill = _make_env_map(prefix, _DEFAULT_SKILL_POLICY_ENV_MAP)
307
+ self.row_backend = _make_env_map(prefix, _DEFAULT_ROW_BACKEND_POLICY_ENV_MAP)
308
+ self.row_backend_override_env = (
309
+ _DEFAULT_ROW_BACKEND_OVERRIDE_REQUEST_ENV.replace("VDS_AUDIT_", prefix)
310
+ if prefix != "VDS_AUDIT_"
311
+ else _DEFAULT_ROW_BACKEND_OVERRIDE_REQUEST_ENV
312
+ )
313
+ self.agent_runtime_mode_env = (
314
+ _DEFAULT_AGENT_RUNTIME_MODE_ENV.replace("VDS_AUDIT_", prefix)
315
+ if prefix != "VDS_AUDIT_"
316
+ else _DEFAULT_AGENT_RUNTIME_MODE_ENV
317
+ )
318
+ self.agent_runtime = _make_env_map(prefix, _DEFAULT_AGENT_RUNTIME_POLICY_ENV_MAP)
319
+ self.agentic = _make_env_map(prefix, _DEFAULT_AGENTIC_POLICY_ENV_MAP)
320
+ self.agentic_tool_first = _make_env_map(prefix, _DEFAULT_AGENTIC_TOOL_FIRST_ENV_MAP)
321
+ self.model_llm = _make_env_map(prefix, _DEFAULT_MODEL_POLICY_LLM_ENV_MAP)
322
+ self.model_dspy = _make_env_map(prefix, _DEFAULT_MODEL_POLICY_DSPY_ENV_MAP)
323
+ self.model_embedding = _make_env_map(prefix, _DEFAULT_MODEL_POLICY_EMBEDDING_ENV_MAP)
324
+ self.active_profile_env = f"{prefix}ACTIVE_PROFILE"
325
+
326
+
327
+ # ---------------------------------------------------------------------------
328
+ # Public functions
329
+ # ---------------------------------------------------------------------------
330
+
331
+
332
+ def resolve_runtime_profiles_path() -> Path:
333
+ """Resolve profile config path with optional env override."""
334
+ configured_path = os.getenv("VDS_AUDIT_RUNTIME_PROFILES_FILE", "").strip()
335
+ if configured_path:
336
+ return Path(configured_path).expanduser()
337
+ return DEFAULT_RUNTIME_PROFILES_FILE
338
+
339
+
340
+ def list_runtime_profile_names() -> list[str]:
341
+ """Return configured runtime profile names in file order."""
342
+ profile_path = resolve_runtime_profiles_path()
343
+ raw: dict[str, Any] = {}
344
+ if profile_path.exists():
345
+ payload = yaml.safe_load(profile_path.read_text(encoding="utf-8")) or {}
346
+ if isinstance(payload, dict):
347
+ raw = payload
348
+ profiles = raw.get("profiles")
349
+ profiles_map = profiles if isinstance(profiles, dict) else {}
350
+ names: list[str] = []
351
+ for name, payload in profiles_map.items():
352
+ profile_name = str(name).strip()
353
+ if not profile_name or not isinstance(payload, dict):
354
+ continue
355
+ names.append(profile_name)
356
+ return names
357
+
358
+
359
+ def resolve_default_failover_profiles(
360
+ active_profile: str | None,
361
+ all_profiles: list[str] | None = None,
362
+ ) -> list[str]:
363
+ """Return the default failover profile list for a given active profile."""
364
+ if all_profiles is None:
365
+ all_profiles = list_runtime_profile_names()
366
+ active_stripped = str(active_profile or "").strip()
367
+ result: list[str] = []
368
+ seen: set[str] = set()
369
+ for name in all_profiles:
370
+ name_stripped = str(name or "").strip()
371
+ if not name_stripped or name_stripped == active_stripped or name_stripped in seen:
372
+ continue
373
+ seen.add(name_stripped)
374
+ result.append(name_stripped)
375
+ return result
376
+
377
+
378
+ def resolve_agentic_tool_first_scalar(
379
+ key: str,
380
+ *,
381
+ default: int | float,
382
+ env_prefix: str = "VDS_AUDIT_",
383
+ ) -> int | float:
384
+ """Resolve bounded agentic scalar env values using runtime-profile limits."""
385
+ maps = _EnvMaps(env_prefix)
386
+ env_key = maps.agentic_tool_first[key]
387
+ min_value, max_value, value_type = _AGENTIC_TOOL_FIRST_BOUNDS[key]
388
+ raw_value = os.getenv(env_key)
389
+ if raw_value is None:
390
+ return default
391
+ try:
392
+ coerced = value_type(raw_value)
393
+ except (TypeError, ValueError):
394
+ return default
395
+ if value_type is int and coerced == 0:
396
+ return 0
397
+ bounded = max(min_value, min(max_value, coerced))
398
+ return int(bounded) if value_type is int else float(bounded)
399
+
400
+
401
+ def profile_protected_env_keys(env_prefix: str = "VDS_AUDIT_") -> tuple[str, ...]:
402
+ """Return env keys whose explicit operator overrides must out-rank profile defaults."""
403
+ maps = _EnvMaps(env_prefix)
404
+ ordered_keys: list[str] = []
405
+ for mapping in (
406
+ maps.model_llm,
407
+ maps.model_dspy,
408
+ maps.model_embedding,
409
+ maps.retry,
410
+ maps.timeout,
411
+ maps.skill,
412
+ maps.row_backend,
413
+ maps.agent_runtime,
414
+ maps.agentic,
415
+ maps.agentic_tool_first,
416
+ ):
417
+ for env_key in mapping.values():
418
+ normalized = str(env_key).strip()
419
+ if normalized and normalized not in ordered_keys:
420
+ ordered_keys.append(normalized)
421
+ extra = _PROFILE_PROTECTED_ENV_EXTRA_KEYS
422
+ if env_prefix != "VDS_AUDIT_":
423
+ extra = tuple(k.replace("VDS_AUDIT_", env_prefix) for k in extra)
424
+ for env_key in extra:
425
+ normalized = str(env_key).strip()
426
+ if normalized and normalized not in ordered_keys:
427
+ ordered_keys.append(normalized)
428
+ return tuple(ordered_keys)
429
+
430
+
431
+ @runtime_checkable
432
+ class CodexCredentialResolver(Protocol):
433
+ """Injectable credential resolver for ${codex:...} profile references.
434
+
435
+ Audit provides the concrete implementation using codex_oauth.
436
+ Non-audit orchestrators that don't use Codex profiles don't need this.
437
+ """
438
+
439
+ def resolve(self, field: str) -> str: ...
440
+
441
+
442
+ # Backward-compatible alias for existing internal references/tests.
443
+ CredentialResolver = CodexCredentialResolver
444
+
445
+
446
+ # Context variable for credential resolver — set by apply_runtime_profile,
447
+ # read by _resolve_env_reference_if_needed (avoids threading through 18+ call sites)
448
+ _credential_resolver_ctx: contextvars.ContextVar[CodexCredentialResolver | None] = contextvars.ContextVar(
449
+ "_credential_resolver_ctx",
450
+ default=None,
451
+ )
452
+
453
+
454
+ def apply_runtime_profile(
455
+ requested_profile: str | None,
456
+ *,
457
+ env_prefix: str = "VDS_AUDIT_",
458
+ force_override: bool = False,
459
+ _config_hooks: ConfigHooks | None = None,
460
+ credential_resolver: CodexCredentialResolver | None = None,
461
+ parse_embedding: bool = False,
462
+ embedding_env_prefix: str = "VDS_AGENT_CORE_EMBED__",
463
+ ) -> RuntimeProfileActivation:
464
+ """Apply runtime profile env overrides before config loading.
465
+
466
+ Args:
467
+ requested_profile: Profile name to activate (None = use default from YAML).
468
+ env_prefix: Prefix for env-key mapping (default "VDS_AUDIT_").
469
+ force_override: If True, override already-set env vars.
470
+ _config_hooks: Optional config access hooks for build operations (private param; prefix prevents accidental positional use).
471
+ parse_embedding: If True (W3, FR-226.13), parse the optional
472
+ ``model.embedding`` block and project its fields into env vars under
473
+ ``embedding_env_prefix``. Default ``False`` preserves the FR-225.22
474
+ back-compat lock for existing audit / progress_report consumers.
475
+ embedding_env_prefix: Env prefix for embedding env vars when
476
+ ``parse_embedding`` is true (default ``VDS_AGENT_CORE_EMBED__``,
477
+ matches :class:`EmbeddingSettings` model_config).
478
+ """
479
+ load_shared_env(ensure_defaults=False)
480
+
481
+ # Set credential resolver in context for nested call sites
482
+ _credential_resolver_ctx.set(credential_resolver)
483
+
484
+ maps = _EnvMaps(env_prefix)
485
+ profile_path = resolve_runtime_profiles_path()
486
+ raw: dict[str, Any] = {}
487
+ if profile_path.exists():
488
+ payload = yaml.safe_load(profile_path.read_text(encoding="utf-8")) or {}
489
+ if isinstance(payload, dict):
490
+ raw = payload
491
+
492
+ profiles = raw.get("profiles")
493
+ profiles_map = profiles if isinstance(profiles, dict) else {}
494
+ default_profile = raw.get("default_profile")
495
+ default_profile_name = str(default_profile).strip() if isinstance(default_profile, str) else ""
496
+
497
+ profile_name: str | None = None
498
+ source: Literal["cli", "default", "none"] = "none"
499
+ if requested_profile and requested_profile.strip():
500
+ profile_name = requested_profile.strip()
501
+ source = "cli"
502
+ elif default_profile_name:
503
+ profile_name = default_profile_name
504
+ source = "default"
505
+
506
+ if not profile_name:
507
+ return RuntimeProfileActivation(
508
+ profile_name=None,
509
+ source=source,
510
+ profile_path=profile_path,
511
+ applied_env_keys=(),
512
+ )
513
+
514
+ profile_payload = profiles_map.get(profile_name)
515
+ if not isinstance(profile_payload, dict):
516
+ raise ValueError(
517
+ f"Runtime profile '{profile_name}' was not found in {profile_path}. Define it under profiles.<name>."
518
+ )
519
+
520
+ applied_keys: list[str] = []
521
+
522
+ model_payload = profile_payload.get("model")
523
+ model_values = model_payload if isinstance(model_payload, dict) else {}
524
+ _apply_profile_model_policy(
525
+ profile_name=profile_name,
526
+ model_policy_payload=model_values,
527
+ applied_keys=applied_keys,
528
+ force_override=force_override,
529
+ maps=maps,
530
+ )
531
+
532
+ env_payload = profile_payload.get("env")
533
+ env_values = env_payload if isinstance(env_payload, dict) else {}
534
+ for key, value in env_values.items():
535
+ env_key = str(key).strip()
536
+ if not env_key:
537
+ continue
538
+ resolved_value = _resolve_env_reference_if_needed(
539
+ profile_name=profile_name,
540
+ key=f"env.{env_key}",
541
+ raw_value=value,
542
+ credential_resolver=credential_resolver,
543
+ )
544
+ if _set_profile_env(env_key, resolved_value, force_override=force_override):
545
+ applied_keys.append(env_key)
546
+
547
+ retry_policy_payload = profile_payload.get("retry_policy")
548
+ retry_policy = retry_policy_payload if isinstance(retry_policy_payload, dict) else {}
549
+ _apply_profile_scalar_policy(
550
+ profile_name=profile_name,
551
+ policy_name="retry_policy",
552
+ policy_payload=retry_policy,
553
+ env_map=maps.retry,
554
+ bounds_map=_RETRY_POLICY_BOUNDS,
555
+ applied_keys=applied_keys,
556
+ force_override=force_override,
557
+ )
558
+
559
+ timeout_policy_payload = profile_payload.get("timeout_policy")
560
+ timeout_policy = timeout_policy_payload if isinstance(timeout_policy_payload, dict) else {}
561
+ _apply_profile_scalar_policy(
562
+ profile_name=profile_name,
563
+ policy_name="timeout_policy",
564
+ policy_payload=timeout_policy,
565
+ env_map=maps.timeout,
566
+ bounds_map=_TIMEOUT_POLICY_BOUNDS,
567
+ applied_keys=applied_keys,
568
+ force_override=force_override,
569
+ )
570
+
571
+ skill_policy_payload = profile_payload.get("skill_policy")
572
+ skill_policy = skill_policy_payload if isinstance(skill_policy_payload, dict) else {}
573
+ _apply_profile_skill_policy(
574
+ profile_name=profile_name,
575
+ skill_policy_payload=skill_policy,
576
+ applied_keys=applied_keys,
577
+ force_override=force_override,
578
+ maps=maps,
579
+ )
580
+
581
+ backend_policy_payload = profile_payload.get("backend_policy")
582
+ backend_policy = backend_policy_payload if isinstance(backend_policy_payload, dict) else {}
583
+ _apply_profile_backend_policy(
584
+ profile_name=profile_name,
585
+ backend_policy_payload=backend_policy,
586
+ applied_keys=applied_keys,
587
+ force_override=force_override,
588
+ maps=maps,
589
+ )
590
+
591
+ agent_runtime_policy_payload = profile_payload.get("agent_runtime_policy")
592
+ agent_runtime_policy = agent_runtime_policy_payload if isinstance(agent_runtime_policy_payload, dict) else {}
593
+ _apply_profile_agent_runtime_policy(
594
+ profile_name=profile_name,
595
+ agent_runtime_policy_payload=agent_runtime_policy,
596
+ applied_keys=applied_keys,
597
+ force_override=force_override,
598
+ maps=maps,
599
+ )
600
+
601
+ agentic_payload = profile_payload.get("agentic")
602
+ agentic_policy = agentic_payload if isinstance(agentic_payload, dict) else {}
603
+ _apply_profile_agentic_policy(
604
+ profile_name=profile_name,
605
+ agentic_payload=agentic_policy,
606
+ applied_keys=applied_keys,
607
+ force_override=force_override,
608
+ maps=maps,
609
+ )
610
+
611
+ _auto_derive_dspy_config(
612
+ profile_name=profile_name,
613
+ applied_keys=applied_keys,
614
+ force_override=force_override,
615
+ maps=maps,
616
+ )
617
+ _validate_dspy_coherence(profile_name=profile_name, maps=maps)
618
+ _apply_codex_chatgpt_baseline_defaults(
619
+ profile_name=profile_name,
620
+ applied_keys=applied_keys,
621
+ env_prefix=env_prefix,
622
+ )
623
+
624
+ # FR-226.13 (W3): opt-in embedding-block parser. Default OFF preserves
625
+ # FR-225.22 back-compat lock for existing audit / progress_report callers.
626
+ if parse_embedding:
627
+ embedding_payload_raw = (
628
+ model_values.get("embedding") if isinstance(model_values, dict) else None
629
+ )
630
+ embedding_payload = embedding_payload_raw if isinstance(embedding_payload_raw, dict) else {}
631
+ if embedding_payload:
632
+ _apply_profile_embedding_block(
633
+ profile_name=profile_name,
634
+ embedding_payload=embedding_payload,
635
+ applied_keys=applied_keys,
636
+ force_override=force_override,
637
+ embedding_env_prefix=embedding_env_prefix,
638
+ credential_resolver=credential_resolver,
639
+ )
640
+ _maybe_log_embedding_resolution(profile_name)
641
+
642
+ # Propagate API key to provider-specific env vars for pydantic-ai.
643
+ _resolved_api_key = os.environ.get(maps.model_llm["api_key"], "")
644
+ _model_payload = profile_payload.get("model", {})
645
+ _llm_type = (
646
+ str((_model_payload.get("llm") or {}).get("type", "")).strip().lower()
647
+ if isinstance(_model_payload, dict)
648
+ else ""
649
+ )
650
+ if _resolved_api_key:
651
+ if _llm_type == "anthropic" and not os.environ.get("ANTHROPIC_API_KEY"):
652
+ os.environ["ANTHROPIC_API_KEY"] = _resolved_api_key
653
+ elif _llm_type in ("openai", "") and not os.environ.get("OPENAI_API_KEY"):
654
+ os.environ["OPENAI_API_KEY"] = _resolved_api_key
655
+
656
+ os.environ[maps.active_profile_env] = profile_name
657
+ return RuntimeProfileActivation(
658
+ profile_name=profile_name,
659
+ source=source,
660
+ profile_path=profile_path,
661
+ applied_env_keys=tuple(applied_keys),
662
+ )
663
+
664
+
665
+ def build_llm_settings_for_profile(
666
+ profile_name: str,
667
+ *,
668
+ env_prefix: str = "VDS_AUDIT_",
669
+ config_hooks: ConfigHooks | None = None,
670
+ settings_factory: Any = None,
671
+ ) -> Any:
672
+ """Build isolated LLM settings for a runtime profile without persistent env mutation.
673
+
674
+ Args:
675
+ profile_name: The profile to build settings for.
676
+ env_prefix: Env prefix for the profile engine.
677
+ config_hooks: Config get/set/reset hooks. Required for config snapshot/restore.
678
+ settings_factory: Callable that returns LLMSettings from current config.
679
+ If None, returns None (caller must handle).
680
+ """
681
+ with _RUNTIME_PROFILE_BUILD_LOCK:
682
+ previous_config = config_hooks.get_config() if config_hooks else None
683
+ env_snapshot = {key: value for key, value in os.environ.items() if key.startswith(env_prefix)}
684
+ try:
685
+ apply_runtime_profile(profile_name, env_prefix=env_prefix, force_override=True)
686
+ if config_hooks:
687
+ config_hooks.reset_config()
688
+ if settings_factory is not None:
689
+ return settings_factory()
690
+ return None
691
+ finally:
692
+ for key in [item for item in os.environ if item.startswith(env_prefix)]:
693
+ if key not in env_snapshot:
694
+ os.environ.pop(key, None)
695
+ for key, value in env_snapshot.items():
696
+ os.environ[key] = value
697
+ if config_hooks and previous_config is not None:
698
+ config_hooks.set_config(previous_config)
699
+
700
+
701
+ def inherit_runtime_llm_policy(
702
+ profile_name: str,
703
+ *,
704
+ source_llm: Any | None = None,
705
+ env_prefix: str = "VDS_AUDIT_",
706
+ config_hooks: ConfigHooks | None = None,
707
+ settings_factory: Any = None,
708
+ ) -> Any:
709
+ """Build profile settings while preserving active runtime execution policy knobs."""
710
+ settings = build_llm_settings_for_profile(
711
+ profile_name,
712
+ env_prefix=env_prefix,
713
+ config_hooks=config_hooks,
714
+ settings_factory=settings_factory,
715
+ )
716
+ if source_llm is None:
717
+ return settings
718
+
719
+ if hasattr(settings, "model_copy"):
720
+ with contextlib.suppress(TypeError, ValueError, AttributeError):
721
+ settings = settings.model_copy(deep=True)
722
+ else:
723
+ settings = copy.copy(settings)
724
+
725
+ for field_name in _RUNTIME_LLM_POLICY_FIELDS:
726
+ if not hasattr(source_llm, field_name):
727
+ continue
728
+ with contextlib.suppress(Exception):
729
+ setattr(settings, field_name, copy.deepcopy(getattr(source_llm, field_name)))
730
+ return settings
731
+
732
+
733
+ def build_embedding_settings_for_profile(
734
+ profile_name: str,
735
+ *,
736
+ env_prefix: str = "VDS_AUDIT_",
737
+ embedding_env_prefix: str = "VDS_AGENT_CORE_EMBED__",
738
+ config_hooks: ConfigHooks | None = None,
739
+ credential_resolver: CodexCredentialResolver | None = None,
740
+ ) -> Any:
741
+ """Build :class:`EmbeddingSettings` for a runtime profile (FR-226.13).
742
+
743
+ Mirrors :func:`build_llm_settings_for_profile`: snapshots both the LLM-prefix
744
+ env vars and the embedding-prefix env vars, applies the profile with
745
+ ``parse_embedding=True``, constructs the EmbeddingSettings, then restores
746
+ the env. Side-effect-free (FR-226.11) -- no Redis / disk-write calls.
747
+
748
+ Args:
749
+ profile_name: Runtime profile to activate.
750
+ env_prefix: LLM-side env prefix (kept for symmetry with siblings).
751
+ embedding_env_prefix: Embedding-side env prefix
752
+ (matches ``EmbeddingSettings.model_config["env_prefix"]``).
753
+ config_hooks: Optional config snapshot/restore hooks.
754
+ credential_resolver: Optional resolver for ``${codex:...}`` references.
755
+
756
+ Returns:
757
+ Newly-constructed :class:`EmbeddingSettings` instance.
758
+ """
759
+ # Lazy import to break the profiles -> llm.embedding cycle.
760
+ from vds_agent_core.llm.embedding import EmbeddingSettings
761
+
762
+ with _RUNTIME_PROFILE_BUILD_LOCK:
763
+ previous_config = config_hooks.get_config() if config_hooks else None
764
+ env_snapshot: dict[str, str] = {
765
+ key: value
766
+ for key, value in os.environ.items()
767
+ if key.startswith(env_prefix) or key.startswith(embedding_env_prefix)
768
+ }
769
+ try:
770
+ apply_runtime_profile(
771
+ profile_name,
772
+ env_prefix=env_prefix,
773
+ force_override=True,
774
+ credential_resolver=credential_resolver,
775
+ parse_embedding=True,
776
+ embedding_env_prefix=embedding_env_prefix,
777
+ )
778
+ if config_hooks:
779
+ config_hooks.reset_config()
780
+ return EmbeddingSettings()
781
+ finally:
782
+ for key in [
783
+ item
784
+ for item in os.environ
785
+ if item.startswith(env_prefix) or item.startswith(embedding_env_prefix)
786
+ ]:
787
+ if key not in env_snapshot:
788
+ os.environ.pop(key, None)
789
+ for key, value in env_snapshot.items():
790
+ os.environ[key] = value
791
+ if config_hooks and previous_config is not None:
792
+ config_hooks.set_config(previous_config)
793
+
794
+
795
+ def is_agent_allowed_for_profile(
796
+ profile_name: str,
797
+ agent_id: str,
798
+ *,
799
+ profiles: dict[str, Any] | None = None,
800
+ ) -> bool:
801
+ """Check whether ``agent_id`` is allowed to activate ``profile_name`` (NFR-225.13).
802
+
803
+ The ``allowed_agents`` field on a profile entry is an optional list of
804
+ fnmatch-style glob patterns. Absent field => any agent allowed
805
+ (back-compat). When present, ``agent_id`` must match at least one pattern.
806
+
807
+ Args:
808
+ profile_name: Profile to check.
809
+ agent_id: Agent identifier (matched verbatim against globs).
810
+ profiles: Optional pre-loaded profiles map. Falls back to loading
811
+ from :func:`resolve_runtime_profiles_path` when ``None``.
812
+
813
+ Returns:
814
+ True if allowed (or field absent); False otherwise.
815
+ """
816
+ profiles_map = profiles
817
+ if profiles_map is None:
818
+ profile_path = resolve_runtime_profiles_path()
819
+ raw: dict[str, Any] = {}
820
+ if profile_path.exists():
821
+ payload = yaml.safe_load(profile_path.read_text(encoding="utf-8")) or {}
822
+ if isinstance(payload, dict):
823
+ raw = payload
824
+ loaded = raw.get("profiles")
825
+ profiles_map = loaded if isinstance(loaded, dict) else {}
826
+ profile_payload = profiles_map.get(profile_name)
827
+ if not isinstance(profile_payload, dict):
828
+ # Unknown profile -> defer to caller; treat as "no constraint" so the
829
+ # subsequent profile-resolution path raises a clearer error message.
830
+ return True
831
+ allowed_agents = profile_payload.get("allowed_agents")
832
+ if allowed_agents is None:
833
+ return True
834
+ if not isinstance(allowed_agents, list):
835
+ raise ProfileValidationError(
836
+ f"Runtime profile '{profile_name}' has invalid allowed_agents: "
837
+ f"{allowed_agents!r} (expected list of glob strings)."
838
+ )
839
+ for pattern in allowed_agents:
840
+ if not isinstance(pattern, str):
841
+ continue
842
+ if fnmatch.fnmatch(agent_id, pattern):
843
+ return True
844
+ return False
845
+
846
+
847
+ def resolve_skill_directory_path(raw_path: str | Path) -> Path:
848
+ """Resolve a skill-directory path with portable relative-path semantics."""
849
+ path_obj = raw_path if isinstance(raw_path, Path) else Path(str(raw_path))
850
+ expanded = path_obj.expanduser()
851
+ if expanded.is_absolute():
852
+ return expanded.resolve()
853
+ candidate_bases: list[Path] = []
854
+ for env_name in ("VDS_PROJECT_DIR", "CLAUDE_PROJECT_DIR"):
855
+ raw_base = os.getenv(env_name)
856
+ if raw_base and raw_base.strip():
857
+ candidate_bases.append(Path(raw_base).expanduser())
858
+ candidate_bases.append(Path.cwd())
859
+ for base in candidate_bases:
860
+ candidate = (base / expanded).resolve()
861
+ if candidate.exists():
862
+ return candidate
863
+ return (candidate_bases[0] / expanded).resolve()
864
+
865
+
866
+ # ---------------------------------------------------------------------------
867
+ # Private helpers
868
+ # ---------------------------------------------------------------------------
869
+
870
+
871
+ def _set_profile_env(env_key: str, value: Any, *, force_override: bool = False) -> bool:
872
+ """Set profile env var without overriding an already-defined process env."""
873
+ existing = os.environ.get(env_key)
874
+ if not force_override and isinstance(existing, str) and existing.strip():
875
+ return False
876
+ os.environ[env_key] = str(value)
877
+ return True
878
+
879
+
880
+ def _get_env_credential_allowlist() -> frozenset[str]:
881
+ """Return the active ``${env:VAR}`` allowlist (compile-time defaults + operator extensions).
882
+
883
+ Operators may extend via ``VDS_AGENT_CORE__CREDENTIAL_ENV_ALLOWLIST`` (JSON array).
884
+ Malformed JSON / non-list payloads silently fall back to the compile-time default
885
+ (NFR-225.12 -- never narrow the allowlist via env-var typo).
886
+ """
887
+ extra = os.environ.get(_ENV_CREDENTIAL_ALLOWLIST_ENV, "").strip()
888
+ if not extra:
889
+ return _DEFAULT_ENV_CREDENTIAL_ALLOWLIST
890
+ try:
891
+ parsed = json.loads(extra)
892
+ except json.JSONDecodeError:
893
+ return _DEFAULT_ENV_CREDENTIAL_ALLOWLIST
894
+ if not isinstance(parsed, list):
895
+ return _DEFAULT_ENV_CREDENTIAL_ALLOWLIST
896
+ extras = {str(item).strip() for item in parsed if isinstance(item, str) and str(item).strip()}
897
+ return _DEFAULT_ENV_CREDENTIAL_ALLOWLIST | frozenset(extras)
898
+
899
+
900
+ def _resolve_env_scheme(
901
+ *,
902
+ profile_name: str,
903
+ key: str,
904
+ value: str,
905
+ ) -> str | None:
906
+ """Resolve ``${env:VAR}`` references against the credential allowlist (FR-226.15, NFR-225.12).
907
+
908
+ Returns:
909
+ The resolved env-var value if ``value`` matches the ``${env:VAR}`` scheme AND
910
+ ``VAR`` is allowlisted. Returns ``None`` if the value does not match the scheme
911
+ (caller should fall through to other resolvers).
912
+
913
+ Raises:
914
+ CredentialResolutionError: if the env var is not on the allowlist.
915
+ ValueError: if the env var is allowlisted but unset/empty.
916
+ """
917
+ match = _ENV_SCHEME_PATTERN.match(value)
918
+ if match is None:
919
+ return None
920
+ env_name = match.group(1)
921
+ allowlist = _get_env_credential_allowlist()
922
+ if env_name not in allowlist:
923
+ raise CredentialResolutionError(
924
+ f"Runtime profile '{profile_name}' references env var {env_name!r} via {value!r} for {key}, "
925
+ f"but env var '{env_name}' is not in the credential allowlist. "
926
+ f"Extend via {_ENV_CREDENTIAL_ALLOWLIST_ENV} (JSON array) or use ${{VAR}} for non-credential vars."
927
+ )
928
+ env_value = os.getenv(env_name, "").strip()
929
+ if not env_value:
930
+ raise ValueError(
931
+ f"Runtime profile '{profile_name}' requires environment variable '{env_name}' for {key}, "
932
+ "but it is not set or empty."
933
+ )
934
+ return env_value
935
+
936
+
937
+ def _resolve_env_reference_if_needed(
938
+ *,
939
+ profile_name: str,
940
+ key: str,
941
+ raw_value: Any,
942
+ credential_resolver: CredentialResolver | None = None,
943
+ ) -> Any:
944
+ """Resolve ${env:VAR}, ${ENV_VAR}, and ${codex:<field>} placeholders in profile values."""
945
+ if not isinstance(raw_value, str):
946
+ return raw_value
947
+ value = raw_value.strip()
948
+ if not value:
949
+ return value
950
+ # FR-226.15 + NFR-225.12: ${env:VAR} scheme has highest priority among env-style
951
+ # patterns; takes the credential allowlist gate.
952
+ env_scheme_resolved = _resolve_env_scheme(profile_name=profile_name, key=key, value=value)
953
+ if env_scheme_resolved is not None:
954
+ return env_scheme_resolved
955
+ match = _ENV_REF_PATTERN.match(value)
956
+ if match is not None:
957
+ env_name = match.group(1)
958
+ env_value = os.getenv(env_name, "").strip()
959
+ if not env_value:
960
+ raise ValueError(
961
+ f"Runtime profile '{profile_name}' requires environment variable '{env_name}' for {key}, "
962
+ "but it is not set or empty."
963
+ )
964
+ return env_value
965
+ codex_match = _CODEX_REF_PATTERN.match(value)
966
+ if codex_match is None:
967
+ if value.startswith("${codex:") and value.endswith("}"):
968
+ raise ValueError(
969
+ f"Runtime profile '{profile_name}' has malformed codex reference '{value}' for {key}. "
970
+ "Expected format: ${codex:access_token} | ${codex:account_id} | ${codex:refresh_token}."
971
+ )
972
+ return value
973
+ field_name = codex_match.group(1)
974
+ if field_name not in _CODEX_REF_FIELDS:
975
+ allowed = ", ".join(_CODEX_REF_FIELDS)
976
+ raise ValueError(
977
+ f"Runtime profile '{profile_name}' has invalid codex reference '{value}' for {key}. "
978
+ f"Allowed fields: {allowed}."
979
+ )
980
+ resolver = credential_resolver or _credential_resolver_ctx.get(None)
981
+ if resolver is None:
982
+ raise ValueError(
983
+ f"Runtime profile '{profile_name}' uses codex reference '{value}' for {key}, "
984
+ "but no credential_resolver was provided. Inject a CredentialResolver "
985
+ "via apply_runtime_profile(..., credential_resolver=...) to resolve ${codex:...} references."
986
+ )
987
+ try:
988
+ return resolver.resolve(field_name)
989
+ except Exception as exc:
990
+ raise ValueError(f"Runtime profile '{profile_name}' failed resolving {key} from '{value}': {exc}") from exc
991
+
992
+
993
+ def _validate_required_string(*, profile_name: str, key: str, raw_value: Any) -> str:
994
+ if not isinstance(raw_value, str) or not raw_value.strip():
995
+ raise ValueError(
996
+ f"Runtime profile '{profile_name}' has invalid {key}: {raw_value!r} (expected non-empty string)."
997
+ )
998
+ return _resolve_env_reference_if_needed(profile_name=profile_name, key=key, raw_value=raw_value.strip())
999
+
1000
+
1001
+ def _validate_boolean_policy_value(*, profile_name: str, key: str, raw_value: Any) -> str:
1002
+ if isinstance(raw_value, bool):
1003
+ return "true" if raw_value else "false"
1004
+ if isinstance(raw_value, str):
1005
+ normalized = raw_value.strip().lower()
1006
+ if normalized in {"true", "false"}:
1007
+ return normalized
1008
+ raise ValueError(f"Runtime profile '{profile_name}' has invalid {key}: {raw_value!r} (expected boolean).")
1009
+
1010
+
1011
+ def _validate_optional_boolean_policy_value(
1012
+ *,
1013
+ profile_name: str,
1014
+ key: str,
1015
+ raw_value: Any,
1016
+ default: bool,
1017
+ ) -> bool:
1018
+ if raw_value is None:
1019
+ return default
1020
+ normalized = _validate_boolean_policy_value(profile_name=profile_name, key=key, raw_value=raw_value)
1021
+ return normalized == "true"
1022
+
1023
+
1024
+ def _validate_retry_policy_value(
1025
+ *,
1026
+ profile_name: str,
1027
+ key: str,
1028
+ raw_value: Any,
1029
+ min_value: float,
1030
+ max_value: float,
1031
+ value_type: type[int] | type[float],
1032
+ allow_zero_int: bool = False,
1033
+ ) -> int | float:
1034
+ """Validate scalar policy value from runtime profile and return normalized scalar."""
1035
+ try:
1036
+ coerced = value_type(raw_value)
1037
+ except (TypeError, ValueError) as exc:
1038
+ raise ValueError(
1039
+ f"Runtime profile '{profile_name}' has invalid {key}: {raw_value!r} (expected {value_type.__name__})."
1040
+ ) from exc
1041
+ if allow_zero_int and value_type is int and coerced == 0:
1042
+ return 0
1043
+ if coerced < min_value or coerced > max_value:
1044
+ raise ValueError(
1045
+ f"Runtime profile '{profile_name}' has out-of-range {key}: {coerced} (allowed {min_value}..{max_value})."
1046
+ )
1047
+ return int(coerced) if value_type is int else float(coerced)
1048
+
1049
+
1050
+ def _apply_profile_scalar_policy(
1051
+ *,
1052
+ profile_name: str,
1053
+ policy_name: str,
1054
+ policy_payload: dict[str, Any],
1055
+ env_map: dict[str, str],
1056
+ bounds_map: dict[str, tuple[float, float, type[int] | type[float]]],
1057
+ applied_keys: list[str],
1058
+ force_override: bool,
1059
+ ) -> None:
1060
+ """Validate and apply scalar policy entries from runtime profile."""
1061
+ for key, env_key in env_map.items():
1062
+ if key not in policy_payload:
1063
+ continue
1064
+ raw_value = policy_payload[key]
1065
+ min_value, max_value, value_type = bounds_map[key]
1066
+ validated = _validate_retry_policy_value(
1067
+ profile_name=profile_name,
1068
+ key=f"{policy_name}.{key}",
1069
+ raw_value=raw_value,
1070
+ min_value=min_value,
1071
+ max_value=max_value,
1072
+ value_type=value_type,
1073
+ allow_zero_int=policy_name == "agentic" and key == "tool_calls_limit",
1074
+ )
1075
+ if _set_profile_env(env_key, validated, force_override=force_override):
1076
+ applied_keys.append(env_key)
1077
+
1078
+
1079
+ def _apply_profile_model_policy(
1080
+ *,
1081
+ profile_name: str,
1082
+ model_policy_payload: dict[str, Any],
1083
+ applied_keys: list[str],
1084
+ force_override: bool,
1085
+ maps: _EnvMaps,
1086
+ ) -> None:
1087
+ """Validate and apply structured model policy from runtime profile."""
1088
+ if not model_policy_payload:
1089
+ return
1090
+
1091
+ llm_payload_raw = model_policy_payload.get("llm")
1092
+ if llm_payload_raw is not None and not isinstance(llm_payload_raw, dict):
1093
+ raise ValueError(
1094
+ f"Runtime profile '{profile_name}' has invalid model.llm: {llm_payload_raw!r} (expected object)."
1095
+ )
1096
+ llm_payload = llm_payload_raw if isinstance(llm_payload_raw, dict) else {}
1097
+ allowed_llm_keys = set(maps.model_llm) | {"model", "code_review_max_total_chars"}
1098
+ unknown_llm_keys = set(llm_payload).difference(allowed_llm_keys)
1099
+ if unknown_llm_keys:
1100
+ raise ValueError(
1101
+ f"Runtime profile '{profile_name}' has invalid model.llm keys: {sorted(unknown_llm_keys)!r} "
1102
+ f"(allowed: {', '.join(sorted(allowed_llm_keys))})."
1103
+ )
1104
+ if "type" in llm_payload:
1105
+ protocol = _validate_required_string(
1106
+ profile_name=profile_name,
1107
+ key="model.llm.type",
1108
+ raw_value=llm_payload["type"],
1109
+ ).lower()
1110
+ if protocol not in _SUPPORTED_PROFILE_PROTOCOLS:
1111
+ raise ValueError(
1112
+ f"Runtime profile '{profile_name}' has invalid model.llm.type='{protocol}'. "
1113
+ f"Allowed protocols: {', '.join(_SUPPORTED_PROFILE_PROTOCOLS)}."
1114
+ )
1115
+ if _set_profile_env(maps.model_llm["type"], protocol, force_override=force_override):
1116
+ applied_keys.append(maps.model_llm["type"])
1117
+ if "base_url" in llm_payload:
1118
+ base_url = _validate_required_string(
1119
+ profile_name=profile_name,
1120
+ key="model.llm.base_url",
1121
+ raw_value=llm_payload["base_url"],
1122
+ )
1123
+ if _set_profile_env(maps.model_llm["base_url"], base_url, force_override=force_override):
1124
+ applied_keys.append(maps.model_llm["base_url"])
1125
+ if "api_key" in llm_payload:
1126
+ api_key = _validate_required_string(
1127
+ profile_name=profile_name,
1128
+ key="model.llm.api_key",
1129
+ raw_value=llm_payload["api_key"],
1130
+ )
1131
+ if _set_profile_env(maps.model_llm["api_key"], api_key, force_override=force_override):
1132
+ applied_keys.append(maps.model_llm["api_key"])
1133
+ if "stream" in llm_payload:
1134
+ stream = _validate_boolean_policy_value(
1135
+ profile_name=profile_name,
1136
+ key="model.llm.stream",
1137
+ raw_value=llm_payload["stream"],
1138
+ )
1139
+ if _set_profile_env(maps.model_llm["stream"], stream, force_override=force_override):
1140
+ applied_keys.append(maps.model_llm["stream"])
1141
+ if "agent_stream" in llm_payload:
1142
+ agent_stream = _validate_boolean_policy_value(
1143
+ profile_name=profile_name,
1144
+ key="model.llm.agent_stream",
1145
+ raw_value=llm_payload["agent_stream"],
1146
+ )
1147
+ if _set_profile_env(maps.model_llm["agent_stream"], agent_stream, force_override=force_override):
1148
+ applied_keys.append(maps.model_llm["agent_stream"])
1149
+ if "row_failover_profiles" in llm_payload:
1150
+ raw_profiles = llm_payload["row_failover_profiles"]
1151
+ if isinstance(raw_profiles, str):
1152
+ failover_profiles = [item.strip() for item in raw_profiles.split(",") if item.strip()]
1153
+ elif isinstance(raw_profiles, list):
1154
+ failover_profiles = []
1155
+ for index, item in enumerate(raw_profiles):
1156
+ if not isinstance(item, str) or not item.strip():
1157
+ raise ValueError(
1158
+ f"Runtime profile '{profile_name}' has invalid model.llm.row_failover_profiles[{index}]: "
1159
+ f"{item!r} (expected non-empty string)."
1160
+ )
1161
+ failover_profiles.append(item.strip())
1162
+ else:
1163
+ raise ValueError(
1164
+ f"Runtime profile '{profile_name}' has invalid model.llm.row_failover_profiles: "
1165
+ f"{raw_profiles!r} (expected string or list)."
1166
+ )
1167
+ if _set_profile_env(
1168
+ maps.model_llm["row_failover_profiles"],
1169
+ json.dumps(failover_profiles),
1170
+ force_override=force_override,
1171
+ ):
1172
+ applied_keys.append(maps.model_llm["row_failover_profiles"])
1173
+ if "row_failover_max_provider_hops" in llm_payload:
1174
+ max_provider_hops = _validate_retry_policy_value(
1175
+ profile_name=profile_name,
1176
+ key="model.llm.row_failover_max_provider_hops",
1177
+ raw_value=llm_payload["row_failover_max_provider_hops"],
1178
+ min_value=0,
1179
+ max_value=5,
1180
+ value_type=int,
1181
+ )
1182
+ if _set_profile_env(
1183
+ maps.model_llm["row_failover_max_provider_hops"],
1184
+ max_provider_hops,
1185
+ force_override=force_override,
1186
+ ):
1187
+ applied_keys.append(maps.model_llm["row_failover_max_provider_hops"])
1188
+ if "reasoning_effort" in llm_payload:
1189
+ reasoning_effort = _validate_required_string(
1190
+ profile_name=profile_name,
1191
+ key="model.llm.reasoning_effort",
1192
+ raw_value=llm_payload["reasoning_effort"],
1193
+ ).lower()
1194
+ if reasoning_effort not in _LLM_REASONING_EFFORT_VALUES:
1195
+ raise ValueError(
1196
+ f"Runtime profile '{profile_name}' has invalid model.llm.reasoning_effort={reasoning_effort!r}. "
1197
+ f"Allowed values: {', '.join(_LLM_REASONING_EFFORT_VALUES)}."
1198
+ )
1199
+ if _set_profile_env(maps.model_llm["reasoning_effort"], reasoning_effort, force_override=force_override):
1200
+ applied_keys.append(maps.model_llm["reasoning_effort"])
1201
+ if "model" in llm_payload:
1202
+ model = _validate_required_string(
1203
+ profile_name=profile_name,
1204
+ key="model.llm.model",
1205
+ raw_value=llm_payload["model"],
1206
+ )
1207
+ if "simple" not in llm_payload and _set_profile_env(
1208
+ maps.model_llm["simple"], model, force_override=force_override
1209
+ ):
1210
+ applied_keys.append(maps.model_llm["simple"])
1211
+ if "standard" not in llm_payload and _set_profile_env(
1212
+ maps.model_llm["standard"], model, force_override=force_override
1213
+ ):
1214
+ applied_keys.append(maps.model_llm["standard"])
1215
+ if "complex" not in llm_payload and _set_profile_env(
1216
+ maps.model_llm["complex"], model, force_override=force_override
1217
+ ):
1218
+ applied_keys.append(maps.model_llm["complex"])
1219
+ for tier, env_key in maps.model_llm.items():
1220
+ if tier in {"type", "base_url", "stream", "agent_stream", "reasoning_effort"}:
1221
+ continue
1222
+ if tier not in llm_payload:
1223
+ continue
1224
+ model_value = _validate_required_string(
1225
+ profile_name=profile_name,
1226
+ key=f"model.llm.{tier}",
1227
+ raw_value=llm_payload[tier],
1228
+ )
1229
+ if _set_profile_env(env_key, model_value, force_override=force_override):
1230
+ applied_keys.append(env_key)
1231
+ if "code_review_max_total_chars" in llm_payload:
1232
+ cr_env_key = f"{maps.prefix}LLM__CODE_REVIEW_MAX_TOTAL_CHARS"
1233
+ value = _validate_retry_policy_value(
1234
+ profile_name=profile_name,
1235
+ key="model.llm.code_review_max_total_chars",
1236
+ raw_value=llm_payload["code_review_max_total_chars"],
1237
+ min_value=1000,
1238
+ max_value=500000,
1239
+ value_type=int,
1240
+ )
1241
+ if _set_profile_env(cr_env_key, value, force_override=force_override):
1242
+ applied_keys.append(cr_env_key)
1243
+
1244
+ # DSPy model policy
1245
+ dspy_payload_raw = model_policy_payload.get("dspy")
1246
+ if dspy_payload_raw is not None and not isinstance(dspy_payload_raw, dict):
1247
+ raise ValueError(
1248
+ f"Runtime profile '{profile_name}' has invalid model.dspy: {dspy_payload_raw!r} (expected object)."
1249
+ )
1250
+ dspy_payload = dspy_payload_raw if isinstance(dspy_payload_raw, dict) else {}
1251
+ unknown_dspy_keys = set(dspy_payload).difference(maps.model_dspy)
1252
+ if unknown_dspy_keys:
1253
+ raise ValueError(
1254
+ f"Runtime profile '{profile_name}' has invalid model.dspy keys: {sorted(unknown_dspy_keys)!r} "
1255
+ f"(allowed: {', '.join(maps.model_dspy)})."
1256
+ )
1257
+ if "type" in dspy_payload:
1258
+ protocol = _validate_required_string(
1259
+ profile_name=profile_name,
1260
+ key="model.dspy.type",
1261
+ raw_value=dspy_payload["type"],
1262
+ ).lower()
1263
+ if protocol not in _SUPPORTED_PROFILE_PROTOCOLS:
1264
+ raise ValueError(
1265
+ f"Runtime profile '{profile_name}' has invalid model.dspy.type='{protocol}'. "
1266
+ f"Allowed protocols: {', '.join(_SUPPORTED_PROFILE_PROTOCOLS)}."
1267
+ )
1268
+ if _set_profile_env(maps.model_dspy["type"], protocol, force_override=force_override):
1269
+ applied_keys.append(maps.model_dspy["type"])
1270
+ if "model" in dspy_payload:
1271
+ str_value = _validate_required_string(
1272
+ profile_name=profile_name,
1273
+ key="model.dspy.model",
1274
+ raw_value=dspy_payload["model"],
1275
+ )
1276
+ if _set_profile_env(maps.model_dspy["model"], str_value, force_override=force_override):
1277
+ applied_keys.append(maps.model_dspy["model"])
1278
+ if "api_key" in dspy_payload:
1279
+ str_value = _validate_required_string(
1280
+ profile_name=profile_name,
1281
+ key="model.dspy.api_key",
1282
+ raw_value=dspy_payload["api_key"],
1283
+ )
1284
+ if _set_profile_env(maps.model_dspy["api_key"], str_value, force_override=force_override):
1285
+ applied_keys.append(maps.model_dspy["api_key"])
1286
+ if "max_tokens" in dspy_payload:
1287
+ value = _validate_retry_policy_value(
1288
+ profile_name=profile_name,
1289
+ key="model.dspy.max_tokens",
1290
+ raw_value=dspy_payload["max_tokens"],
1291
+ min_value=1,
1292
+ max_value=200000,
1293
+ value_type=int,
1294
+ )
1295
+ if _set_profile_env(maps.model_dspy["max_tokens"], value, force_override=force_override):
1296
+ applied_keys.append(maps.model_dspy["max_tokens"])
1297
+ if "temperature" in dspy_payload:
1298
+ value = _validate_retry_policy_value(
1299
+ profile_name=profile_name,
1300
+ key="model.dspy.temperature",
1301
+ raw_value=dspy_payload["temperature"],
1302
+ min_value=0.0,
1303
+ max_value=2.0,
1304
+ value_type=float,
1305
+ )
1306
+ if _set_profile_env(maps.model_dspy["temperature"], value, force_override=force_override):
1307
+ applied_keys.append(maps.model_dspy["temperature"])
1308
+ if "base_url" in dspy_payload:
1309
+ str_value = _validate_required_string(
1310
+ profile_name=profile_name,
1311
+ key="model.dspy.base_url",
1312
+ raw_value=dspy_payload["base_url"],
1313
+ )
1314
+ if _set_profile_env(maps.model_dspy["base_url"], str_value, force_override=force_override):
1315
+ applied_keys.append(maps.model_dspy["base_url"])
1316
+ if "system_role_compat" in dspy_payload:
1317
+ bool_str_value = _validate_boolean_policy_value(
1318
+ profile_name=profile_name,
1319
+ key="model.dspy.system_role_compat",
1320
+ raw_value=dspy_payload["system_role_compat"],
1321
+ )
1322
+ encoded = "1" if bool_str_value == "true" else "0"
1323
+ if _set_profile_env(maps.model_dspy["system_role_compat"], encoded, force_override=force_override):
1324
+ applied_keys.append(maps.model_dspy["system_role_compat"])
1325
+
1326
+ # Embedding model policy
1327
+ embedding_payload_raw = model_policy_payload.get("embedding")
1328
+ if embedding_payload_raw is not None and not isinstance(embedding_payload_raw, dict):
1329
+ raise ValueError(
1330
+ f"Runtime profile '{profile_name}' has invalid model.embedding: {embedding_payload_raw!r} "
1331
+ "(expected object)."
1332
+ )
1333
+ embedding_payload = embedding_payload_raw if isinstance(embedding_payload_raw, dict) else {}
1334
+ # FR-226.13 (W3): ``type`` and ``dimension`` are accepted here as forward-compatible
1335
+ # keys for the new embedding-block parser. They are validated in
1336
+ # _apply_profile_embedding_block (under parse_embedding=True); this helper merely
1337
+ # tolerates their presence so legacy callers (parse_embedding=False) don't trip.
1338
+ _W3_TOLERATED_EMBEDDING_KEYS = {
1339
+ "type",
1340
+ "dimension",
1341
+ "model_simple",
1342
+ "model_standard",
1343
+ "model_complex",
1344
+ "fail_open",
1345
+ "cache_ttl_seconds",
1346
+ "timeout_seconds",
1347
+ }
1348
+ legacy_allowed = set(maps.model_embedding) | _W3_TOLERATED_EMBEDDING_KEYS
1349
+ unknown_embedding_keys = set(embedding_payload).difference(legacy_allowed)
1350
+ if unknown_embedding_keys:
1351
+ raise ValueError(
1352
+ f"Runtime profile '{profile_name}' has invalid model.embedding keys: {sorted(unknown_embedding_keys)!r} "
1353
+ f"(allowed: {', '.join(sorted(legacy_allowed))})."
1354
+ )
1355
+ for emb_key in ("base_url", "model", "api_key"):
1356
+ if emb_key in embedding_payload:
1357
+ str_value = _validate_required_string(
1358
+ profile_name=profile_name,
1359
+ key=f"model.embedding.{emb_key}",
1360
+ raw_value=embedding_payload[emb_key],
1361
+ )
1362
+ if _set_profile_env(maps.model_embedding[emb_key], str_value, force_override=force_override):
1363
+ applied_keys.append(maps.model_embedding[emb_key])
1364
+
1365
+
1366
+ def _apply_profile_embedding_block(
1367
+ *,
1368
+ profile_name: str,
1369
+ embedding_payload: dict[str, Any],
1370
+ applied_keys: list[str],
1371
+ force_override: bool,
1372
+ embedding_env_prefix: str,
1373
+ credential_resolver: CodexCredentialResolver | None = None,
1374
+ ) -> None:
1375
+ """Parse the ``model.embedding`` block into ``EmbeddingSettings``-shaped env vars.
1376
+
1377
+ Activated only when ``apply_runtime_profile(..., parse_embedding=True)`` (FR-226.13).
1378
+ Validates ``type`` against the live ``EMBEDDING_PROVIDERS`` registry and
1379
+ projects the rest of the block into ``<embedding_env_prefix>*`` env keys.
1380
+ """
1381
+ # Lazy import: avoids a profiles -> llm.embedding cycle on module load.
1382
+ from vds_agent_core.llm.embedding import EMBEDDING_PROVIDERS
1383
+
1384
+ if "type" in embedding_payload:
1385
+ raw_type = embedding_payload["type"]
1386
+ if not isinstance(raw_type, str) or not raw_type.strip():
1387
+ raise ProfileValidationError(
1388
+ f"Runtime profile '{profile_name}' has invalid model.embedding.type: "
1389
+ f"{raw_type!r} (expected non-empty string)."
1390
+ )
1391
+ type_value = raw_type.strip()
1392
+ if type_value not in EMBEDDING_PROVIDERS:
1393
+ raise ProfileValidationError(
1394
+ f"Unknown embedding type {type_value!r}; registered: {sorted(EMBEDDING_PROVIDERS)}"
1395
+ )
1396
+ env_key = f"{embedding_env_prefix}PROVIDER"
1397
+ if _set_profile_env(env_key, type_value, force_override=force_override):
1398
+ applied_keys.append(env_key)
1399
+
1400
+ str_field_to_env = {
1401
+ "base_url": "BASE_URL",
1402
+ "api_key": "API_KEY",
1403
+ "model": "MODEL_STANDARD",
1404
+ "model_simple": "MODEL_SIMPLE",
1405
+ "model_standard": "MODEL_STANDARD",
1406
+ "model_complex": "MODEL_COMPLEX",
1407
+ }
1408
+ for field_name, env_suffix in str_field_to_env.items():
1409
+ if field_name not in embedding_payload:
1410
+ continue
1411
+ str_value = _validate_required_string(
1412
+ profile_name=profile_name,
1413
+ key=f"model.embedding.{field_name}",
1414
+ raw_value=embedding_payload[field_name],
1415
+ )
1416
+ # api_key may legitimately resolve to a sensitive string via ${env:VAR};
1417
+ # _validate_required_string already routed through credential_resolver.
1418
+ _ = credential_resolver # Silence linters; resolver context is used inside helpers.
1419
+ env_key = f"{embedding_env_prefix}{env_suffix}"
1420
+ if _set_profile_env(env_key, str_value, force_override=force_override):
1421
+ applied_keys.append(env_key)
1422
+
1423
+ if "dimension" in embedding_payload:
1424
+ raw_dim = embedding_payload["dimension"]
1425
+ try:
1426
+ dim_value = int(raw_dim)
1427
+ except (TypeError, ValueError) as exc:
1428
+ raise ProfileValidationError(
1429
+ f"Runtime profile '{profile_name}' has invalid model.embedding.dimension: "
1430
+ f"{raw_dim!r} (expected positive integer)."
1431
+ ) from exc
1432
+ if dim_value <= 0:
1433
+ raise ProfileValidationError(
1434
+ f"Runtime profile '{profile_name}' has invalid model.embedding.dimension: "
1435
+ f"{dim_value} (expected positive integer)."
1436
+ )
1437
+ env_key = f"{embedding_env_prefix}DIMENSION"
1438
+ if _set_profile_env(env_key, str(dim_value), force_override=force_override):
1439
+ applied_keys.append(env_key)
1440
+
1441
+ if "fail_open" in embedding_payload:
1442
+ bool_str = _validate_boolean_policy_value(
1443
+ profile_name=profile_name,
1444
+ key="model.embedding.fail_open",
1445
+ raw_value=embedding_payload["fail_open"],
1446
+ )
1447
+ env_key = f"{embedding_env_prefix}FAIL_OPEN"
1448
+ if _set_profile_env(env_key, bool_str, force_override=force_override):
1449
+ applied_keys.append(env_key)
1450
+
1451
+ if "cache_ttl_seconds" in embedding_payload:
1452
+ raw_ttl = embedding_payload["cache_ttl_seconds"]
1453
+ try:
1454
+ ttl_value = int(raw_ttl)
1455
+ except (TypeError, ValueError) as exc:
1456
+ raise ProfileValidationError(
1457
+ f"Runtime profile '{profile_name}' has invalid model.embedding.cache_ttl_seconds: "
1458
+ f"{raw_ttl!r} (expected non-negative integer)."
1459
+ ) from exc
1460
+ if ttl_value < 0:
1461
+ raise ProfileValidationError(
1462
+ f"Runtime profile '{profile_name}' has invalid model.embedding.cache_ttl_seconds: "
1463
+ f"{ttl_value} (expected non-negative integer)."
1464
+ )
1465
+ env_key = f"{embedding_env_prefix}CACHE_TTL_SECONDS"
1466
+ if _set_profile_env(env_key, str(ttl_value), force_override=force_override):
1467
+ applied_keys.append(env_key)
1468
+
1469
+ if "timeout_seconds" in embedding_payload:
1470
+ raw_timeout = embedding_payload["timeout_seconds"]
1471
+ try:
1472
+ timeout_value = float(raw_timeout)
1473
+ except (TypeError, ValueError) as exc:
1474
+ raise ProfileValidationError(
1475
+ f"Runtime profile '{profile_name}' has invalid model.embedding.timeout_seconds: "
1476
+ f"{raw_timeout!r} (expected positive float)."
1477
+ ) from exc
1478
+ if timeout_value <= 0:
1479
+ raise ProfileValidationError(
1480
+ f"Runtime profile '{profile_name}' has invalid model.embedding.timeout_seconds: "
1481
+ f"{timeout_value} (expected positive float)."
1482
+ )
1483
+ env_key = f"{embedding_env_prefix}TIMEOUT_SECONDS"
1484
+ if _set_profile_env(env_key, str(timeout_value), force_override=force_override):
1485
+ applied_keys.append(env_key)
1486
+
1487
+
1488
+ def _maybe_log_embedding_resolution(profile_name: str) -> None:
1489
+ """Emit one-shot ``profile_embedding_resolved`` INFO log per profile (NFR-226.1).
1490
+
1491
+ BLOCKER-1 (W6 v20.6.1 fix): the ``logger.info`` MUST sit inside the lock —
1492
+ otherwise two threads passing the ``add()`` can both emit the log before
1493
+ the first ``return``. Mirrors the lock-emit pattern in
1494
+ ``_cascade.py::_log_resolution_once``.
1495
+ """
1496
+ if os.environ.get("VDS_AGENT_CORE__LOG_RESOLUTION", "").lower() != "true":
1497
+ return
1498
+ with _EMBEDDING_PROFILE_RESOLUTION_LOCK:
1499
+ if profile_name in _EMBEDDING_PROFILE_RESOLUTION_SEEN:
1500
+ return
1501
+ _EMBEDDING_PROFILE_RESOLUTION_SEEN.add(profile_name)
1502
+ logger.info("profile_embedding_resolved", profile_name=profile_name)
1503
+
1504
+
1505
+ def _reset_embedding_resolution_log() -> None:
1506
+ """Test helper: clear the one-shot embedding-resolution log set."""
1507
+ with _EMBEDDING_PROFILE_RESOLUTION_LOCK:
1508
+ _EMBEDDING_PROFILE_RESOLUTION_SEEN.clear()
1509
+
1510
+
1511
+ def _apply_profile_skill_policy(
1512
+ *,
1513
+ profile_name: str,
1514
+ skill_policy_payload: dict[str, Any],
1515
+ applied_keys: list[str],
1516
+ force_override: bool,
1517
+ maps: _EnvMaps,
1518
+ ) -> None:
1519
+ """Validate and apply skill_policy entries from runtime profile."""
1520
+ if "enabled" in skill_policy_payload:
1521
+ env_key = maps.skill["enabled"]
1522
+ value = _validate_boolean_policy_value(
1523
+ profile_name=profile_name,
1524
+ key="skill_policy.enabled",
1525
+ raw_value=skill_policy_payload["enabled"],
1526
+ )
1527
+ if _set_profile_env(env_key, value, force_override=force_override):
1528
+ applied_keys.append(env_key)
1529
+ if "directories" in skill_policy_payload:
1530
+ env_key = maps.skill["directories"]
1531
+ directories = _validate_skill_directory_list(
1532
+ profile_name=profile_name,
1533
+ key="skill_policy.directories",
1534
+ raw_value=skill_policy_payload["directories"],
1535
+ )
1536
+ if _set_profile_env(env_key, json.dumps(directories), force_override=force_override):
1537
+ applied_keys.append(env_key)
1538
+ if "allow_script_execution" in skill_policy_payload:
1539
+ env_key = maps.skill["allow_script_execution"]
1540
+ value = _validate_boolean_policy_value(
1541
+ profile_name=profile_name,
1542
+ key="skill_policy.allow_script_execution",
1543
+ raw_value=skill_policy_payload["allow_script_execution"],
1544
+ )
1545
+ if _set_profile_env(env_key, value, force_override=force_override):
1546
+ applied_keys.append(env_key)
1547
+ if "default_trust_tier" in skill_policy_payload:
1548
+ env_key = maps.skill["default_trust_tier"]
1549
+ value = _validate_skill_trust_tier(
1550
+ profile_name=profile_name,
1551
+ key="skill_policy.default_trust_tier",
1552
+ raw_value=skill_policy_payload["default_trust_tier"],
1553
+ )
1554
+ if _set_profile_env(env_key, value, force_override=force_override):
1555
+ applied_keys.append(env_key)
1556
+ if "allowed_trust_tiers" in skill_policy_payload:
1557
+ env_key = maps.skill["allowed_trust_tiers"]
1558
+ tiers = _validate_skill_trust_tier_list(
1559
+ profile_name=profile_name,
1560
+ key="skill_policy.allowed_trust_tiers",
1561
+ raw_value=skill_policy_payload["allowed_trust_tiers"],
1562
+ )
1563
+ if _set_profile_env(env_key, json.dumps(tiers), force_override=force_override):
1564
+ applied_keys.append(env_key)
1565
+ if "allowlist" in skill_policy_payload:
1566
+ env_key = maps.skill["allowlist"]
1567
+ allowlist = _validate_skill_name_list(
1568
+ profile_name=profile_name,
1569
+ key="skill_policy.allowlist",
1570
+ raw_value=skill_policy_payload["allowlist"],
1571
+ )
1572
+ if _set_profile_env(env_key, json.dumps(allowlist), force_override=force_override):
1573
+ applied_keys.append(env_key)
1574
+ if "trust_tiers" in skill_policy_payload:
1575
+ env_key = maps.skill["trust_tiers"]
1576
+ trust_tiers = _validate_skill_trust_tier_map(
1577
+ profile_name=profile_name,
1578
+ key="skill_policy.trust_tiers",
1579
+ raw_value=skill_policy_payload["trust_tiers"],
1580
+ )
1581
+ if _set_profile_env(env_key, json.dumps(trust_tiers), force_override=force_override):
1582
+ applied_keys.append(env_key)
1583
+ if "strict_require_effective_skill" in skill_policy_payload:
1584
+ env_key = maps.skill["strict_require_effective_skill"]
1585
+ value = _validate_boolean_policy_value(
1586
+ profile_name=profile_name,
1587
+ key="skill_policy.strict_require_effective_skill",
1588
+ raw_value=skill_policy_payload["strict_require_effective_skill"],
1589
+ )
1590
+ if _set_profile_env(env_key, value, force_override=force_override):
1591
+ applied_keys.append(env_key)
1592
+
1593
+
1594
+ def _validate_skill_trust_tier(*, profile_name: str, key: str, raw_value: Any) -> str:
1595
+ if not isinstance(raw_value, str):
1596
+ raise ValueError(
1597
+ f"Runtime profile '{profile_name}' has invalid {key}: {raw_value!r} (expected trust-tier string)."
1598
+ )
1599
+ value = raw_value.strip()
1600
+ if value not in _SKILL_TRUST_TIERS:
1601
+ raise ValueError(
1602
+ f"Runtime profile '{profile_name}' has invalid {key}: {raw_value!r} "
1603
+ f"(allowed: {', '.join(_SKILL_TRUST_TIERS)})."
1604
+ )
1605
+ return value
1606
+
1607
+
1608
+ def _validate_skill_trust_tier_list(*, profile_name: str, key: str, raw_value: Any) -> list[str]:
1609
+ if not isinstance(raw_value, list):
1610
+ raise ValueError(f"Runtime profile '{profile_name}' has invalid {key}: {raw_value!r} (expected list).")
1611
+ if not raw_value:
1612
+ raise ValueError(f"Runtime profile '{profile_name}' has invalid {key}: list cannot be empty.")
1613
+ if len(raw_value) > _SKILL_POLICY_MAX_LIST_ITEMS:
1614
+ raise ValueError(
1615
+ f"Runtime profile '{profile_name}' has invalid {key}: too many entries "
1616
+ f"(max {_SKILL_POLICY_MAX_LIST_ITEMS})."
1617
+ )
1618
+ validated: list[str] = []
1619
+ for index, item in enumerate(raw_value):
1620
+ validated.append(_validate_skill_trust_tier(profile_name=profile_name, key=f"{key}[{index}]", raw_value=item))
1621
+ return list(dict.fromkeys(validated))
1622
+
1623
+
1624
+ def _validate_skill_name_list(*, profile_name: str, key: str, raw_value: Any) -> list[str]:
1625
+ if not isinstance(raw_value, list):
1626
+ raise ValueError(f"Runtime profile '{profile_name}' has invalid {key}: {raw_value!r} (expected list).")
1627
+ if len(raw_value) > _SKILL_POLICY_MAX_LIST_ITEMS:
1628
+ raise ValueError(
1629
+ f"Runtime profile '{profile_name}' has invalid {key}: too many entries "
1630
+ f"(max {_SKILL_POLICY_MAX_LIST_ITEMS})."
1631
+ )
1632
+ validated: list[str] = []
1633
+ for index, item in enumerate(raw_value):
1634
+ if not isinstance(item, str) or not item.strip():
1635
+ raise ValueError(
1636
+ f"Runtime profile '{profile_name}' has invalid {key}[{index}]: {item!r} (expected non-empty string)."
1637
+ )
1638
+ validated.append(item.strip())
1639
+ return validated
1640
+
1641
+
1642
+ def _validate_skill_directory_list(*, profile_name: str, key: str, raw_value: Any) -> list[str]:
1643
+ if not isinstance(raw_value, list):
1644
+ raise ValueError(f"Runtime profile '{profile_name}' has invalid {key}: {raw_value!r} (expected list).")
1645
+ if not raw_value:
1646
+ raise ValueError(f"Runtime profile '{profile_name}' has invalid {key}: list cannot be empty.")
1647
+ if len(raw_value) > _SKILL_POLICY_MAX_LIST_ITEMS:
1648
+ raise ValueError(
1649
+ f"Runtime profile '{profile_name}' has invalid {key}: too many entries "
1650
+ f"(max {_SKILL_POLICY_MAX_LIST_ITEMS})."
1651
+ )
1652
+ validated: list[str] = []
1653
+ for index, item in enumerate(raw_value):
1654
+ if not isinstance(item, str) or not item.strip():
1655
+ raise ValueError(
1656
+ f"Runtime profile '{profile_name}' has invalid {key}[{index}]: {item!r} (expected non-empty string)."
1657
+ )
1658
+ resolved = resolve_skill_directory_path(item.strip())
1659
+ validated.append(str(resolved))
1660
+ return validated
1661
+
1662
+
1663
+ def _validate_skill_trust_tier_map(*, profile_name: str, key: str, raw_value: Any) -> dict[str, str]:
1664
+ if not isinstance(raw_value, dict):
1665
+ raise ValueError(f"Runtime profile '{profile_name}' has invalid {key}: {raw_value!r} (expected object map).")
1666
+ if len(raw_value) > _SKILL_POLICY_MAX_MAP_ITEMS:
1667
+ raise ValueError(
1668
+ f"Runtime profile '{profile_name}' has invalid {key}: too many entries (max {_SKILL_POLICY_MAX_MAP_ITEMS})."
1669
+ )
1670
+ validated: dict[str, str] = {}
1671
+ for skill_name, tier in raw_value.items():
1672
+ if not isinstance(skill_name, str) or not skill_name.strip():
1673
+ raise ValueError(
1674
+ f"Runtime profile '{profile_name}' has invalid {key} key: {skill_name!r} (expected non-empty string)."
1675
+ )
1676
+ normalized_name = skill_name.strip()
1677
+ validated[normalized_name] = _validate_skill_trust_tier(
1678
+ profile_name=profile_name,
1679
+ key=f"{key}.{normalized_name}",
1680
+ raw_value=tier,
1681
+ )
1682
+ return validated
1683
+
1684
+
1685
+ def _apply_profile_backend_policy(
1686
+ *,
1687
+ profile_name: str,
1688
+ backend_policy_payload: dict[str, Any],
1689
+ applied_keys: list[str],
1690
+ force_override: bool,
1691
+ maps: _EnvMaps,
1692
+ ) -> None:
1693
+ """Validate and apply backend_policy entries from runtime profile."""
1694
+ if not backend_policy_payload:
1695
+ return
1696
+ backend = _validate_row_backend_value(
1697
+ profile_name=profile_name,
1698
+ key="backend_policy.backend",
1699
+ raw_value=backend_policy_payload.get("backend"),
1700
+ )
1701
+ locked = _validate_optional_boolean_policy_value(
1702
+ profile_name=profile_name,
1703
+ key="backend_policy.locked",
1704
+ raw_value=backend_policy_payload.get("locked"),
1705
+ default=False,
1706
+ )
1707
+ allow_override = _validate_optional_boolean_policy_value(
1708
+ profile_name=profile_name,
1709
+ key="backend_policy.allow_override",
1710
+ raw_value=backend_policy_payload.get("allow_override"),
1711
+ default=False,
1712
+ )
1713
+ if locked and allow_override:
1714
+ raise ValueError(
1715
+ f"Runtime profile '{profile_name}' has invalid backend_policy: "
1716
+ "locked=true cannot be combined with allow_override=true."
1717
+ )
1718
+ override_request_raw = os.getenv(maps.row_backend_override_env, "")
1719
+ override_request = override_request_raw.strip() if isinstance(override_request_raw, str) else ""
1720
+ effective_backend = backend
1721
+ backend_source = "profile"
1722
+ if override_request:
1723
+ override_backend = _validate_row_backend_value(
1724
+ profile_name=profile_name,
1725
+ key=f"env.{maps.row_backend_override_env}",
1726
+ raw_value=override_request,
1727
+ )
1728
+ if locked:
1729
+ raise ValueError(
1730
+ f"Runtime profile '{profile_name}' rejected {maps.row_backend_override_env}: backend policy is locked."
1731
+ )
1732
+ if not allow_override:
1733
+ raise ValueError(
1734
+ f"Runtime profile '{profile_name}' rejected {maps.row_backend_override_env}: "
1735
+ "backend override is disabled by policy."
1736
+ )
1737
+ effective_backend = override_backend
1738
+ backend_source = "override_request"
1739
+ if _set_profile_env(maps.row_backend["backend"], effective_backend, force_override=force_override):
1740
+ applied_keys.append(maps.row_backend["backend"])
1741
+ if _set_profile_env(maps.row_backend["source"], backend_source, force_override=force_override):
1742
+ applied_keys.append(maps.row_backend["source"])
1743
+ if _set_profile_env(maps.row_backend["locked"], "true" if locked else "false", force_override=force_override):
1744
+ applied_keys.append(maps.row_backend["locked"])
1745
+ if _set_profile_env(
1746
+ maps.row_backend["allow_override"],
1747
+ "true" if allow_override else "false",
1748
+ force_override=force_override,
1749
+ ):
1750
+ applied_keys.append(maps.row_backend["allow_override"])
1751
+
1752
+
1753
+ def _validate_row_backend_value(*, profile_name: str, key: str, raw_value: Any) -> str:
1754
+ if not isinstance(raw_value, str):
1755
+ raise ValueError(
1756
+ f"Runtime profile '{profile_name}' has invalid {key}: {raw_value!r} (expected backend string)."
1757
+ )
1758
+ backend = raw_value.strip()
1759
+ if backend not in _ROW_EVALUATION_BACKENDS:
1760
+ raise ValueError(
1761
+ f"Runtime profile '{profile_name}' has invalid {key}: {raw_value!r} "
1762
+ f"(allowed: {', '.join(_ROW_EVALUATION_BACKENDS)})."
1763
+ )
1764
+ return backend
1765
+
1766
+
1767
+ def _apply_profile_agent_runtime_policy(
1768
+ *,
1769
+ profile_name: str,
1770
+ agent_runtime_policy_payload: dict[str, Any],
1771
+ applied_keys: list[str],
1772
+ force_override: bool,
1773
+ maps: _EnvMaps,
1774
+ ) -> None:
1775
+ """Validate and apply agent runtime policy from runtime profile."""
1776
+ if not agent_runtime_policy_payload:
1777
+ return
1778
+ runtime_mode = _validate_agent_runtime_mode(
1779
+ profile_name=profile_name,
1780
+ key="agent_runtime_policy.mode",
1781
+ raw_value=agent_runtime_policy_payload.get("mode"),
1782
+ )
1783
+ if _set_profile_env(maps.agent_runtime_mode_env, runtime_mode, force_override=force_override):
1784
+ applied_keys.append(maps.agent_runtime_mode_env)
1785
+ if "tool_allowlists" in agent_runtime_policy_payload:
1786
+ tool_allowlists = _validate_agent_tool_allowlists(
1787
+ profile_name=profile_name,
1788
+ key="agent_runtime_policy.tool_allowlists",
1789
+ raw_value=agent_runtime_policy_payload["tool_allowlists"],
1790
+ )
1791
+ env_key = maps.agent_runtime["tool_allowlists"]
1792
+ if _set_profile_env(env_key, json.dumps(tool_allowlists), force_override=force_override):
1793
+ applied_keys.append(env_key)
1794
+ if "non_progress_policy" in agent_runtime_policy_payload:
1795
+ non_progress_policy = _validate_agent_non_progress_policy_payload(
1796
+ profile_name=profile_name,
1797
+ key="agent_runtime_policy.non_progress_policy",
1798
+ raw_value=agent_runtime_policy_payload["non_progress_policy"],
1799
+ )
1800
+ env_key = maps.agent_runtime["non_progress_policy"]
1801
+ if _set_profile_env(env_key, json.dumps(non_progress_policy), force_override=force_override):
1802
+ applied_keys.append(env_key)
1803
+
1804
+
1805
+ def _validate_agent_runtime_mode(*, profile_name: str, key: str, raw_value: Any) -> str:
1806
+ if not isinstance(raw_value, str):
1807
+ raise ValueError(
1808
+ f"Runtime profile '{profile_name}' has invalid {key}: {raw_value!r} (expected runtime mode string)."
1809
+ )
1810
+ mode = raw_value.strip()
1811
+ if mode not in _AGENT_RUNTIME_MODES:
1812
+ raise ValueError(
1813
+ f"Runtime profile '{profile_name}' has invalid {key}: {raw_value!r} "
1814
+ f"(allowed: {', '.join(_AGENT_RUNTIME_MODES)})."
1815
+ )
1816
+ return mode
1817
+
1818
+
1819
+ def _validate_agent_tool_allowlists(*, profile_name: str, key: str, raw_value: Any) -> dict[str, list[str]]:
1820
+ if not isinstance(raw_value, dict):
1821
+ raise ValueError(f"Runtime profile '{profile_name}' has invalid {key}: {raw_value!r} (expected object map).")
1822
+ validated: dict[str, list[str]] = {}
1823
+ for agent_name, tools in raw_value.items():
1824
+ if not isinstance(agent_name, str) or not agent_name.strip():
1825
+ raise ValueError(
1826
+ f"Runtime profile '{profile_name}' has invalid {key} key: {agent_name!r} (expected non-empty string)."
1827
+ )
1828
+ if not isinstance(tools, list):
1829
+ raise ValueError(
1830
+ f"Runtime profile '{profile_name}' has invalid {key}.{agent_name}: {tools!r} (expected list)."
1831
+ )
1832
+ normalized_tools: list[str] = []
1833
+ for index, tool_name in enumerate(tools):
1834
+ if not isinstance(tool_name, str) or not tool_name.strip():
1835
+ raise ValueError(
1836
+ f"Runtime profile '{profile_name}' has invalid {key}.{agent_name}[{index}]: "
1837
+ f"{tool_name!r} (expected non-empty string)."
1838
+ )
1839
+ normalized = tool_name.strip()
1840
+ if normalized not in normalized_tools:
1841
+ normalized_tools.append(normalized)
1842
+ validated[agent_name.strip().lower()] = normalized_tools
1843
+ return validated
1844
+
1845
+
1846
+ def _validate_agent_non_progress_policy_payload(*, profile_name: str, key: str, raw_value: Any) -> dict[str, Any]:
1847
+ if not isinstance(raw_value, dict):
1848
+ raise ValueError(f"Runtime profile '{profile_name}' has invalid {key}: {raw_value!r} (expected object).")
1849
+ return raw_value
1850
+
1851
+
1852
+ def _apply_profile_agentic_policy(
1853
+ *,
1854
+ profile_name: str,
1855
+ agentic_payload: dict[str, Any],
1856
+ applied_keys: list[str],
1857
+ force_override: bool,
1858
+ maps: _EnvMaps,
1859
+ ) -> None:
1860
+ """Validate and apply profile-level agentic policy payload."""
1861
+ if not agentic_payload:
1862
+ return
1863
+ if "non_progress_preset" in agentic_payload:
1864
+ value = _validate_non_progress_preset(
1865
+ profile_name=profile_name,
1866
+ key="agentic.non_progress_preset",
1867
+ raw_value=agentic_payload["non_progress_preset"],
1868
+ )
1869
+ env_key = maps.agentic["non_progress_preset"]
1870
+ if _set_profile_env(env_key, value, force_override=force_override):
1871
+ applied_keys.append(env_key)
1872
+ if "strict_no_fallback" in agentic_payload:
1873
+ value = _validate_boolean_policy_value(
1874
+ profile_name=profile_name,
1875
+ key="agentic.strict_no_fallback",
1876
+ raw_value=agentic_payload["strict_no_fallback"],
1877
+ )
1878
+ env_key = maps.agentic["strict_no_fallback"]
1879
+ if _set_profile_env(env_key, value, force_override=force_override):
1880
+ applied_keys.append(env_key)
1881
+ _apply_profile_scalar_policy(
1882
+ profile_name=profile_name,
1883
+ policy_name="agentic",
1884
+ policy_payload=agentic_payload,
1885
+ env_map=maps.agentic_tool_first,
1886
+ bounds_map=_AGENTIC_TOOL_FIRST_BOUNDS,
1887
+ applied_keys=applied_keys,
1888
+ force_override=force_override,
1889
+ )
1890
+
1891
+
1892
+ def _validate_non_progress_preset(*, profile_name: str, key: str, raw_value: Any) -> str:
1893
+ if not isinstance(raw_value, str):
1894
+ raise ValueError(f"Runtime profile '{profile_name}' has invalid {key}: {raw_value!r} (expected preset string).")
1895
+ preset = raw_value.strip().lower()
1896
+ if preset not in _NON_PROGRESS_PRESETS:
1897
+ raise ValueError(
1898
+ f"Runtime profile '{profile_name}' has invalid {key}: {raw_value!r} "
1899
+ f"(allowed: {', '.join(_NON_PROGRESS_PRESETS)})."
1900
+ )
1901
+ return preset
1902
+
1903
+
1904
+ def _auto_derive_dspy_config(
1905
+ *,
1906
+ profile_name: str,
1907
+ applied_keys: list[str],
1908
+ force_override: bool,
1909
+ maps: _EnvMaps,
1910
+ ) -> None:
1911
+ """Auto-derive DSPy runtime config from active protocol/model when not explicit."""
1912
+ llm_protocol = (os.getenv(maps.model_llm["type"]) or "").strip().lower()
1913
+ if llm_protocol and llm_protocol not in _SUPPORTED_PROFILE_PROTOCOLS:
1914
+ raise ValueError(
1915
+ f"Runtime profile '{profile_name}' has unsupported {maps.model_llm['type']}='{llm_protocol}'. "
1916
+ f"Allowed protocols: {', '.join(_SUPPORTED_PROFILE_PROTOCOLS)}."
1917
+ )
1918
+ dspy_protocol = (os.getenv(maps.model_dspy["type"]) or "").strip().lower()
1919
+ if dspy_protocol and dspy_protocol not in _SUPPORTED_PROFILE_PROTOCOLS:
1920
+ raise ValueError(
1921
+ f"Runtime profile '{profile_name}' has unsupported {maps.model_dspy['type']}='{dspy_protocol}'. "
1922
+ f"Allowed protocols: {', '.join(_SUPPORTED_PROFILE_PROTOCOLS)}."
1923
+ )
1924
+ protocol = dspy_protocol or llm_protocol
1925
+ split_protocol_active = bool(dspy_protocol and llm_protocol and dspy_protocol != llm_protocol)
1926
+
1927
+ dspy_model = (os.getenv(maps.model_dspy["model"]) or "").strip()
1928
+ llm_standard = (os.getenv(maps.model_llm["standard"]) or "").strip()
1929
+ if not split_protocol_active and not dspy_model and protocol and llm_standard:
1930
+ derived_model = _derive_dspy_model(protocol=protocol, llm_model_standard=llm_standard)
1931
+ if _set_profile_env(maps.model_dspy["model"], derived_model, force_override=force_override):
1932
+ applied_keys.append(maps.model_dspy["model"])
1933
+ dspy_base = (os.getenv(maps.model_dspy["base_url"]) or "").strip()
1934
+ llm_base = (os.getenv(maps.model_llm["base_url"]) or "").strip()
1935
+ if not split_protocol_active and not dspy_base and llm_base and _set_profile_env(maps.model_dspy["base_url"], llm_base, force_override=force_override):
1936
+ applied_keys.append(maps.model_dspy["base_url"])
1937
+
1938
+
1939
+ def _derive_dspy_model(*, protocol: str, llm_model_standard: str) -> str:
1940
+ model = llm_model_standard.strip()
1941
+ if not model:
1942
+ return ""
1943
+ expected_prefix = _resolve_dspy_expected_prefix(protocol=protocol)
1944
+ if expected_prefix == "gemini":
1945
+ if model.startswith("google/"):
1946
+ return f"gemini/{model.split('/', 1)[1]}"
1947
+ if model.startswith("gemini/"):
1948
+ return model
1949
+ if "/" not in model:
1950
+ return f"gemini/{model}"
1951
+ return model
1952
+ if "/" in model:
1953
+ return model
1954
+ return f"{expected_prefix}/{model}"
1955
+
1956
+
1957
+ def _resolve_dspy_expected_prefix(*, protocol: str) -> str:
1958
+ if protocol == "openai-codex":
1959
+ return "openai"
1960
+ if protocol == "gemini":
1961
+ return "gemini"
1962
+ return protocol
1963
+
1964
+
1965
+ def _validate_dspy_coherence(*, profile_name: str, maps: _EnvMaps) -> None:
1966
+ """Fail fast when DSPy protocol/model pairing is incoherent."""
1967
+ protocol = (
1968
+ (os.getenv(maps.model_dspy["type"]) or "").strip() or (os.getenv(maps.model_llm["type"]) or "").strip()
1969
+ ).lower()
1970
+ dspy_model = (os.getenv(maps.model_dspy["model"]) or "").strip()
1971
+ if not protocol or not dspy_model:
1972
+ return
1973
+ if protocol not in _SUPPORTED_PROFILE_PROTOCOLS:
1974
+ return
1975
+ model_prefix = dspy_model.split("/", 1)[0].lower() if "/" in dspy_model else ""
1976
+ normalized_prefix = "gemini" if model_prefix == "google" else model_prefix
1977
+ expected_prefix = _resolve_dspy_expected_prefix(protocol=protocol)
1978
+ if model_prefix and protocol != "openai" and normalized_prefix != expected_prefix:
1979
+ raise ValueError(
1980
+ f"Runtime profile '{profile_name}' has incoherent DSPy model/protocol pairing: "
1981
+ f"protocol='{protocol}' but {maps.model_dspy['model']}='{dspy_model}'. "
1982
+ f"Expected model prefix '{expected_prefix}/...' or no prefix."
1983
+ )
1984
+ lowered_model = dspy_model.lower()
1985
+ if not model_prefix and protocol != "anthropic" and lowered_model.startswith("claude-"):
1986
+ raise ValueError(
1987
+ f"Runtime profile '{profile_name}' has incoherent DSPy model/protocol pairing: "
1988
+ f"protocol='{protocol}' cannot use Anthropic-only model '{dspy_model}'."
1989
+ )
1990
+ if not model_prefix and protocol != "gemini" and lowered_model.startswith("gemini"):
1991
+ raise ValueError(
1992
+ f"Runtime profile '{profile_name}' has incoherent DSPy model/protocol pairing: "
1993
+ f"protocol='{protocol}' cannot use Google Gemini model '{dspy_model}'."
1994
+ )
1995
+
1996
+
1997
+ def _apply_codex_chatgpt_baseline_defaults(
1998
+ *,
1999
+ profile_name: str,
2000
+ applied_keys: list[str],
2001
+ env_prefix: str,
2002
+ ) -> None:
2003
+ """Apply deterministic codex baseline defaults for subscription provider runs."""
2004
+ if profile_name != _CODEX_CHATGPT_PROFILE_NAME:
2005
+ return
2006
+ protocol_env = f"{env_prefix}LLM_PROTOCOL"
2007
+ protocol = str(os.getenv(protocol_env) or "").strip().lower()
2008
+ if protocol != "openai-codex":
2009
+ return
2010
+ defaults = _CODEX_CHATGPT_BASELINE_ENV_DEFAULTS
2011
+ if env_prefix != "VDS_AUDIT_":
2012
+ defaults = {k.replace("VDS_AUDIT_", env_prefix): v for k, v in defaults.items()}
2013
+ for env_key, value in defaults.items():
2014
+ if _set_profile_env(env_key, value, force_override=False):
2015
+ applied_keys.append(env_key)