onto-mcp 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.onto/authority/core-lens-registry.yaml +134 -0
- package/.onto/authority/core-lexicon.yaml +1562 -0
- package/.onto/authority/diagnostic-codes.yaml +94 -0
- package/.onto/domains/accounting/competency_qs.md +384 -0
- package/.onto/domains/accounting/concepts.md +186 -0
- package/.onto/domains/accounting/conciseness_rules.md +160 -0
- package/.onto/domains/accounting/dependency_rules.md +239 -0
- package/.onto/domains/accounting/domain_scope.md +213 -0
- package/.onto/domains/accounting/extension_cases.md +416 -0
- package/.onto/domains/accounting/logic_rules.md +226 -0
- package/.onto/domains/accounting/structure_spec.md +298 -0
- package/.onto/domains/accounting-kr/competency_qs.md +562 -0
- package/.onto/domains/accounting-kr/concepts.md +187 -0
- package/.onto/domains/accounting-kr/conciseness_rules.md +125 -0
- package/.onto/domains/accounting-kr/dependency_rules.md +93 -0
- package/.onto/domains/accounting-kr/domain_scope.md +140 -0
- package/.onto/domains/accounting-kr/extension_cases.md +343 -0
- package/.onto/domains/accounting-kr/logic_rules.md +160 -0
- package/.onto/domains/accounting-kr/structure_spec.md +85 -0
- package/.onto/domains/business/competency_qs.md +263 -0
- package/.onto/domains/business/concepts.md +200 -0
- package/.onto/domains/business/conciseness_rules.md +135 -0
- package/.onto/domains/business/dependency_rules.md +113 -0
- package/.onto/domains/business/domain_scope.md +240 -0
- package/.onto/domains/business/extension_cases.md +249 -0
- package/.onto/domains/business/logic_rules.md +134 -0
- package/.onto/domains/business/structure_spec.md +114 -0
- package/.onto/domains/finance/competency_qs.md +362 -0
- package/.onto/domains/finance/concepts.md +194 -0
- package/.onto/domains/finance/conciseness_rules.md +155 -0
- package/.onto/domains/finance/dependency_rules.md +171 -0
- package/.onto/domains/finance/domain_scope.md +215 -0
- package/.onto/domains/finance/extension_cases.md +350 -0
- package/.onto/domains/finance/logic_rules.md +191 -0
- package/.onto/domains/finance/structure_spec.md +182 -0
- package/.onto/domains/llm-native-development/competency_qs.md +430 -0
- package/.onto/domains/llm-native-development/concepts.md +242 -0
- package/.onto/domains/llm-native-development/conciseness_rules.md +163 -0
- package/.onto/domains/llm-native-development/dependency_rules.md +216 -0
- package/.onto/domains/llm-native-development/domain_scope.md +197 -0
- package/.onto/domains/llm-native-development/extension_cases.md +474 -0
- package/.onto/domains/llm-native-development/logic_rules.md +123 -0
- package/.onto/domains/llm-native-development/prompt_interface.md +49 -0
- package/.onto/domains/llm-native-development/structure_spec.md +245 -0
- package/.onto/domains/market-intelligence/competency_qs.md +274 -0
- package/.onto/domains/market-intelligence/concepts.md +233 -0
- package/.onto/domains/market-intelligence/conciseness_rules.md +165 -0
- package/.onto/domains/market-intelligence/dependency_rules.md +197 -0
- package/.onto/domains/market-intelligence/domain_scope.md +231 -0
- package/.onto/domains/market-intelligence/extension_cases.md +425 -0
- package/.onto/domains/market-intelligence/logic_rules.md +247 -0
- package/.onto/domains/market-intelligence/structure_spec.md +209 -0
- package/.onto/domains/ontology/competency_qs.md +394 -0
- package/.onto/domains/ontology/concepts.md +172 -0
- package/.onto/domains/ontology/conciseness_rules.md +134 -0
- package/.onto/domains/ontology/dependency_rules.md +125 -0
- package/.onto/domains/ontology/domain_scope.md +114 -0
- package/.onto/domains/ontology/extension_cases.md +501 -0
- package/.onto/domains/ontology/logic_rules.md +114 -0
- package/.onto/domains/ontology/problem_framing_profile.md +67 -0
- package/.onto/domains/ontology/structure_spec.md +115 -0
- package/.onto/domains/palantir-foundry/RESEARCH_NOTES.md +911 -0
- package/.onto/domains/palantir-foundry/competency_qs.md +191 -0
- package/.onto/domains/palantir-foundry/competitive_comparison.md +329 -0
- package/.onto/domains/palantir-foundry/concepts.md +197 -0
- package/.onto/domains/palantir-foundry/conciseness_rules.md +245 -0
- package/.onto/domains/palantir-foundry/dependency_rules.md +135 -0
- package/.onto/domains/palantir-foundry/domain_scope.md +395 -0
- package/.onto/domains/palantir-foundry/extension_cases.md +210 -0
- package/.onto/domains/palantir-foundry/logic_rules.md +172 -0
- package/.onto/domains/palantir-foundry/structure_spec.md +291 -0
- package/.onto/domains/software-engineering/competency_qs.md +538 -0
- package/.onto/domains/software-engineering/concepts.md +238 -0
- package/.onto/domains/software-engineering/conciseness_rules.md +167 -0
- package/.onto/domains/software-engineering/dependency_rules.md +216 -0
- package/.onto/domains/software-engineering/domain_scope.md +183 -0
- package/.onto/domains/software-engineering/extension_cases.md +551 -0
- package/.onto/domains/software-engineering/logic_rules.md +240 -0
- package/.onto/domains/software-engineering/problem_framing_profile.md +68 -0
- package/.onto/domains/software-engineering/structure_spec.md +185 -0
- package/.onto/domains/ui-design/competency_qs.md +567 -0
- package/.onto/domains/ui-design/concepts.md +194 -0
- package/.onto/domains/ui-design/conciseness_rules.md +190 -0
- package/.onto/domains/ui-design/dependency_rules.md +323 -0
- package/.onto/domains/ui-design/domain_scope.md +340 -0
- package/.onto/domains/ui-design/extension_cases.md +563 -0
- package/.onto/domains/ui-design/logic_rules.md +349 -0
- package/.onto/domains/ui-design/structure_spec.md +252 -0
- package/.onto/domains/visual-design/competency_qs.md +472 -0
- package/.onto/domains/visual-design/concepts.md +147 -0
- package/.onto/domains/visual-design/conciseness_rules.md +186 -0
- package/.onto/domains/visual-design/dependency_rules.md +282 -0
- package/.onto/domains/visual-design/domain_scope.md +290 -0
- package/.onto/domains/visual-design/extension_cases.md +480 -0
- package/.onto/domains/visual-design/logic_rules.md +232 -0
- package/.onto/domains/visual-design/structure_spec.md +213 -0
- package/.onto/principles/llm-native-development-guideline.md +401 -0
- package/.onto/principles/llm-runtime-interface-principles.md +665 -0
- package/.onto/principles/non-specialist-communication-guideline.md +74 -0
- package/.onto/principles/ontology-as-code-guideline.md +243 -0
- package/.onto/principles/ontology-as-code-naming-charter.md +130 -0
- package/.onto/principles/product-locality-principle.md +129 -0
- package/.onto/principles/productization-charter.md +569 -0
- package/.onto/processes/evolve/material-kind-adapter-contract.md +113 -0
- package/.onto/processes/reconstruct/reconstruct-boundary-contract.md +366 -0
- package/.onto/processes/reconstruct/source-profile-contract.md +107 -0
- package/.onto/processes/reconstruct/source-profiles/code.md +72 -0
- package/.onto/processes/reconstruct/source-profiles/database.md +74 -0
- package/.onto/processes/reconstruct/source-profiles/document.md +71 -0
- package/.onto/processes/reconstruct/source-profiles/spreadsheet.md +79 -0
- package/.onto/processes/review/binding-contract.md +270 -0
- package/.onto/processes/review/execution-preparation-artifacts.md +281 -0
- package/.onto/processes/review/interpretation-contract.md +245 -0
- package/.onto/processes/review/issue-stance-deliberation-contract.md +761 -0
- package/.onto/processes/review/lens-prompt-contract.md +402 -0
- package/.onto/processes/review/lens-registry.md +127 -0
- package/.onto/processes/review/pre-dispatch-contracts.md +428 -0
- package/.onto/processes/review/productized-live-path.md +398 -0
- package/.onto/processes/review/prompt-execution-runner-contract.md +187 -0
- package/.onto/processes/review/record-contract.md +427 -0
- package/.onto/processes/review/record-field-mapping.md +337 -0
- package/.onto/processes/review/review-context-manifest-contract.md +356 -0
- package/.onto/processes/review/review-execution-ux-contract.md +809 -0
- package/.onto/processes/review/review-target-profile-contract.md +259 -0
- package/.onto/processes/review/shared-phenomenon-contract.md +129 -0
- package/.onto/processes/review/synthesize-prompt-contract.md +343 -0
- package/.onto/processes/shared/target-material-kind-contract.md +198 -0
- package/.onto/roles/axiology.md +81 -0
- package/.onto/roles/conciseness.md +36 -0
- package/.onto/roles/coverage.md +34 -0
- package/.onto/roles/dependency.md +37 -0
- package/.onto/roles/evolution.md +35 -0
- package/.onto/roles/logic.md +104 -0
- package/.onto/roles/pragmatics.md +32 -0
- package/.onto/roles/semantics.md +36 -0
- package/.onto/roles/structure.md +33 -0
- package/.onto/roles/synthesize.md +92 -0
- package/AGENTS.md +240 -0
- package/CLAUDE.md +39 -0
- package/README.md +287 -0
- package/bin/onto +92 -0
- package/dist/cli.js +101 -0
- package/dist/core-api/reconstruct-api.js +222 -0
- package/dist/core-api/review-api.js +1271 -0
- package/dist/core-runtime/cli/assemble-review-record.js +431 -0
- package/dist/core-runtime/cli/bootstrap-review-binding.js +186 -0
- package/dist/core-runtime/cli/codex-nested-dispatch.js +226 -0
- package/dist/core-runtime/cli/codex-nested-dispatch.test.js +390 -0
- package/dist/core-runtime/cli/codex-nested-teamlead-executor.js +464 -0
- package/dist/core-runtime/cli/codex-nested-teamlead-executor.test.js +335 -0
- package/dist/core-runtime/cli/codex-review-unit-executor.js +228 -0
- package/dist/core-runtime/cli/complete-review-session.js +64 -0
- package/dist/core-runtime/cli/complexity-assessment.js +153 -0
- package/dist/core-runtime/cli/coordinator-helpers.js +583 -0
- package/dist/core-runtime/cli/coordinator-state-machine-deliberation.test.js +167 -0
- package/dist/core-runtime/cli/coordinator-state-machine.js +794 -0
- package/dist/core-runtime/cli/e2e-codex-multi-agent-fixes.test.js +615 -0
- package/dist/core-runtime/cli/e2e-start-review-session.test.js +312 -0
- package/dist/core-runtime/cli/health.js +44 -0
- package/dist/core-runtime/cli/inline-http-review-unit-executor.js +656 -0
- package/dist/core-runtime/cli/inline-http-review-unit-executor.test.js +567 -0
- package/dist/core-runtime/cli/materialize-review-execution-preparation.js +104 -0
- package/dist/core-runtime/cli/materialize-review-prompt-packets.js +952 -0
- package/dist/core-runtime/cli/migrate-session-roots.js +118 -0
- package/dist/core-runtime/cli/mock-review-unit-executor.js +285 -0
- package/dist/core-runtime/cli/onto-tools.js +369 -0
- package/dist/core-runtime/cli/prepare-review-session.js +272 -0
- package/dist/core-runtime/cli/render-review-final-output.js +350 -0
- package/dist/core-runtime/cli/repo-layout-migration-replace.smoke.test.js +106 -0
- package/dist/core-runtime/cli/review-invoke-auto-resolution.test.js +268 -0
- package/dist/core-runtime/cli/review-invoke-coordinator-topology.test.js +136 -0
- package/dist/core-runtime/cli/review-invoke-resolver-caching.test.js +201 -0
- package/dist/core-runtime/cli/review-invoke-topology-dispatch.test.js +192 -0
- package/dist/core-runtime/cli/review-invoke.js +2030 -0
- package/dist/core-runtime/cli/run-review-prompt-execution.js +2152 -0
- package/dist/core-runtime/cli/session-root-guard.js +168 -0
- package/dist/core-runtime/cli/spawn-watcher.js +173 -0
- package/dist/core-runtime/cli/spawn-watcher.test.js +457 -0
- package/dist/core-runtime/cli/start-review-session.js +68 -0
- package/dist/core-runtime/cli/strip-wrapping-code-fence.js +56 -0
- package/dist/core-runtime/cli/strip-wrapping-code-fence.test.js +79 -0
- package/dist/core-runtime/cli/teamcreate-lens-deliberation-executor.js +412 -0
- package/dist/core-runtime/cli/teamcreate-lens-deliberation-executor.test.js +351 -0
- package/dist/core-runtime/cli/topology-executor-mapping.js +139 -0
- package/dist/core-runtime/cli/topology-executor-mapping.test.js +173 -0
- package/dist/core-runtime/cli/write-review-interpretation.js +81 -0
- package/dist/core-runtime/config/onto-config-cli.js +278 -0
- package/dist/core-runtime/config/onto-config-key-path.js +288 -0
- package/dist/core-runtime/config/onto-config-key-path.test.js +195 -0
- package/dist/core-runtime/config/onto-config-preview.js +108 -0
- package/dist/core-runtime/config/onto-config-preview.test.js +132 -0
- package/dist/core-runtime/discovery/config-chain.js +118 -0
- package/dist/core-runtime/discovery/config-chain.test.js +103 -0
- package/dist/core-runtime/discovery/config-profile.js +199 -0
- package/dist/core-runtime/discovery/config-profile.test.js +233 -0
- package/dist/core-runtime/discovery/host-detection.js +33 -0
- package/dist/core-runtime/discovery/host-detection.test.js +186 -0
- package/dist/core-runtime/discovery/installation-paths.js +21 -0
- package/dist/core-runtime/discovery/installation-paths.test.js +65 -0
- package/dist/core-runtime/discovery/lens-registry.js +60 -0
- package/dist/core-runtime/discovery/lens-registry.test.js +81 -0
- package/dist/core-runtime/discovery/onto-home.js +71 -0
- package/dist/core-runtime/discovery/path-normalization.js +28 -0
- package/dist/core-runtime/discovery/path-normalization.test.js +22 -0
- package/dist/core-runtime/discovery/plugin-path.js +72 -0
- package/dist/core-runtime/discovery/plugin-path.test.js +95 -0
- package/dist/core-runtime/discovery/project-root.js +47 -0
- package/dist/core-runtime/discovery/settings-chain.js +353 -0
- package/dist/core-runtime/discovery/walk-up.js +17 -0
- package/dist/core-runtime/evolve/adapters/code-product/compile/compile-defense.js +344 -0
- package/dist/core-runtime/evolve/adapters/code-product/compile/compile-defense.test.js +915 -0
- package/dist/core-runtime/evolve/adapters/code-product/compile/compile.js +564 -0
- package/dist/core-runtime/evolve/adapters/code-product/compile/compile.test.js +708 -0
- package/dist/core-runtime/evolve/adapters/code-product/parsers/brief-parser.js +165 -0
- package/dist/core-runtime/evolve/adapters/code-product/parsers/brief-parser.test.js +227 -0
- package/dist/core-runtime/evolve/adapters/code-product/validators/validate.js +59 -0
- package/dist/core-runtime/evolve/adapters/code-product/validators/validate.test.js +205 -0
- package/dist/core-runtime/evolve/adapters/methodology/adapter.js +16 -0
- package/dist/core-runtime/evolve/adapters/methodology/adapter.test.js +9 -0
- package/dist/core-runtime/evolve/adapters/methodology/perspectives/authority-consistency.js +298 -0
- package/dist/core-runtime/evolve/adapters/methodology/perspectives/authority-consistency.test.js +70 -0
- package/dist/core-runtime/evolve/adapters/methodology/scope-types/process.js +46 -0
- package/dist/core-runtime/evolve/adapters/methodology/scope-types/process.test.js +73 -0
- package/dist/core-runtime/evolve/adapters/registry.js +47 -0
- package/dist/core-runtime/evolve/adapters/registry.test.js +67 -0
- package/dist/core-runtime/evolve/cli.js +256 -0
- package/dist/core-runtime/evolve/commands/align.js +194 -0
- package/dist/core-runtime/evolve/commands/align.test.js +82 -0
- package/dist/core-runtime/evolve/commands/apply.js +161 -0
- package/dist/core-runtime/evolve/commands/apply.test.js +138 -0
- package/dist/core-runtime/evolve/commands/close.js +39 -0
- package/dist/core-runtime/evolve/commands/close.test.js +99 -0
- package/dist/core-runtime/evolve/commands/defer.js +40 -0
- package/dist/core-runtime/evolve/commands/defer.test.js +134 -0
- package/dist/core-runtime/evolve/commands/draft.js +323 -0
- package/dist/core-runtime/evolve/commands/draft.test.js +178 -0
- package/dist/core-runtime/evolve/commands/e2e-evolve-full-cycle.test.js +208 -0
- package/dist/core-runtime/evolve/commands/error-messages.js +125 -0
- package/dist/core-runtime/evolve/commands/error-messages.test.js +167 -0
- package/dist/core-runtime/evolve/commands/propose-align.js +222 -0
- package/dist/core-runtime/evolve/commands/propose-align.test.js +136 -0
- package/dist/core-runtime/evolve/commands/reconstruct.js +330 -0
- package/dist/core-runtime/evolve/commands/reconstruct.test.js +278 -0
- package/dist/core-runtime/evolve/commands/shared.js +22 -0
- package/dist/core-runtime/evolve/commands/stale-check.js +103 -0
- package/dist/core-runtime/evolve/commands/stale-check.test.js +84 -0
- package/dist/core-runtime/evolve/commands/start.js +887 -0
- package/dist/core-runtime/evolve/commands/start.test.js +396 -0
- package/dist/core-runtime/evolve/config/project-config.js +99 -0
- package/dist/core-runtime/evolve/config/project-config.test.js +170 -0
- package/dist/core-runtime/evolve/renderers/align-packet.js +280 -0
- package/dist/core-runtime/evolve/renderers/align-packet.test.js +332 -0
- package/dist/core-runtime/evolve/renderers/draft-packet.js +303 -0
- package/dist/core-runtime/evolve/renderers/draft-packet.test.js +377 -0
- package/dist/core-runtime/evolve/renderers/format.js +5 -0
- package/dist/core-runtime/evolve/renderers/scope-md.js +237 -0
- package/dist/core-runtime/evolve/renderers/scope-md.test.js +306 -0
- package/dist/core-runtime/govern/cli.js +369 -0
- package/dist/core-runtime/govern/cli.test.js +314 -0
- package/dist/core-runtime/govern/drift-engine.js +103 -0
- package/dist/core-runtime/govern/drift-engine.test.js +319 -0
- package/dist/core-runtime/govern/promote-principle.js +206 -0
- package/dist/core-runtime/govern/promote-principle.test.js +368 -0
- package/dist/core-runtime/govern/queue.js +81 -0
- package/dist/core-runtime/govern/types.js +16 -0
- package/dist/core-runtime/install/cli.js +530 -0
- package/dist/core-runtime/install/detect.js +128 -0
- package/dist/core-runtime/install/detect.test.js +155 -0
- package/dist/core-runtime/install/gitignore-update.js +74 -0
- package/dist/core-runtime/install/gitignore-update.test.js +64 -0
- package/dist/core-runtime/install/install-integration.test.js +373 -0
- package/dist/core-runtime/install/prompts.js +389 -0
- package/dist/core-runtime/install/prompts.test.js +293 -0
- package/dist/core-runtime/install/types.js +26 -0
- package/dist/core-runtime/install/validation.js +295 -0
- package/dist/core-runtime/install/validation.test.js +313 -0
- package/dist/core-runtime/install/writer.js +254 -0
- package/dist/core-runtime/install/writer.test.js +218 -0
- package/dist/core-runtime/learning/extractor.js +461 -0
- package/dist/core-runtime/learning/feedback.js +179 -0
- package/dist/core-runtime/learning/health-report.js +165 -0
- package/dist/core-runtime/learning/health-report.test.js +169 -0
- package/dist/core-runtime/learning/loader.js +388 -0
- package/dist/core-runtime/learning/loader.test.js +102 -0
- package/dist/core-runtime/learning/promote/apply-state.js +240 -0
- package/dist/core-runtime/learning/promote/audit-obligation.js +195 -0
- package/dist/core-runtime/learning/promote/collector.js +432 -0
- package/dist/core-runtime/learning/promote/degraded-state.js +125 -0
- package/dist/core-runtime/learning/promote/domain-doc-proposer.js +166 -0
- package/dist/core-runtime/learning/promote/e2e-promote.test.js +6385 -0
- package/dist/core-runtime/learning/promote/health-snapshot.js +150 -0
- package/dist/core-runtime/learning/promote/insight-reclassifier.js +544 -0
- package/dist/core-runtime/learning/promote/judgment-auditor.js +517 -0
- package/dist/core-runtime/learning/promote/panel-reviewer.js +1158 -0
- package/dist/core-runtime/learning/promote/promote-executor.js +1675 -0
- package/dist/core-runtime/learning/promote/promoter.js +307 -0
- package/dist/core-runtime/learning/promote/retirement.js +122 -0
- package/dist/core-runtime/learning/promote/types.js +23 -0
- package/dist/core-runtime/learning/prompt-sections.js +51 -0
- package/dist/core-runtime/learning/shared/artifact-registry-init.js +45 -0
- package/dist/core-runtime/learning/shared/artifact-registry.js +254 -0
- package/dist/core-runtime/learning/shared/audit-obligation-kernel.js +73 -0
- package/dist/core-runtime/learning/shared/audit-state.js +99 -0
- package/dist/core-runtime/learning/shared/duplicate-check.js +28 -0
- package/dist/core-runtime/learning/shared/llm-caller.js +831 -0
- package/dist/core-runtime/learning/shared/llm-caller.test.js +601 -0
- package/dist/core-runtime/learning/shared/llm-tool-loop.js +393 -0
- package/dist/core-runtime/learning/shared/mode.js +25 -0
- package/dist/core-runtime/learning/shared/paths.js +84 -0
- package/dist/core-runtime/learning/shared/paths.test.js +79 -0
- package/dist/core-runtime/learning/shared/patterns.js +37 -0
- package/dist/core-runtime/learning/shared/recoverability.js +355 -0
- package/dist/core-runtime/learning/shared/recovery-context.js +374 -0
- package/dist/core-runtime/learning/shared/scope.js +1 -0
- package/dist/core-runtime/learning/shared/semantic-classifier.js +94 -0
- package/dist/core-runtime/learning/shared/specs/apply-execution-state-spec.js +42 -0
- package/dist/core-runtime/learning/shared/specs/audit-state-spec.js +37 -0
- package/dist/core-runtime/learning/shared/specs/backup-metadata-spec.js +39 -0
- package/dist/core-runtime/learning/shared/specs/emergency-log-spec.js +41 -0
- package/dist/core-runtime/learning/shared/specs/layout-version-spec.js +38 -0
- package/dist/core-runtime/learning/shared/specs/promote-decisions-spec.js +43 -0
- package/dist/core-runtime/learning/shared/specs/promote-report-spec.js +113 -0
- package/dist/core-runtime/learning/shared/specs/prune-log-spec.js +36 -0
- package/dist/core-runtime/learning/shared/specs/recovery-resolution-spec.js +48 -0
- package/dist/core-runtime/learning/shared/specs/restore-manifest-spec.js +43 -0
- package/dist/core-runtime/learning/shared/specs/spec-helpers.js +64 -0
- package/dist/core-runtime/learning/usage-tracker.js +190 -0
- package/dist/core-runtime/learning/usage-tracker.test.js +176 -0
- package/dist/core-runtime/llm/llm-caller.js +649 -0
- package/dist/core-runtime/llm/llm-tool-loop.js +401 -0
- package/dist/core-runtime/llm/model-switcher.js +62 -0
- package/dist/core-runtime/logger.js +22 -0
- package/dist/core-runtime/onboard/detect-review-axes.js +122 -0
- package/dist/core-runtime/onboard/detect-review-axes.test.js +127 -0
- package/dist/core-runtime/onboard/write-review-block.js +188 -0
- package/dist/core-runtime/onboard/write-review-block.test.js +240 -0
- package/dist/core-runtime/readers/brownfield-builder.js +150 -0
- package/dist/core-runtime/readers/brownfield-builder.test.js +136 -0
- package/dist/core-runtime/readers/code-chunk-collector.js +53 -0
- package/dist/core-runtime/readers/code-chunk-collector.test.js +136 -0
- package/dist/core-runtime/readers/file-utils.js +240 -0
- package/dist/core-runtime/readers/file-utils.test.js +146 -0
- package/dist/core-runtime/readers/lexicon-citation-check.js +93 -0
- package/dist/core-runtime/readers/lexicon-citation-check.test.js +77 -0
- package/dist/core-runtime/readers/mcp-figma.js +30 -0
- package/dist/core-runtime/readers/mcp-figma.test.js +82 -0
- package/dist/core-runtime/readers/mcp-generic.js +31 -0
- package/dist/core-runtime/readers/mcp-generic.test.js +76 -0
- package/dist/core-runtime/readers/ontology-index.js +148 -0
- package/dist/core-runtime/readers/ontology-index.test.js +245 -0
- package/dist/core-runtime/readers/ontology-query.js +168 -0
- package/dist/core-runtime/readers/ontology-query.test.js +311 -0
- package/dist/core-runtime/readers/ontology-resolve.js +48 -0
- package/dist/core-runtime/readers/ontology-resolve.test.js +48 -0
- package/dist/core-runtime/readers/patterns/index.js +7 -0
- package/dist/core-runtime/readers/review-log.js +213 -0
- package/dist/core-runtime/readers/review-log.test.js +313 -0
- package/dist/core-runtime/readers/scan-local.js +102 -0
- package/dist/core-runtime/readers/scan-local.test.js +102 -0
- package/dist/core-runtime/readers/scan-tarball.js +121 -0
- package/dist/core-runtime/readers/scan-tarball.test.js +283 -0
- package/dist/core-runtime/readers/scan-vault.js +34 -0
- package/dist/core-runtime/readers/scan-vault.test.js +81 -0
- package/dist/core-runtime/readers/types.js +42 -0
- package/dist/core-runtime/readers/types.test.js +94 -0
- package/dist/core-runtime/readers/viewpoint-collectors.js +229 -0
- package/dist/core-runtime/reconstruct/artifact-types.js +1 -0
- package/dist/core-runtime/reconstruct/directive-validation.js +123 -0
- package/dist/core-runtime/reconstruct/materialize-preparation.js +251 -0
- package/dist/core-runtime/reconstruct/record.js +198 -0
- package/dist/core-runtime/reconstruct/run.js +578 -0
- package/dist/core-runtime/reconstruct/seed-candidate-validation.js +356 -0
- package/dist/core-runtime/reconstruct/source-observations.js +62 -0
- package/dist/core-runtime/reconstruct/source-profiles.js +73 -0
- package/dist/core-runtime/release-channel/release-channel.js +90 -0
- package/dist/core-runtime/review/artifact-types.js +13 -0
- package/dist/core-runtime/review/citation-audit.js +204 -0
- package/dist/core-runtime/review/citation-audit.test.js +165 -0
- package/dist/core-runtime/review/controlled-lens-deliberation.js +125 -0
- package/dist/core-runtime/review/execution-plan-resolver.js +247 -0
- package/dist/core-runtime/review/execution-plan-resolver.test.js +243 -0
- package/dist/core-runtime/review/execution-topology-resolver-axis-first.test.js +246 -0
- package/dist/core-runtime/review/execution-topology-resolver.js +401 -0
- package/dist/core-runtime/review/execution-topology-resolver.test.js +315 -0
- package/dist/core-runtime/review/failure-records.js +57 -0
- package/dist/core-runtime/review/inline-context-embedder.js +141 -0
- package/dist/core-runtime/review/inline-context-embedder.test.js +154 -0
- package/dist/core-runtime/review/issue-artifact-runtime.js +859 -0
- package/dist/core-runtime/review/legacy-mode-policy.js +88 -0
- package/dist/core-runtime/review/lens-completion-policy.js +17 -0
- package/dist/core-runtime/review/materializers-effort-persist.test.js +79 -0
- package/dist/core-runtime/review/materializers.js +963 -0
- package/dist/core-runtime/review/ontology-path-classifier.js +179 -0
- package/dist/core-runtime/review/ontology-path-classifier.test.js +216 -0
- package/dist/core-runtime/review/packet-boundary-policy.js +215 -0
- package/dist/core-runtime/review/packet-boundary-policy.test.js +107 -0
- package/dist/core-runtime/review/participating-lens-paths.js +61 -0
- package/dist/core-runtime/review/participating-lens-paths.test.js +73 -0
- package/dist/core-runtime/review/review-artifact-utils.js +287 -0
- package/dist/core-runtime/review/review-config-legacy-translate.js +244 -0
- package/dist/core-runtime/review/review-config-legacy-translate.test.js +161 -0
- package/dist/core-runtime/review/review-config-validator.js +289 -0
- package/dist/core-runtime/review/review-config-validator.test.js +236 -0
- package/dist/core-runtime/review/review-execution-profile.js +193 -0
- package/dist/core-runtime/review/review-execution-route.js +52 -0
- package/dist/core-runtime/review/review-progress-contract.js +123 -0
- package/dist/core-runtime/review/review-record-validation.js +251 -0
- package/dist/core-runtime/review/review-result-classification.js +379 -0
- package/dist/core-runtime/review/review-state-machine.js +39 -0
- package/dist/core-runtime/review/route-visibility.js +125 -0
- package/dist/core-runtime/review/shape-pipeline-audit.test.js +311 -0
- package/dist/core-runtime/review/shape-to-topology-id.js +117 -0
- package/dist/core-runtime/review/shape-to-topology-id.test.js +132 -0
- package/dist/core-runtime/review/topology-shape-derivation.js +155 -0
- package/dist/core-runtime/review/topology-shape-derivation.test.js +195 -0
- package/dist/core-runtime/scope-runtime/constants.js +12 -0
- package/dist/core-runtime/scope-runtime/constraint-pool.js +166 -0
- package/dist/core-runtime/scope-runtime/constraint-pool.test.js +674 -0
- package/dist/core-runtime/scope-runtime/domain-validation-log.js +135 -0
- package/dist/core-runtime/scope-runtime/domain-validation-log.test.js +156 -0
- package/dist/core-runtime/scope-runtime/eval-persistence.js +65 -0
- package/dist/core-runtime/scope-runtime/eval-persistence.test.js +84 -0
- package/dist/core-runtime/scope-runtime/event-pipeline.js +64 -0
- package/dist/core-runtime/scope-runtime/event-pipeline.test.js +450 -0
- package/dist/core-runtime/scope-runtime/event-store.js +39 -0
- package/dist/core-runtime/scope-runtime/event-store.test.js +95 -0
- package/dist/core-runtime/scope-runtime/gate-guard.js +348 -0
- package/dist/core-runtime/scope-runtime/gate-guard.test.js +1047 -0
- package/dist/core-runtime/scope-runtime/hash.js +4 -0
- package/dist/core-runtime/scope-runtime/hash.test.js +33 -0
- package/dist/core-runtime/scope-runtime/id.js +4 -0
- package/dist/core-runtime/scope-runtime/id.test.js +17 -0
- package/dist/core-runtime/scope-runtime/reducer.js +297 -0
- package/dist/core-runtime/scope-runtime/reducer.test.js +759 -0
- package/dist/core-runtime/scope-runtime/scope-manager.js +161 -0
- package/dist/core-runtime/scope-runtime/state-machine.js +309 -0
- package/dist/core-runtime/scope-runtime/state-machine.test.js +704 -0
- package/dist/core-runtime/scope-runtime/types.js +116 -0
- package/dist/core-runtime/scope-runtime/types.test.js +69 -0
- package/dist/core-runtime/target-material-kind.js +256 -0
- package/dist/core-runtime/translate/render-for-user.js +169 -0
- package/dist/core-runtime/translate/render-for-user.test.js +122 -0
- package/dist/mcp/server.js +1011 -0
- package/dist/mcp/tool-schemas.js +93 -0
- package/dist/providers/capability-contract.js +1 -0
- package/package.json +68 -0
- package/settings.example.json +33 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex Nested Dispatch Bridge.
|
|
3
|
+
*
|
|
4
|
+
* # What this module is
|
|
5
|
+
*
|
|
6
|
+
* The bridge between review session artifacts and the nested Codex worker
|
|
7
|
+
* orchestrator.
|
|
8
|
+
* It reads the execution plan, constructs the
|
|
9
|
+
* `NestedLensDispatchInput`, invokes `runCodexNestedTeamlead`, and
|
|
10
|
+
* classifies per-lens outcomes into the
|
|
11
|
+
* `ReviewPromptExecutionResult`-compatible shape used downstream by
|
|
12
|
+
* `completeReviewSession`.
|
|
13
|
+
*
|
|
14
|
+
* # Why it exists
|
|
15
|
+
*
|
|
16
|
+
* `runCodexNestedTeamlead` is a pure function over lens inputs → outcomes,
|
|
17
|
+
* intentionally decoupled from onto's session artifacts so it can be
|
|
18
|
+
* unit-tested without filesystem fixtures. This bridge adds the integration that the
|
|
19
|
+
* runner (`runReviewInvokeCli`) can branch into when the resolved
|
|
20
|
+
* profile mode is `nested-workers`.
|
|
21
|
+
*
|
|
22
|
+
* Keeping this seat **separate** from `executeReviewPromptExecution`
|
|
23
|
+
* (which uses the per-lens worker loop) preserves the existing review flow
|
|
24
|
+
* for main-workers mode.
|
|
25
|
+
*
|
|
26
|
+
* # How it relates
|
|
27
|
+
*
|
|
28
|
+
* - `ReviewExecutionProfile.mode` selects whether this bridge is used.
|
|
29
|
+
* - `executeReviewViaCodexNested()` handles the nested worker execution phase.
|
|
30
|
+
* - `completeReviewSession()` downstream consumes the result to compile
|
|
31
|
+
* the final review record.
|
|
32
|
+
*
|
|
33
|
+
* # Scope
|
|
34
|
+
*
|
|
35
|
+
* - Bridge function `executeReviewViaCodexNested`
|
|
36
|
+
* - Output-file validation (exists + non-empty) on top of orchestrator
|
|
37
|
+
* outcomes — a per-lens `status: "ok"` in the orchestrator is
|
|
38
|
+
* necessary but not sufficient; the file must actually be written.
|
|
39
|
+
* - Tests with injected orchestrator + injected filesystem
|
|
40
|
+
*
|
|
41
|
+
* This bridge owns only nested lens dispatch. Synthesize, deliberation
|
|
42
|
+
* artifact handling, and final record assembly stay in the main review
|
|
43
|
+
* runner.
|
|
44
|
+
*
|
|
45
|
+
* # Design reference
|
|
46
|
+
*
|
|
47
|
+
* - Nested Codex validation notes under `development-records/`
|
|
48
|
+
*/
|
|
49
|
+
import fs from "node:fs/promises";
|
|
50
|
+
import path from "node:path";
|
|
51
|
+
import { normalizeLlmModelSwitcher } from "../llm/model-switcher.js";
|
|
52
|
+
import { readYamlDocument } from "../review/review-artifact-utils.js";
|
|
53
|
+
import { runCodexNestedTeamlead, } from "./codex-nested-teamlead-executor.js";
|
|
54
|
+
const defaultInspector = async (p) => {
|
|
55
|
+
try {
|
|
56
|
+
const stat = await fs.stat(p);
|
|
57
|
+
return { exists: stat.isFile(), size: stat.size };
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return { exists: false, size: 0 };
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
// Artifact archival
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
/**
|
|
67
|
+
* Archive for outer codex stdout/stderr when streaming did not
|
|
68
|
+
* already write the files. Normally `spawnOuterCodex` is invoked with
|
|
69
|
+
* `stream_stdout_path` / `stream_stderr_path` and the on-disk files
|
|
70
|
+
* carry the authoritative content via `fs.createWriteStream`; in that
|
|
71
|
+
* case this helper sees non-empty files and returns without writing
|
|
72
|
+
* (prevents dual-writer drift — 3rd self-review U4).
|
|
73
|
+
*
|
|
74
|
+
* Silently swallows write errors — an artifact write failure must not
|
|
75
|
+
* mask the actual dispatch outcome. Best-effort.
|
|
76
|
+
*/
|
|
77
|
+
async function archiveOuterStreamsIfMissing(sessionRoot, nestedResult) {
|
|
78
|
+
const stdoutPath = path.join(sessionRoot, "nested-outer-stdout.log");
|
|
79
|
+
const stderrPath = path.join(sessionRoot, "nested-outer-stderr.log");
|
|
80
|
+
await Promise.all([
|
|
81
|
+
archiveWriteIfMissing(stdoutPath, nestedResult.outer_stdout ?? ""),
|
|
82
|
+
archiveWriteIfMissing(stderrPath, nestedResult.outer_stderr ?? ""),
|
|
83
|
+
]);
|
|
84
|
+
}
|
|
85
|
+
async function archiveWriteIfMissing(targetPath, content) {
|
|
86
|
+
try {
|
|
87
|
+
const stat = await fs.stat(targetPath).catch(() => null);
|
|
88
|
+
if (stat && stat.size > 0) {
|
|
89
|
+
// Streaming writer produced a non-empty file — respect it as the
|
|
90
|
+
// single authority. Do not overwrite.
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
await fs.writeFile(targetPath, content).catch(() => { });
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// Best-effort; never throw.
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
// Worker setting resolution
|
|
101
|
+
// ---------------------------------------------------------------------------
|
|
102
|
+
/**
|
|
103
|
+
* Resolve distinct Codex model settings for the outer teamlead and inner lens
|
|
104
|
+
* workers. Empty objects mean Codex picks its configured defaults for that seat.
|
|
105
|
+
*/
|
|
106
|
+
export function resolveCodexSpawnConfig(config) {
|
|
107
|
+
const execution = config.review?.execution;
|
|
108
|
+
const inherited = config.llm;
|
|
109
|
+
return {
|
|
110
|
+
teamlead: codexConfigFromRef(execution?.teamlead.llm, inherited) ?? {},
|
|
111
|
+
lens: codexConfigFromRef(execution?.lens.llm, inherited) ?? {},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function codexConfigFromRef(ref, inherited) {
|
|
115
|
+
const llm = ref === undefined || ref === "inherit" ? inherited : ref;
|
|
116
|
+
const selection = normalizeLlmModelSwitcher(llm);
|
|
117
|
+
if (selection?.provider !== "codex")
|
|
118
|
+
return null;
|
|
119
|
+
return {
|
|
120
|
+
...(selection.model_id ? { model: selection.model_id } : {}),
|
|
121
|
+
...(selection.reasoning_effort ? { effort: selection.reasoning_effort } : {}),
|
|
122
|
+
...(selection.service_tier ? { service_tier: selection.service_tier } : {}),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
// ---------------------------------------------------------------------------
|
|
126
|
+
// Main bridge function
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
/**
|
|
129
|
+
* Execute a review via the nested Codex worker path. Reads the execution
|
|
130
|
+
* plan from `sessionRoot/execution-plan.yaml`, dispatches all lens
|
|
131
|
+
* packets through one outer Codex teamlead plus one inner Codex worker per lens, and
|
|
132
|
+
* classifies outcomes into participating / degraded lens sets.
|
|
133
|
+
*
|
|
134
|
+
* An orchestrator `status: "ok"` is NOT sufficient for `participating` —
|
|
135
|
+
* the output file must exist AND be non-empty. This guards against the
|
|
136
|
+
* outer Codex reporting success when an inner worker failed to write its
|
|
137
|
+
* `-o` output.
|
|
138
|
+
*
|
|
139
|
+
* Injection:
|
|
140
|
+
* - `runImpl`: replace the orchestrator (default: `runCodexNestedTeamlead`)
|
|
141
|
+
* - `inspector`: replace the file-existence probe (default: `fs.stat`)
|
|
142
|
+
*/
|
|
143
|
+
export async function executeReviewViaCodexNested(args, runImpl = runCodexNestedTeamlead, inspector = defaultInspector) {
|
|
144
|
+
const executionPlanPath = path.join(args.sessionRoot, "execution-plan.yaml");
|
|
145
|
+
// `readYamlDocument` throws with a descriptive message when the file
|
|
146
|
+
// is missing or malformed — let it propagate so the caller sees the
|
|
147
|
+
// session artifact problem directly rather than a generic null check.
|
|
148
|
+
const plan = await readYamlDocument(executionPlanPath);
|
|
149
|
+
const lenses = plan.lens_prompt_packet_seats.map((seat) => ({
|
|
150
|
+
lens_id: seat.lens_id,
|
|
151
|
+
packet_path: seat.packet_path,
|
|
152
|
+
output_path: seat.output_path,
|
|
153
|
+
}));
|
|
154
|
+
const spawnConfig = resolveCodexSpawnConfig(args.ontoConfig);
|
|
155
|
+
// Stream paths live under sessionRoot so the watcher pane can `tail -f`
|
|
156
|
+
// them from the moment the outer codex starts emitting, instead of
|
|
157
|
+
// waiting for the post-hoc `archiveOuterStreams` batch write. With
|
|
158
|
+
// streaming active, these files are the single authority — no post-
|
|
159
|
+
// dispatch overwrite (3rd self-review U4: prevent dual-writer drift
|
|
160
|
+
// where two writers could diverge if one was interrupted mid-flush).
|
|
161
|
+
const streamStdoutPath = path.join(args.sessionRoot, "nested-outer-stdout.log");
|
|
162
|
+
const streamStderrPath = path.join(args.sessionRoot, "nested-outer-stderr.log");
|
|
163
|
+
const nestedResult = await runImpl({
|
|
164
|
+
lenses,
|
|
165
|
+
...(spawnConfig.teamlead.model
|
|
166
|
+
? { teamlead_model: spawnConfig.teamlead.model }
|
|
167
|
+
: {}),
|
|
168
|
+
...(spawnConfig.teamlead.effort
|
|
169
|
+
? { teamlead_reasoning_effort: spawnConfig.teamlead.effort }
|
|
170
|
+
: {}),
|
|
171
|
+
...(spawnConfig.teamlead.service_tier
|
|
172
|
+
? { teamlead_service_tier: spawnConfig.teamlead.service_tier }
|
|
173
|
+
: {}),
|
|
174
|
+
...(spawnConfig.lens.model ? { lens_model: spawnConfig.lens.model } : {}),
|
|
175
|
+
...(spawnConfig.lens.effort
|
|
176
|
+
? { lens_reasoning_effort: spawnConfig.lens.effort }
|
|
177
|
+
: {}),
|
|
178
|
+
...(spawnConfig.lens.service_tier
|
|
179
|
+
? { lens_service_tier: spawnConfig.lens.service_tier }
|
|
180
|
+
: {}),
|
|
181
|
+
...(args.projectRoot ? { project_root: args.projectRoot } : {}),
|
|
182
|
+
...(typeof args.timeout_ms === "number" ? { timeout_ms: args.timeout_ms } : {}),
|
|
183
|
+
...(args.codex_bin ? { codex_bin: args.codex_bin } : {}),
|
|
184
|
+
stream_stdout_path: streamStdoutPath,
|
|
185
|
+
stream_stderr_path: streamStderrPath,
|
|
186
|
+
});
|
|
187
|
+
// Archive step is a no-op when streaming already produced files.
|
|
188
|
+
await archiveOuterStreamsIfMissing(args.sessionRoot, nestedResult);
|
|
189
|
+
const participating = [];
|
|
190
|
+
const degraded = [];
|
|
191
|
+
for (let i = 0; i < lenses.length; i += 1) {
|
|
192
|
+
const lens = lenses[i];
|
|
193
|
+
const outcome = nestedResult.outcomes[i];
|
|
194
|
+
const orchestratorOk = outcome?.status === "ok";
|
|
195
|
+
if (!orchestratorOk) {
|
|
196
|
+
degraded.push(lens.lens_id);
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
const probe = await inspector(lens.output_path);
|
|
200
|
+
if (probe.exists && probe.size > 0) {
|
|
201
|
+
participating.push(lens.lens_id);
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
degraded.push(lens.lens_id);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// Determine halt_reason when orchestrator signalled teamlead-level
|
|
208
|
+
// failure (e.g., timeout, no summary) — surfaces to the caller for
|
|
209
|
+
// error reporting. Per-lens degradation alone does NOT halt.
|
|
210
|
+
let halt_reason;
|
|
211
|
+
if (!nestedResult.summary_parsed && nestedResult.outer_exit_code !== 0) {
|
|
212
|
+
halt_reason =
|
|
213
|
+
`codex-nested outer teamlead failed (exit=${nestedResult.outer_exit_code}, summary=${nestedResult.summary_parsed ? "parsed" : "missing"})`;
|
|
214
|
+
}
|
|
215
|
+
return {
|
|
216
|
+
session_root: args.sessionRoot,
|
|
217
|
+
executed_lens_count: lenses.length,
|
|
218
|
+
participating_lens_ids: participating,
|
|
219
|
+
degraded_lens_ids: degraded,
|
|
220
|
+
synthesis_executed: false,
|
|
221
|
+
synthesis_output_path: plan.synthesis_output_path,
|
|
222
|
+
error_log_path: plan.error_log_path ?? null,
|
|
223
|
+
nested_raw: nestedResult,
|
|
224
|
+
...(halt_reason ? { halt_reason } : {}),
|
|
225
|
+
};
|
|
226
|
+
}
|
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
5
|
+
import { writeYamlDocument } from "../review/review-artifact-utils.js";
|
|
6
|
+
import { executeReviewViaCodexNested, } from "./codex-nested-dispatch.js";
|
|
7
|
+
async function mkSession(plan) {
|
|
8
|
+
const root = await fs.mkdtemp(path.join(os.tmpdir(), "onto-pr-h-"));
|
|
9
|
+
const sessionRoot = path.join(root, "session");
|
|
10
|
+
await fs.mkdir(sessionRoot, { recursive: true });
|
|
11
|
+
await writeYamlDocument(path.join(sessionRoot, "execution-plan.yaml"), plan);
|
|
12
|
+
return {
|
|
13
|
+
sessionRoot,
|
|
14
|
+
cleanup: async () => {
|
|
15
|
+
await fs.rm(root, { recursive: true, force: true });
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function buildPlan(lenses, sessionRoot) {
|
|
20
|
+
return {
|
|
21
|
+
session_id: "pr-h-test",
|
|
22
|
+
session_root: sessionRoot,
|
|
23
|
+
execution_realization: "subagent",
|
|
24
|
+
host_runtime: "codex",
|
|
25
|
+
review_mode: "core-axis",
|
|
26
|
+
interpretation_artifact_path: path.join(sessionRoot, "interpretation.yaml"),
|
|
27
|
+
binding_output_path: path.join(sessionRoot, "binding.yaml"),
|
|
28
|
+
session_metadata_path: path.join(sessionRoot, "session-metadata.yaml"),
|
|
29
|
+
execution_preparation_root: path.join(sessionRoot, "prep"),
|
|
30
|
+
round1_root: path.join(sessionRoot, "round1"),
|
|
31
|
+
lens_execution_seats: lenses.map((l) => ({
|
|
32
|
+
lens_id: l.lens_id,
|
|
33
|
+
output_path: l.output_path,
|
|
34
|
+
})),
|
|
35
|
+
prompt_packets_root: path.join(sessionRoot, "prompt-packets"),
|
|
36
|
+
lens_prompt_packet_seats: lenses,
|
|
37
|
+
synthesize_prompt_packet_path: path.join(sessionRoot, "synthesize-packet.md"),
|
|
38
|
+
synthesis_output_path: path.join(sessionRoot, "synthesis.md"),
|
|
39
|
+
deliberation_output_path: path.join(sessionRoot, "deliberation.md"),
|
|
40
|
+
execution_result_path: path.join(sessionRoot, "execution-result.yaml"),
|
|
41
|
+
error_log_path: path.join(sessionRoot, "error-log.md"),
|
|
42
|
+
final_output_path: path.join(sessionRoot, "final.md"),
|
|
43
|
+
review_record_path: path.join(sessionRoot, "review-record.yaml"),
|
|
44
|
+
boundary_policy: {
|
|
45
|
+
web_research_policy: "allowed",
|
|
46
|
+
repo_exploration_policy: "allowed",
|
|
47
|
+
recursive_reference_expansion_policy: "allowed",
|
|
48
|
+
filesystem_scope: { allowed_roots: [], source_mutation_policy: "denied" },
|
|
49
|
+
},
|
|
50
|
+
boundary_presentation: {
|
|
51
|
+
web_research: { requested_policy: "allowed" },
|
|
52
|
+
repo_exploration: { requested_policy: "allowed" },
|
|
53
|
+
recursive_reference_expansion: { requested_policy: "allowed" },
|
|
54
|
+
source_mutation: { requested_policy: "denied" },
|
|
55
|
+
filesystem_scope: { requested_allowed_roots: [] },
|
|
56
|
+
},
|
|
57
|
+
boundary_enforcement_profile: {
|
|
58
|
+
web_research: "prompt_declared_only",
|
|
59
|
+
repo_exploration: "prompt_declared_only",
|
|
60
|
+
recursive_reference_expansion: "prompt_declared_only",
|
|
61
|
+
source_mutation: "prompt_declared_only",
|
|
62
|
+
filesystem_scope: "prompt_declared_only",
|
|
63
|
+
},
|
|
64
|
+
effective_boundary_state: {
|
|
65
|
+
web_research: {
|
|
66
|
+
requested_policy: "allowed",
|
|
67
|
+
effective_policy: "allowed",
|
|
68
|
+
guarantee_level: "prompt_declared_only",
|
|
69
|
+
},
|
|
70
|
+
repo_exploration: {
|
|
71
|
+
requested_policy: "allowed",
|
|
72
|
+
effective_policy: "allowed",
|
|
73
|
+
guarantee_level: "prompt_declared_only",
|
|
74
|
+
},
|
|
75
|
+
recursive_reference_expansion: {
|
|
76
|
+
requested_policy: "allowed",
|
|
77
|
+
effective_policy: "allowed",
|
|
78
|
+
guarantee_level: "prompt_declared_only",
|
|
79
|
+
},
|
|
80
|
+
source_mutation: {
|
|
81
|
+
requested_policy: "denied",
|
|
82
|
+
effective_policy: "denied",
|
|
83
|
+
guarantee_level: "prompt_declared_only",
|
|
84
|
+
},
|
|
85
|
+
filesystem_scope: {
|
|
86
|
+
requested_allowed_roots: [],
|
|
87
|
+
effective_allowed_roots: [],
|
|
88
|
+
guarantee_level: "prompt_declared_only",
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function buildOrchestrator(outcomes, opts = {}) {
|
|
94
|
+
const calls = [];
|
|
95
|
+
const impl = async (input) => {
|
|
96
|
+
calls.push(input);
|
|
97
|
+
return {
|
|
98
|
+
outcomes,
|
|
99
|
+
outer_stdout: opts.outer_stdout ?? "",
|
|
100
|
+
outer_stderr: opts.outer_stderr ?? "",
|
|
101
|
+
outer_exit_code: opts.outer_exit_code ?? 0,
|
|
102
|
+
summary_parsed: opts.summary_parsed ?? true,
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
return { impl, calls };
|
|
106
|
+
}
|
|
107
|
+
function staticInspector(present, sizes = {}) {
|
|
108
|
+
return async (p) => ({
|
|
109
|
+
exists: present.has(p),
|
|
110
|
+
size: sizes[p] ?? (present.has(p) ? 1 : 0),
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
// Forwarding: execution-plan lenses → orchestrator input
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
describe("executeReviewViaCodexNested — forwarding", () => {
|
|
117
|
+
let fixture;
|
|
118
|
+
afterEach(async () => {
|
|
119
|
+
if (fixture)
|
|
120
|
+
await fixture.cleanup();
|
|
121
|
+
});
|
|
122
|
+
it("forwards lens packet triples in execution-plan order", async () => {
|
|
123
|
+
const plan = buildPlan([
|
|
124
|
+
{ lens_id: "logic", packet_path: "/pkts/logic.md", output_path: "/out/logic.md" },
|
|
125
|
+
{ lens_id: "pragmatics", packet_path: "/pkts/pr.md", output_path: "/out/pr.md" },
|
|
126
|
+
{ lens_id: "axiology", packet_path: "/pkts/ax.md", output_path: "/out/ax.md" },
|
|
127
|
+
], "");
|
|
128
|
+
fixture = await mkSession(plan);
|
|
129
|
+
const { impl, calls } = buildOrchestrator([
|
|
130
|
+
{ lens_id: "logic", status: "ok" },
|
|
131
|
+
{ lens_id: "pragmatics", status: "ok" },
|
|
132
|
+
{ lens_id: "axiology", status: "ok" },
|
|
133
|
+
]);
|
|
134
|
+
await executeReviewViaCodexNested({ sessionRoot: fixture.sessionRoot, ontoConfig: {} }, impl, staticInspector(new Set(["/out/logic.md", "/out/pr.md", "/out/ax.md"])));
|
|
135
|
+
expect(calls).toHaveLength(1);
|
|
136
|
+
expect(calls[0].lenses.map((l) => l.lens_id)).toEqual([
|
|
137
|
+
"logic",
|
|
138
|
+
"pragmatics",
|
|
139
|
+
"axiology",
|
|
140
|
+
]);
|
|
141
|
+
expect(calls[0].lenses[0].packet_path).toBe("/pkts/logic.md");
|
|
142
|
+
expect(calls[0].lenses[0].output_path).toBe("/out/logic.md");
|
|
143
|
+
});
|
|
144
|
+
it("passes model from ontoConfig.codex.model and reasoning_effort from codex.effort", async () => {
|
|
145
|
+
const plan = buildPlan([{ lens_id: "l", packet_path: "/p", output_path: "/o" }], "");
|
|
146
|
+
fixture = await mkSession(plan);
|
|
147
|
+
const { impl, calls } = buildOrchestrator([{ lens_id: "l", status: "ok" }]);
|
|
148
|
+
await executeReviewViaCodexNested({
|
|
149
|
+
sessionRoot: fixture.sessionRoot,
|
|
150
|
+
ontoConfig: { codex: { model: "gpt-5.4", effort: "high" } },
|
|
151
|
+
}, impl, staticInspector(new Set(["/o"])));
|
|
152
|
+
expect(calls[0].model).toBe("gpt-5.4");
|
|
153
|
+
expect(calls[0].reasoning_effort).toBe("high");
|
|
154
|
+
});
|
|
155
|
+
it("falls back to top-level model / reasoning_effort when codex.* unset", async () => {
|
|
156
|
+
const plan = buildPlan([{ lens_id: "l", packet_path: "/p", output_path: "/o" }], "");
|
|
157
|
+
fixture = await mkSession(plan);
|
|
158
|
+
const { impl, calls } = buildOrchestrator([{ lens_id: "l", status: "ok" }]);
|
|
159
|
+
await executeReviewViaCodexNested({
|
|
160
|
+
sessionRoot: fixture.sessionRoot,
|
|
161
|
+
ontoConfig: { model: "gpt-top", reasoning_effort: "low" },
|
|
162
|
+
}, impl, staticInspector(new Set(["/o"])));
|
|
163
|
+
expect(calls[0].model).toBe("gpt-top");
|
|
164
|
+
expect(calls[0].reasoning_effort).toBe("low");
|
|
165
|
+
});
|
|
166
|
+
it("reads model/effort from review.subagent (P2 canonical location)", async () => {
|
|
167
|
+
const plan = buildPlan([{ lens_id: "l", packet_path: "/p", output_path: "/o" }], "");
|
|
168
|
+
fixture = await mkSession(plan);
|
|
169
|
+
const { impl, calls } = buildOrchestrator([{ lens_id: "l", status: "ok" }]);
|
|
170
|
+
await executeReviewViaCodexNested({
|
|
171
|
+
sessionRoot: fixture.sessionRoot,
|
|
172
|
+
ontoConfig: {
|
|
173
|
+
review: {
|
|
174
|
+
subagent: { provider: "codex", model_id: "gpt-sub", effort: "medium" },
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
}, impl, staticInspector(new Set(["/o"])));
|
|
178
|
+
expect(calls[0].model).toBe("gpt-sub");
|
|
179
|
+
expect(calls[0].reasoning_effort).toBe("medium");
|
|
180
|
+
});
|
|
181
|
+
it("reads model/effort from review.teamlead.model when external codex teamlead", async () => {
|
|
182
|
+
const plan = buildPlan([{ lens_id: "l", packet_path: "/p", output_path: "/o" }], "");
|
|
183
|
+
fixture = await mkSession(plan);
|
|
184
|
+
const { impl, calls } = buildOrchestrator([{ lens_id: "l", status: "ok" }]);
|
|
185
|
+
await executeReviewViaCodexNested({
|
|
186
|
+
sessionRoot: fixture.sessionRoot,
|
|
187
|
+
ontoConfig: {
|
|
188
|
+
review: {
|
|
189
|
+
teamlead: { model: { provider: "codex", model_id: "gpt-tl", effort: "high" } },
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
}, impl, staticInspector(new Set(["/o"])));
|
|
193
|
+
expect(calls[0].model).toBe("gpt-tl");
|
|
194
|
+
expect(calls[0].reasoning_effort).toBe("high");
|
|
195
|
+
});
|
|
196
|
+
it("review.subagent wins over top-level codex.* (P2 canonical > legacy)", async () => {
|
|
197
|
+
const plan = buildPlan([{ lens_id: "l", packet_path: "/p", output_path: "/o" }], "");
|
|
198
|
+
fixture = await mkSession(plan);
|
|
199
|
+
const { impl, calls } = buildOrchestrator([{ lens_id: "l", status: "ok" }]);
|
|
200
|
+
await executeReviewViaCodexNested({
|
|
201
|
+
sessionRoot: fixture.sessionRoot,
|
|
202
|
+
ontoConfig: {
|
|
203
|
+
review: {
|
|
204
|
+
subagent: { provider: "codex", model_id: "gpt-sub", effort: "medium" },
|
|
205
|
+
},
|
|
206
|
+
codex: { model: "gpt-legacy", effort: "high" },
|
|
207
|
+
},
|
|
208
|
+
}, impl, staticInspector(new Set(["/o"])));
|
|
209
|
+
expect(calls[0].model).toBe("gpt-sub");
|
|
210
|
+
expect(calls[0].reasoning_effort).toBe("medium");
|
|
211
|
+
});
|
|
212
|
+
it("review.subagent with provider=main-native does NOT claim codex slot (falls through)", async () => {
|
|
213
|
+
// main-native subagent is not a codex provider → resolver should move on
|
|
214
|
+
// to teamlead → legacy → top-level, not pick up subagent.
|
|
215
|
+
const plan = buildPlan([{ lens_id: "l", packet_path: "/p", output_path: "/o" }], "");
|
|
216
|
+
fixture = await mkSession(plan);
|
|
217
|
+
const { impl, calls } = buildOrchestrator([{ lens_id: "l", status: "ok" }]);
|
|
218
|
+
await executeReviewViaCodexNested({
|
|
219
|
+
sessionRoot: fixture.sessionRoot,
|
|
220
|
+
ontoConfig: {
|
|
221
|
+
review: {
|
|
222
|
+
subagent: { provider: "main-native" },
|
|
223
|
+
},
|
|
224
|
+
codex: { model: "gpt-legacy", effort: "high" },
|
|
225
|
+
},
|
|
226
|
+
}, impl, staticInspector(new Set(["/o"])));
|
|
227
|
+
expect(calls[0].model).toBe("gpt-legacy");
|
|
228
|
+
expect(calls[0].reasoning_effort).toBe("high");
|
|
229
|
+
});
|
|
230
|
+
it("passes sessionRoot-based stream_stdout_path/stream_stderr_path to orchestrator (live watcher)", async () => {
|
|
231
|
+
// The watcher pane's tail -f target is sessionRoot/nested-outer-*.log.
|
|
232
|
+
// The orchestrator must receive those absolute paths so spawn-watcher
|
|
233
|
+
// can tee outer codex stdout/stderr there as codex emits chunks. If
|
|
234
|
+
// the dispatch stopped plumbing these paths, streaming would silently
|
|
235
|
+
// fall back to memory-only capture.
|
|
236
|
+
const plan = buildPlan([{ lens_id: "l", packet_path: "/p", output_path: "/o" }], "");
|
|
237
|
+
fixture = await mkSession(plan);
|
|
238
|
+
const { impl, calls } = buildOrchestrator([{ lens_id: "l", status: "ok" }]);
|
|
239
|
+
await executeReviewViaCodexNested({
|
|
240
|
+
sessionRoot: fixture.sessionRoot,
|
|
241
|
+
ontoConfig: {},
|
|
242
|
+
}, impl, staticInspector(new Set(["/o"])));
|
|
243
|
+
expect(calls[0].stream_stdout_path).toBe(path.join(fixture.sessionRoot, "nested-outer-stdout.log"));
|
|
244
|
+
expect(calls[0].stream_stderr_path).toBe(path.join(fixture.sessionRoot, "nested-outer-stderr.log"));
|
|
245
|
+
});
|
|
246
|
+
it("archives outer stdout/stderr to nested-outer-*.log under sessionRoot", async () => {
|
|
247
|
+
// Regression guard: outer codex diagnostics (ENV-BEFORE / ENV-AFTER /
|
|
248
|
+
// LENS_DISPATCH_SUMMARY) and raw stderr are otherwise unreachable
|
|
249
|
+
// after dispatch completes, because review-invoke's final JSON drops
|
|
250
|
+
// `nested_raw`. The archive step is what makes post-hoc auditing
|
|
251
|
+
// possible for the principal.
|
|
252
|
+
const plan = buildPlan([{ lens_id: "l", packet_path: "/p", output_path: "/o" }], "");
|
|
253
|
+
fixture = await mkSession(plan);
|
|
254
|
+
const { impl } = buildOrchestrator([{ lens_id: "l", status: "ok" }], {
|
|
255
|
+
outer_stdout: "ENV-BEFORE lens=l packet=/p output=/o\n" +
|
|
256
|
+
"ENV-AFTER lens=l exit=0 output_bytes=42\n" +
|
|
257
|
+
'LENS_DISPATCH_SUMMARY:{"lens_results":[{"lens_id":"l","status":"ok"}]}\n',
|
|
258
|
+
outer_stderr: "some-warning from outer codex\n",
|
|
259
|
+
});
|
|
260
|
+
await executeReviewViaCodexNested({
|
|
261
|
+
sessionRoot: fixture.sessionRoot,
|
|
262
|
+
ontoConfig: {},
|
|
263
|
+
}, impl, staticInspector(new Set(["/o"])));
|
|
264
|
+
const stdoutArchive = await fs.readFile(path.join(fixture.sessionRoot, "nested-outer-stdout.log"), "utf8");
|
|
265
|
+
const stderrArchive = await fs.readFile(path.join(fixture.sessionRoot, "nested-outer-stderr.log"), "utf8");
|
|
266
|
+
expect(stdoutArchive).toContain("ENV-BEFORE lens=l");
|
|
267
|
+
expect(stdoutArchive).toContain("ENV-AFTER lens=l");
|
|
268
|
+
expect(stdoutArchive).toContain("LENS_DISPATCH_SUMMARY:");
|
|
269
|
+
expect(stderrArchive).toContain("some-warning from outer codex");
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
// ---------------------------------------------------------------------------
|
|
273
|
+
// Classification: orchestrator-ok AND file-exists → participating
|
|
274
|
+
// ---------------------------------------------------------------------------
|
|
275
|
+
describe("executeReviewViaCodexNested — per-lens classification", () => {
|
|
276
|
+
let fixture;
|
|
277
|
+
afterEach(async () => {
|
|
278
|
+
if (fixture)
|
|
279
|
+
await fixture.cleanup();
|
|
280
|
+
});
|
|
281
|
+
it("all ok + all files present → all participating", async () => {
|
|
282
|
+
const plan = buildPlan([
|
|
283
|
+
{ lens_id: "a", packet_path: "/p/a", output_path: "/o/a" },
|
|
284
|
+
{ lens_id: "b", packet_path: "/p/b", output_path: "/o/b" },
|
|
285
|
+
], "");
|
|
286
|
+
fixture = await mkSession(plan);
|
|
287
|
+
const { impl } = buildOrchestrator([
|
|
288
|
+
{ lens_id: "a", status: "ok" },
|
|
289
|
+
{ lens_id: "b", status: "ok" },
|
|
290
|
+
]);
|
|
291
|
+
const result = await executeReviewViaCodexNested({ sessionRoot: fixture.sessionRoot, ontoConfig: {} }, impl, staticInspector(new Set(["/o/a", "/o/b"])));
|
|
292
|
+
expect(result.participating_lens_ids).toEqual(["a", "b"]);
|
|
293
|
+
expect(result.degraded_lens_ids).toEqual([]);
|
|
294
|
+
expect(result.executed_lens_count).toBe(2);
|
|
295
|
+
});
|
|
296
|
+
it("orchestrator fail → degraded (no file probe needed)", async () => {
|
|
297
|
+
const plan = buildPlan([
|
|
298
|
+
{ lens_id: "a", packet_path: "/p/a", output_path: "/o/a" },
|
|
299
|
+
{ lens_id: "b", packet_path: "/p/b", output_path: "/o/b" },
|
|
300
|
+
], "");
|
|
301
|
+
fixture = await mkSession(plan);
|
|
302
|
+
const { impl } = buildOrchestrator([
|
|
303
|
+
{ lens_id: "a", status: "ok" },
|
|
304
|
+
{ lens_id: "b", status: "fail", error: "inner exit 1" },
|
|
305
|
+
]);
|
|
306
|
+
const result = await executeReviewViaCodexNested({ sessionRoot: fixture.sessionRoot, ontoConfig: {} }, impl, staticInspector(new Set(["/o/a", "/o/b"])));
|
|
307
|
+
expect(result.participating_lens_ids).toEqual(["a"]);
|
|
308
|
+
expect(result.degraded_lens_ids).toEqual(["b"]);
|
|
309
|
+
});
|
|
310
|
+
it("orchestrator ok but output file missing → degraded", async () => {
|
|
311
|
+
const plan = buildPlan([
|
|
312
|
+
{ lens_id: "a", packet_path: "/p/a", output_path: "/o/a" },
|
|
313
|
+
{ lens_id: "b", packet_path: "/p/b", output_path: "/o/b" },
|
|
314
|
+
], "");
|
|
315
|
+
fixture = await mkSession(plan);
|
|
316
|
+
const { impl } = buildOrchestrator([
|
|
317
|
+
{ lens_id: "a", status: "ok" },
|
|
318
|
+
{ lens_id: "b", status: "ok" },
|
|
319
|
+
]);
|
|
320
|
+
const result = await executeReviewViaCodexNested({ sessionRoot: fixture.sessionRoot, ontoConfig: {} }, impl, staticInspector(new Set(["/o/a"])));
|
|
321
|
+
expect(result.participating_lens_ids).toEqual(["a"]);
|
|
322
|
+
expect(result.degraded_lens_ids).toEqual(["b"]);
|
|
323
|
+
});
|
|
324
|
+
it("orchestrator ok but output file size=0 → degraded", async () => {
|
|
325
|
+
const plan = buildPlan([{ lens_id: "a", packet_path: "/p/a", output_path: "/o/a" }], "");
|
|
326
|
+
fixture = await mkSession(plan);
|
|
327
|
+
const { impl } = buildOrchestrator([{ lens_id: "a", status: "ok" }]);
|
|
328
|
+
const result = await executeReviewViaCodexNested({ sessionRoot: fixture.sessionRoot, ontoConfig: {} }, impl, staticInspector(new Set(["/o/a"]), { "/o/a": 0 }));
|
|
329
|
+
expect(result.participating_lens_ids).toEqual([]);
|
|
330
|
+
expect(result.degraded_lens_ids).toEqual(["a"]);
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
// ---------------------------------------------------------------------------
|
|
334
|
+
// Result shape
|
|
335
|
+
// ---------------------------------------------------------------------------
|
|
336
|
+
describe("executeReviewViaCodexNested — result shape", () => {
|
|
337
|
+
let fixture;
|
|
338
|
+
afterEach(async () => {
|
|
339
|
+
if (fixture)
|
|
340
|
+
await fixture.cleanup();
|
|
341
|
+
});
|
|
342
|
+
it("synthesis_executed is always false in PR-H (deferred)", async () => {
|
|
343
|
+
const plan = buildPlan([{ lens_id: "a", packet_path: "/p/a", output_path: "/o/a" }], "");
|
|
344
|
+
fixture = await mkSession(plan);
|
|
345
|
+
const { impl } = buildOrchestrator([{ lens_id: "a", status: "ok" }]);
|
|
346
|
+
const result = await executeReviewViaCodexNested({ sessionRoot: fixture.sessionRoot, ontoConfig: {} }, impl, staticInspector(new Set(["/o/a"])));
|
|
347
|
+
expect(result.synthesis_executed).toBe(false);
|
|
348
|
+
});
|
|
349
|
+
it("synthesis_output_path is sourced from execution-plan for downstream synthesize wire-in", async () => {
|
|
350
|
+
const plan = buildPlan([{ lens_id: "a", packet_path: "/p/a", output_path: "/o/a" }], "");
|
|
351
|
+
plan.synthesis_output_path = "/tmp/synth-target.md";
|
|
352
|
+
fixture = await mkSession(plan);
|
|
353
|
+
const { impl } = buildOrchestrator([{ lens_id: "a", status: "ok" }]);
|
|
354
|
+
const result = await executeReviewViaCodexNested({ sessionRoot: fixture.sessionRoot, ontoConfig: {} }, impl, staticInspector(new Set(["/o/a"])));
|
|
355
|
+
expect(result.synthesis_output_path).toBe("/tmp/synth-target.md");
|
|
356
|
+
});
|
|
357
|
+
it("nested_raw exposes orchestrator result verbatim for debugging", async () => {
|
|
358
|
+
const plan = buildPlan([{ lens_id: "a", packet_path: "/p/a", output_path: "/o/a" }], "");
|
|
359
|
+
fixture = await mkSession(plan);
|
|
360
|
+
const { impl } = buildOrchestrator([{ lens_id: "a", status: "ok" }], { outer_stdout: "outer stdout content", outer_stderr: "outer stderr content" });
|
|
361
|
+
const result = await executeReviewViaCodexNested({ sessionRoot: fixture.sessionRoot, ontoConfig: {} }, impl, staticInspector(new Set(["/o/a"])));
|
|
362
|
+
expect(result.nested_raw.outer_stdout).toBe("outer stdout content");
|
|
363
|
+
expect(result.nested_raw.outer_stderr).toBe("outer stderr content");
|
|
364
|
+
});
|
|
365
|
+
it("halt_reason populated when outer exit non-zero AND summary not parsed", async () => {
|
|
366
|
+
const plan = buildPlan([{ lens_id: "a", packet_path: "/p/a", output_path: "/o/a" }], "");
|
|
367
|
+
fixture = await mkSession(plan);
|
|
368
|
+
const { impl } = buildOrchestrator([{ lens_id: "a", status: "fail", error: "no summary" }], { outer_exit_code: 137, summary_parsed: false });
|
|
369
|
+
const result = await executeReviewViaCodexNested({ sessionRoot: fixture.sessionRoot, ontoConfig: {} }, impl, staticInspector(new Set()));
|
|
370
|
+
expect(result.halt_reason).toBeDefined();
|
|
371
|
+
expect(result.halt_reason).toContain("137");
|
|
372
|
+
});
|
|
373
|
+
it("halt_reason absent when per-lens degraded but teamlead ok", async () => {
|
|
374
|
+
const plan = buildPlan([{ lens_id: "a", packet_path: "/p/a", output_path: "/o/a" }], "");
|
|
375
|
+
fixture = await mkSession(plan);
|
|
376
|
+
const { impl } = buildOrchestrator([{ lens_id: "a", status: "fail", error: "inner 1" }], { outer_exit_code: 0, summary_parsed: true });
|
|
377
|
+
const result = await executeReviewViaCodexNested({ sessionRoot: fixture.sessionRoot, ontoConfig: {} }, impl, staticInspector(new Set()));
|
|
378
|
+
expect(result.halt_reason).toBeUndefined();
|
|
379
|
+
expect(result.degraded_lens_ids).toEqual(["a"]);
|
|
380
|
+
});
|
|
381
|
+
});
|
|
382
|
+
// ---------------------------------------------------------------------------
|
|
383
|
+
// Execution-plan missing — bridge surfaces the error
|
|
384
|
+
// ---------------------------------------------------------------------------
|
|
385
|
+
describe("executeReviewViaCodexNested — missing execution-plan", () => {
|
|
386
|
+
it("propagates readYamlDocument error when execution-plan.yaml absent", async () => {
|
|
387
|
+
const { impl } = buildOrchestrator([]);
|
|
388
|
+
await expect(executeReviewViaCodexNested({ sessionRoot: "/nonexistent/session/path", ontoConfig: {} }, impl, staticInspector(new Set()))).rejects.toThrow(/Failed to read artifact/);
|
|
389
|
+
});
|
|
390
|
+
});
|