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,268 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import * as os from "node:os";
|
|
4
|
+
import * as path from "node:path";
|
|
5
|
+
import { resolveExecutionRealizationHandoff, detectClaudeCodeHost, detectCodexAvailable, } from "./review-invoke.js";
|
|
6
|
+
// ─── Helpers ───
|
|
7
|
+
const originalEnv = { ...process.env };
|
|
8
|
+
function clearEnv() {
|
|
9
|
+
delete process.env.CLAUDECODE;
|
|
10
|
+
// Don't touch PATH/HOME globally — we override them in tests that need to.
|
|
11
|
+
}
|
|
12
|
+
function restoreEnv() {
|
|
13
|
+
for (const k of Object.keys(process.env)) {
|
|
14
|
+
if (!(k in originalEnv))
|
|
15
|
+
delete process.env[k];
|
|
16
|
+
}
|
|
17
|
+
for (const [k, v] of Object.entries(originalEnv)) {
|
|
18
|
+
process.env[k] = v;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function createTmpHome() {
|
|
22
|
+
const home = fs.mkdtempSync(path.join(os.tmpdir(), "onto-auto-resolution-test-"));
|
|
23
|
+
fs.mkdirSync(path.join(home, ".codex"), { recursive: true });
|
|
24
|
+
return {
|
|
25
|
+
home,
|
|
26
|
+
cleanup: () => fs.rmSync(home, { recursive: true, force: true }),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
// ─── detectClaudeCodeHost ───
|
|
30
|
+
describe("detectClaudeCodeHost", () => {
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
clearEnv();
|
|
33
|
+
});
|
|
34
|
+
afterEach(() => {
|
|
35
|
+
restoreEnv();
|
|
36
|
+
});
|
|
37
|
+
it("returns true when CLAUDECODE=1", () => {
|
|
38
|
+
process.env.CLAUDECODE = "1";
|
|
39
|
+
expect(detectClaudeCodeHost()).toBe(true);
|
|
40
|
+
});
|
|
41
|
+
it("returns false when CLAUDECODE unset", () => {
|
|
42
|
+
expect(detectClaudeCodeHost()).toBe(false);
|
|
43
|
+
});
|
|
44
|
+
it("returns false when CLAUDECODE=0 or other value", () => {
|
|
45
|
+
process.env.CLAUDECODE = "0";
|
|
46
|
+
expect(detectClaudeCodeHost()).toBe(false);
|
|
47
|
+
process.env.CLAUDECODE = "true";
|
|
48
|
+
expect(detectClaudeCodeHost()).toBe(false);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
// ─── detectCodexAvailable ───
|
|
52
|
+
describe("detectCodexAvailable", () => {
|
|
53
|
+
let tmp = null;
|
|
54
|
+
const originalPath = process.env.PATH;
|
|
55
|
+
const originalHome = process.env.HOME;
|
|
56
|
+
beforeEach(() => {
|
|
57
|
+
tmp = createTmpHome();
|
|
58
|
+
process.env.HOME = tmp.home;
|
|
59
|
+
});
|
|
60
|
+
afterEach(() => {
|
|
61
|
+
if (tmp)
|
|
62
|
+
tmp.cleanup();
|
|
63
|
+
tmp = null;
|
|
64
|
+
if (originalPath !== undefined)
|
|
65
|
+
process.env.PATH = originalPath;
|
|
66
|
+
if (originalHome !== undefined)
|
|
67
|
+
process.env.HOME = originalHome;
|
|
68
|
+
});
|
|
69
|
+
it("returns false when codex binary not on PATH", () => {
|
|
70
|
+
const emptyDir = fs.mkdtempSync(path.join(os.tmpdir(), "onto-empty-path-"));
|
|
71
|
+
process.env.PATH = emptyDir;
|
|
72
|
+
try {
|
|
73
|
+
expect(detectCodexAvailable()).toBe(false);
|
|
74
|
+
}
|
|
75
|
+
finally {
|
|
76
|
+
fs.rmSync(emptyDir, { recursive: true, force: true });
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
it("returns false when binary on PATH but auth.json missing", () => {
|
|
80
|
+
const binDir = fs.mkdtempSync(path.join(os.tmpdir(), "onto-bin-"));
|
|
81
|
+
const fakeCodex = path.join(binDir, "codex");
|
|
82
|
+
fs.writeFileSync(fakeCodex, "#!/bin/sh\necho fake\n");
|
|
83
|
+
fs.chmodSync(fakeCodex, 0o755);
|
|
84
|
+
process.env.PATH = binDir;
|
|
85
|
+
// HOME has tmp with .codex dir but no auth.json
|
|
86
|
+
try {
|
|
87
|
+
expect(detectCodexAvailable()).toBe(false);
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
fs.rmSync(binDir, { recursive: true, force: true });
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
it("returns true when both binary and auth.json exist", () => {
|
|
94
|
+
const binDir = fs.mkdtempSync(path.join(os.tmpdir(), "onto-bin-"));
|
|
95
|
+
const fakeCodex = path.join(binDir, "codex");
|
|
96
|
+
fs.writeFileSync(fakeCodex, "#!/bin/sh\necho fake\n");
|
|
97
|
+
fs.chmodSync(fakeCodex, 0o755);
|
|
98
|
+
process.env.PATH = binDir;
|
|
99
|
+
fs.writeFileSync(path.join(tmp.home, ".codex", "auth.json"), "{}");
|
|
100
|
+
try {
|
|
101
|
+
expect(detectCodexAvailable()).toBe(true);
|
|
102
|
+
}
|
|
103
|
+
finally {
|
|
104
|
+
fs.rmSync(binDir, { recursive: true, force: true });
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
// ─── resolveExecutionRealizationHandoff ───
|
|
109
|
+
describe("resolveExecutionRealizationHandoff", () => {
|
|
110
|
+
let tmp = null;
|
|
111
|
+
const originalPath = process.env.PATH;
|
|
112
|
+
const originalHome = process.env.HOME;
|
|
113
|
+
beforeEach(() => {
|
|
114
|
+
clearEnv();
|
|
115
|
+
tmp = createTmpHome();
|
|
116
|
+
process.env.HOME = tmp.home;
|
|
117
|
+
// Default: empty PATH (codex not available) unless test sets it.
|
|
118
|
+
process.env.PATH = "/tmp/none-existing-dir";
|
|
119
|
+
});
|
|
120
|
+
afterEach(() => {
|
|
121
|
+
if (tmp)
|
|
122
|
+
tmp.cleanup();
|
|
123
|
+
tmp = null;
|
|
124
|
+
if (originalPath !== undefined)
|
|
125
|
+
process.env.PATH = originalPath;
|
|
126
|
+
else
|
|
127
|
+
delete process.env.PATH;
|
|
128
|
+
if (originalHome !== undefined)
|
|
129
|
+
process.env.HOME = originalHome;
|
|
130
|
+
restoreEnv();
|
|
131
|
+
});
|
|
132
|
+
it("E1 explicit --codex → self", () => {
|
|
133
|
+
const out = resolveExecutionRealizationHandoff({
|
|
134
|
+
explicitCodex: true,
|
|
135
|
+
prepareOnly: false,
|
|
136
|
+
ontoConfig: {},
|
|
137
|
+
});
|
|
138
|
+
expect(out.type).toBe("self");
|
|
139
|
+
if (out.type === "self") {
|
|
140
|
+
expect(out.profile.host_runtime).toBe("codex");
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
it("E1b prepare-only on Claude host → self with Claude profile (artifact seam)", () => {
|
|
144
|
+
// coordinator-state-machine calls reviewPrepareOnly(--prepare-only) from within
|
|
145
|
+
// a Claude Code session; it must receive the Claude profile so prepared session
|
|
146
|
+
// artifacts get recorded as agent-teams+claude, not subagent+codex. This is the
|
|
147
|
+
// artifact seam fix (review consensus #1, 2026-04-16).
|
|
148
|
+
process.env.CLAUDECODE = "1";
|
|
149
|
+
const out = resolveExecutionRealizationHandoff({
|
|
150
|
+
explicitCodex: false,
|
|
151
|
+
prepareOnly: true,
|
|
152
|
+
ontoConfig: {},
|
|
153
|
+
});
|
|
154
|
+
expect(out.type).toBe("self");
|
|
155
|
+
if (out.type === "self") {
|
|
156
|
+
expect(out.profile.host_runtime).toBe("claude");
|
|
157
|
+
expect(out.profile.execution_realization).toBe("agent-teams");
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
it("E2 env ONTO_HOST_RUNTIME=claude → coordinator_start with agent-teams default", () => {
|
|
161
|
+
process.env.ONTO_HOST_RUNTIME = "claude";
|
|
162
|
+
const out = resolveExecutionRealizationHandoff({
|
|
163
|
+
explicitCodex: false,
|
|
164
|
+
prepareOnly: false,
|
|
165
|
+
ontoConfig: {},
|
|
166
|
+
});
|
|
167
|
+
expect(out.type).toBe("coordinator_start");
|
|
168
|
+
if (out.type === "coordinator_start") {
|
|
169
|
+
expect(out.profile.execution_realization).toBe("agent-teams");
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
it("E2c env ONTO_HOST_RUNTIME=codex → self", () => {
|
|
173
|
+
process.env.ONTO_HOST_RUNTIME = "codex";
|
|
174
|
+
const out = resolveExecutionRealizationHandoff({
|
|
175
|
+
explicitCodex: false,
|
|
176
|
+
prepareOnly: false,
|
|
177
|
+
ontoConfig: {},
|
|
178
|
+
});
|
|
179
|
+
expect(out.type).toBe("self");
|
|
180
|
+
if (out.type === "self") {
|
|
181
|
+
expect(out.profile.host_runtime).toBe("codex");
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
it("E3 auto + CLAUDECODE=1 → coordinator_start with agent-teams", () => {
|
|
185
|
+
process.env.CLAUDECODE = "1";
|
|
186
|
+
const out = resolveExecutionRealizationHandoff({
|
|
187
|
+
explicitCodex: false,
|
|
188
|
+
prepareOnly: false,
|
|
189
|
+
ontoConfig: {},
|
|
190
|
+
});
|
|
191
|
+
expect(out.type).toBe("coordinator_start");
|
|
192
|
+
if (out.type === "coordinator_start") {
|
|
193
|
+
expect(out.profile.execution_realization).toBe("agent-teams");
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
it("E4 auto + codex available + no CLAUDECODE → self", () => {
|
|
197
|
+
const binDir = fs.mkdtempSync(path.join(os.tmpdir(), "onto-bin-"));
|
|
198
|
+
const fakeCodex = path.join(binDir, "codex");
|
|
199
|
+
fs.writeFileSync(fakeCodex, "#!/bin/sh\n");
|
|
200
|
+
fs.chmodSync(fakeCodex, 0o755);
|
|
201
|
+
process.env.PATH = binDir;
|
|
202
|
+
fs.writeFileSync(path.join(tmp.home, ".codex", "auth.json"), "{}");
|
|
203
|
+
try {
|
|
204
|
+
const out = resolveExecutionRealizationHandoff({
|
|
205
|
+
explicitCodex: false,
|
|
206
|
+
prepareOnly: false,
|
|
207
|
+
ontoConfig: {},
|
|
208
|
+
});
|
|
209
|
+
expect(out.type).toBe("self");
|
|
210
|
+
if (out.type === "self") {
|
|
211
|
+
expect(out.profile.host_runtime).toBe("codex");
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
finally {
|
|
215
|
+
fs.rmSync(binDir, { recursive: true, force: true });
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
it("E5 auto + both CLAUDECODE and codex available → stay-in-host (Claude wins)", () => {
|
|
219
|
+
process.env.CLAUDECODE = "1";
|
|
220
|
+
const binDir = fs.mkdtempSync(path.join(os.tmpdir(), "onto-bin-"));
|
|
221
|
+
const fakeCodex = path.join(binDir, "codex");
|
|
222
|
+
fs.writeFileSync(fakeCodex, "#!/bin/sh\n");
|
|
223
|
+
fs.chmodSync(fakeCodex, 0o755);
|
|
224
|
+
process.env.PATH = binDir;
|
|
225
|
+
fs.writeFileSync(path.join(tmp.home, ".codex", "auth.json"), "{}");
|
|
226
|
+
try {
|
|
227
|
+
const out = resolveExecutionRealizationHandoff({
|
|
228
|
+
explicitCodex: false,
|
|
229
|
+
prepareOnly: false,
|
|
230
|
+
ontoConfig: {},
|
|
231
|
+
});
|
|
232
|
+
expect(out.type).toBe("coordinator_start");
|
|
233
|
+
if (out.type === "coordinator_start") {
|
|
234
|
+
expect(out.profile.execution_realization).toBe("agent-teams");
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
finally {
|
|
238
|
+
fs.rmSync(binDir, { recursive: true, force: true });
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
it("E6 auto + nothing available → no_host", () => {
|
|
242
|
+
const out = resolveExecutionRealizationHandoff({
|
|
243
|
+
explicitCodex: false,
|
|
244
|
+
prepareOnly: false,
|
|
245
|
+
ontoConfig: {},
|
|
246
|
+
});
|
|
247
|
+
expect(out).toEqual({ type: "no_host" });
|
|
248
|
+
});
|
|
249
|
+
it("E7 external_http_provider=litellm → ts_inline_http self-execute", () => {
|
|
250
|
+
// LiteLLM wiring is live via the P4 auto-detection branch —
|
|
251
|
+
// `resolveExecutionPlan` sees `external_http_provider` set, routes to
|
|
252
|
+
// the S1 external HTTP path, and the handoff returns `self` so the
|
|
253
|
+
// invoking process runs the executor in-band.
|
|
254
|
+
const out = resolveExecutionRealizationHandoff({
|
|
255
|
+
explicitCodex: false,
|
|
256
|
+
prepareOnly: false,
|
|
257
|
+
ontoConfig: {
|
|
258
|
+
external_http_provider: "litellm",
|
|
259
|
+
llm_base_url: "http://proxy.local",
|
|
260
|
+
litellm: { model: "llama-8b" },
|
|
261
|
+
},
|
|
262
|
+
});
|
|
263
|
+
expect(out).toEqual({
|
|
264
|
+
type: "self",
|
|
265
|
+
profile: { execution_realization: "ts_inline_http", host_runtime: "litellm" },
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
});
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
2
|
+
import { tryResolveTopologyForHandoff } from "./review-invoke.js";
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Coordinator handoff descriptor invariants (P9.3, 2026-04-21):
|
|
5
|
+
//
|
|
6
|
+
// (1) `tryResolveTopologyForHandoff` attempts axis-first resolution
|
|
7
|
+
// unconditionally; the former opt-in gate (config.review presence)
|
|
8
|
+
// is gone. Every review invocation that reaches a reachable host
|
|
9
|
+
// ships a descriptor.
|
|
10
|
+
// (2) Resolvable topology → non-null descriptor with all 6 static
|
|
11
|
+
// attributes, minus plan_trace (handoff payload stays compact).
|
|
12
|
+
// (3) Descriptor is JSON-serializable with deterministic shape —
|
|
13
|
+
// downstream coordinator consumers parse it unmodified.
|
|
14
|
+
// (4) Returns null ONLY when ontoConfig is undefined (defensive) or
|
|
15
|
+
// the resolver itself returns `no_host` (axis + main_native
|
|
16
|
+
// degrade both failed, i.e. no Claude or Codex host reachable).
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
const ORIGINAL_ENV = { ...process.env };
|
|
19
|
+
function restoreEnv() {
|
|
20
|
+
for (const k of Object.keys(process.env)) {
|
|
21
|
+
if (!(k in ORIGINAL_ENV))
|
|
22
|
+
delete process.env[k];
|
|
23
|
+
}
|
|
24
|
+
for (const [k, v] of Object.entries(ORIGINAL_ENV)) {
|
|
25
|
+
process.env[k] = v;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
describe("tryResolveTopologyForHandoff — null paths", () => {
|
|
29
|
+
beforeEach(() => {
|
|
30
|
+
delete process.env.CLAUDECODE;
|
|
31
|
+
delete process.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS;
|
|
32
|
+
});
|
|
33
|
+
afterEach(restoreEnv);
|
|
34
|
+
it("undefined ontoConfig → null (defensive guard)", () => {
|
|
35
|
+
expect(tryResolveTopologyForHandoff(undefined)).toBeNull();
|
|
36
|
+
});
|
|
37
|
+
it("no host signals → null (resolver returns no_host)", () => {
|
|
38
|
+
// No CLAUDECODE, no codex session. With no reachable host even the
|
|
39
|
+
// main_native degrade cannot map — resolver returns no_host and the
|
|
40
|
+
// handoff payload omits the topology field.
|
|
41
|
+
expect(tryResolveTopologyForHandoff({})).toBeNull();
|
|
42
|
+
});
|
|
43
|
+
it("review block declares unreachable subagent → null (axis + degrade both fail)", () => {
|
|
44
|
+
// No CLAUDECODE, no experimental, no codex, no litellm. Axis-first
|
|
45
|
+
// derives `cc-teams-codex-subprocess` which fails requirements; the
|
|
46
|
+
// main_native degrade then fails to map (no host) → no_host.
|
|
47
|
+
expect(tryResolveTopologyForHandoff({
|
|
48
|
+
review: {
|
|
49
|
+
subagent: { provider: "codex", model_id: "gpt-5.4" },
|
|
50
|
+
},
|
|
51
|
+
})).toBeNull();
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
describe("tryResolveTopologyForHandoff — always-on axis-first (P9.3)", () => {
|
|
55
|
+
beforeEach(() => {
|
|
56
|
+
delete process.env.CLAUDECODE;
|
|
57
|
+
delete process.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS;
|
|
58
|
+
});
|
|
59
|
+
afterEach(restoreEnv);
|
|
60
|
+
it("plain CC session without review block → cc-main-agent-subagent descriptor via main_native degrade", () => {
|
|
61
|
+
// P9.3 invariant: every review invocation produces a descriptor
|
|
62
|
+
// when a host is reachable, even without an explicit `review:`
|
|
63
|
+
// axis block. Main_native degrade maps to cc-main-agent-subagent
|
|
64
|
+
// under CLAUDECODE=1.
|
|
65
|
+
process.env.CLAUDECODE = "1";
|
|
66
|
+
const descriptor = tryResolveTopologyForHandoff({});
|
|
67
|
+
expect(descriptor).not.toBeNull();
|
|
68
|
+
expect(descriptor.id).toBe("cc-main-agent-subagent");
|
|
69
|
+
});
|
|
70
|
+
it("empty `review: {}` ALSO resolves via main_native degrade under CC host", () => {
|
|
71
|
+
// The former M2 opt-in guard is gone — empty review blocks are no
|
|
72
|
+
// longer distinct from absent ones at dispatch time. Both produce
|
|
73
|
+
// the same cc-main-agent-subagent descriptor on CLAUDECODE=1.
|
|
74
|
+
process.env.CLAUDECODE = "1";
|
|
75
|
+
const descriptor = tryResolveTopologyForHandoff({
|
|
76
|
+
review: {},
|
|
77
|
+
});
|
|
78
|
+
expect(descriptor).not.toBeNull();
|
|
79
|
+
expect(descriptor.id).toBe("cc-main-agent-subagent");
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
describe("tryResolveTopologyForHandoff — resolved descriptor", () => {
|
|
83
|
+
beforeEach(() => {
|
|
84
|
+
delete process.env.CLAUDECODE;
|
|
85
|
+
delete process.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS;
|
|
86
|
+
});
|
|
87
|
+
afterEach(restoreEnv);
|
|
88
|
+
it("cc-main-agent-subagent resolves to descriptor with 6 static attributes", () => {
|
|
89
|
+
process.env.CLAUDECODE = "1";
|
|
90
|
+
const descriptor = tryResolveTopologyForHandoff({
|
|
91
|
+
review: { subagent: { provider: "main-native" } },
|
|
92
|
+
});
|
|
93
|
+
expect(descriptor).not.toBeNull();
|
|
94
|
+
expect(descriptor.id).toBe("cc-main-agent-subagent");
|
|
95
|
+
expect(descriptor.teamlead_location).toBe("onto-main");
|
|
96
|
+
expect(descriptor.lens_spawn_mechanism).toBe("claude-agent-tool");
|
|
97
|
+
expect(descriptor.max_concurrent_lenses).toBe(10);
|
|
98
|
+
expect(descriptor.transport_rank).toBe("S2");
|
|
99
|
+
expect(descriptor.deliberation_channel).toBe("synthesizer-only");
|
|
100
|
+
});
|
|
101
|
+
it("cc-teams-lens-agent-deliberation resolves when triple opt-in met", () => {
|
|
102
|
+
process.env.CLAUDECODE = "1";
|
|
103
|
+
process.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS = "1";
|
|
104
|
+
// P9.2 (2026-04-21): deliberation topology is selected through the
|
|
105
|
+
// `config.review` axis block (`lens_deliberation: sendmessage-a2a`)
|
|
106
|
+
// + `lens_agent_teams_mode: true` double opt-in.
|
|
107
|
+
const descriptor = tryResolveTopologyForHandoff({
|
|
108
|
+
review: {
|
|
109
|
+
subagent: { provider: "main-native" },
|
|
110
|
+
lens_deliberation: "sendmessage-a2a",
|
|
111
|
+
},
|
|
112
|
+
lens_agent_teams_mode: true,
|
|
113
|
+
});
|
|
114
|
+
expect(descriptor).not.toBeNull();
|
|
115
|
+
expect(descriptor.id).toBe("cc-teams-lens-agent-deliberation");
|
|
116
|
+
expect(descriptor.deliberation_channel).toBe("sendmessage-a2a");
|
|
117
|
+
expect(descriptor.lens_spawn_mechanism).toBe("claude-teamcreate-member");
|
|
118
|
+
});
|
|
119
|
+
it("descriptor does NOT include plan_trace (compact handoff JSON)", () => {
|
|
120
|
+
process.env.CLAUDECODE = "1";
|
|
121
|
+
const descriptor = tryResolveTopologyForHandoff({
|
|
122
|
+
review: { subagent: { provider: "main-native" } },
|
|
123
|
+
});
|
|
124
|
+
expect(descriptor).not.toBeNull();
|
|
125
|
+
expect(Object.keys(descriptor)).not.toContain("plan_trace");
|
|
126
|
+
});
|
|
127
|
+
it("descriptor is JSON round-trip stable", () => {
|
|
128
|
+
process.env.CLAUDECODE = "1";
|
|
129
|
+
const descriptor = tryResolveTopologyForHandoff({
|
|
130
|
+
review: { subagent: { provider: "main-native" } },
|
|
131
|
+
});
|
|
132
|
+
const json = JSON.stringify(descriptor);
|
|
133
|
+
const parsed = JSON.parse(json);
|
|
134
|
+
expect(parsed).toEqual(descriptor);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { tryResolveTopologyForHandoff, tryTopologyDerivedExecutor, } from "./review-invoke.js";
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// P9.3-m1 Resolver caching invariants (2026-04-21):
|
|
5
|
+
//
|
|
6
|
+
// `runReviewInvokeCli` resolves `resolveExecutionTopology` exactly once
|
|
7
|
+
// per invocation and threads the result as `cached` to 3 downstream
|
|
8
|
+
// consumers. This file protects the cache plumbing from future
|
|
9
|
+
// regressions — a caller that accidentally drops the `cached` argument
|
|
10
|
+
// (reverting to the 3x resolver-call pattern) would re-emit the full
|
|
11
|
+
// `[topology]` STDERR trace, which these tests assert does NOT happen.
|
|
12
|
+
//
|
|
13
|
+
// The `[topology] signals:` line is the most stable counter because
|
|
14
|
+
// `resolveExecutionTopology` emits it exactly once at the very start of
|
|
15
|
+
// each invocation (see execution-topology-resolver.ts:413). When the
|
|
16
|
+
// helpers honour `cached`, they skip the resolver entirely and this
|
|
17
|
+
// line MUST NOT appear.
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
const FAKE_HOME = "/tmp/fake-onto-home";
|
|
20
|
+
const CACHED_LITELLM_TOPOLOGY = {
|
|
21
|
+
id: "cc-teams-litellm-sessions",
|
|
22
|
+
teamlead_location: "claude-teamcreate",
|
|
23
|
+
lens_spawn_mechanism: "litellm-http",
|
|
24
|
+
max_concurrent_lenses: 3,
|
|
25
|
+
transport_rank: "S2",
|
|
26
|
+
deliberation_channel: "synthesizer-only",
|
|
27
|
+
plan_trace: ["cached-by-runReviewInvokeCli"],
|
|
28
|
+
};
|
|
29
|
+
const CACHED_CC_MAIN_TOPOLOGY = {
|
|
30
|
+
id: "cc-main-agent-subagent",
|
|
31
|
+
teamlead_location: "onto-main",
|
|
32
|
+
lens_spawn_mechanism: "claude-agent-tool",
|
|
33
|
+
max_concurrent_lenses: 3,
|
|
34
|
+
transport_rank: "S0",
|
|
35
|
+
deliberation_channel: "synthesizer-only",
|
|
36
|
+
plan_trace: ["cached-by-runReviewInvokeCli"],
|
|
37
|
+
};
|
|
38
|
+
describe("tryResolveTopologyForHandoff — cached topology bypass", () => {
|
|
39
|
+
const originalEnv = { ...process.env };
|
|
40
|
+
let stderrSpy;
|
|
41
|
+
beforeEach(() => {
|
|
42
|
+
delete process.env.CLAUDECODE;
|
|
43
|
+
delete process.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS;
|
|
44
|
+
stderrSpy = vi.spyOn(process.stderr, "write").mockImplementation(() => true);
|
|
45
|
+
});
|
|
46
|
+
afterEach(() => {
|
|
47
|
+
stderrSpy.mockRestore();
|
|
48
|
+
for (const k of Object.keys(process.env)) {
|
|
49
|
+
if (!(k in originalEnv))
|
|
50
|
+
delete process.env[k];
|
|
51
|
+
}
|
|
52
|
+
for (const [k, v] of Object.entries(originalEnv)) {
|
|
53
|
+
process.env[k] = v;
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
function signalsTraceLines() {
|
|
57
|
+
return stderrSpy.mock.calls
|
|
58
|
+
.map((c) => String(c[0]))
|
|
59
|
+
.filter((l) => l.startsWith("[topology] signals:"));
|
|
60
|
+
}
|
|
61
|
+
it("cached=ExecutionTopology → descriptor returned without re-running resolver", () => {
|
|
62
|
+
const descriptor = tryResolveTopologyForHandoff({}, CACHED_LITELLM_TOPOLOGY);
|
|
63
|
+
expect(descriptor).not.toBeNull();
|
|
64
|
+
expect(descriptor.id).toBe("cc-teams-litellm-sessions");
|
|
65
|
+
expect(descriptor.teamlead_location).toBe("claude-teamcreate");
|
|
66
|
+
expect(signalsTraceLines()).toHaveLength(0);
|
|
67
|
+
});
|
|
68
|
+
it("cached=null → returns null without re-running resolver", () => {
|
|
69
|
+
const descriptor = tryResolveTopologyForHandoff({}, null);
|
|
70
|
+
expect(descriptor).toBeNull();
|
|
71
|
+
expect(signalsTraceLines()).toHaveLength(0);
|
|
72
|
+
});
|
|
73
|
+
it("cached=undefined → legacy behaviour (resolver runs, emits signals)", () => {
|
|
74
|
+
// Two-argument call path preserved for test-harness compatibility;
|
|
75
|
+
// this branch is what existing tests exercise.
|
|
76
|
+
tryResolveTopologyForHandoff({});
|
|
77
|
+
expect(signalsTraceLines()).toHaveLength(1);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
describe("tryTopologyDerivedExecutor — cached topology bypass", () => {
|
|
81
|
+
const originalEnv = { ...process.env };
|
|
82
|
+
let stderrSpy;
|
|
83
|
+
beforeEach(() => {
|
|
84
|
+
delete process.env.CLAUDECODE;
|
|
85
|
+
delete process.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS;
|
|
86
|
+
stderrSpy = vi.spyOn(process.stderr, "write").mockImplementation(() => true);
|
|
87
|
+
});
|
|
88
|
+
afterEach(() => {
|
|
89
|
+
stderrSpy.mockRestore();
|
|
90
|
+
for (const k of Object.keys(process.env)) {
|
|
91
|
+
if (!(k in originalEnv))
|
|
92
|
+
delete process.env[k];
|
|
93
|
+
}
|
|
94
|
+
for (const [k, v] of Object.entries(originalEnv)) {
|
|
95
|
+
process.env[k] = v;
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
function signalsTraceLines() {
|
|
99
|
+
return stderrSpy.mock.calls
|
|
100
|
+
.map((c) => String(c[0]))
|
|
101
|
+
.filter((l) => l.startsWith("[topology] signals:"));
|
|
102
|
+
}
|
|
103
|
+
it("cached=ExecutionTopology (binary-backed) → executor returned without re-running resolver", () => {
|
|
104
|
+
const result = tryTopologyDerivedExecutor({ llm_base_url: "http://localhost:4000" }, FAKE_HOME, CACHED_LITELLM_TOPOLOGY);
|
|
105
|
+
expect(result).not.toBeNull();
|
|
106
|
+
expect(result.bin).toBe("node");
|
|
107
|
+
expect(result.args[0]).toContain("inline-http-review-unit-executor.js");
|
|
108
|
+
expect(signalsTraceLines()).toHaveLength(0);
|
|
109
|
+
});
|
|
110
|
+
it("cached=ExecutionTopology (no standalone binary) → null without re-running resolver", () => {
|
|
111
|
+
const result = tryTopologyDerivedExecutor({}, FAKE_HOME, CACHED_CC_MAIN_TOPOLOGY);
|
|
112
|
+
expect(result).toBeNull();
|
|
113
|
+
expect(signalsTraceLines()).toHaveLength(0);
|
|
114
|
+
});
|
|
115
|
+
it("cached=null → null without re-running resolver", () => {
|
|
116
|
+
const result = tryTopologyDerivedExecutor({}, FAKE_HOME, null);
|
|
117
|
+
expect(result).toBeNull();
|
|
118
|
+
expect(signalsTraceLines()).toHaveLength(0);
|
|
119
|
+
});
|
|
120
|
+
it("cached=undefined → legacy behaviour (resolver runs, emits signals)", () => {
|
|
121
|
+
process.env.CLAUDECODE = "1";
|
|
122
|
+
tryTopologyDerivedExecutor({}, FAKE_HOME);
|
|
123
|
+
expect(signalsTraceLines()).toHaveLength(1);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
// ---------------------------------------------------------------------------
|
|
127
|
+
// Integration-layer invariant: exercise the 3-consumer contract that
|
|
128
|
+
// `runReviewInvokeCli` depends on. The stderr-based tests above prove
|
|
129
|
+
// the helper-level contract; these tests prove the full-dispatch
|
|
130
|
+
// consumer sequence (tryResolveTopologyForHandoff + tryTopologyDerivedExecutor
|
|
131
|
+
// twice — the shape invoked by resolveExecutorConfig for default +
|
|
132
|
+
// synthesize) adds up to ZERO resolver invocations when the cache is
|
|
133
|
+
// threaded. If a future refactor drops the `cached` argument from any
|
|
134
|
+
// consumer, the signals-line count will jump from 0 to 1-or-more and
|
|
135
|
+
// this test will fail — catching the very regression class MINOR-1 of
|
|
136
|
+
// the P9.3-m1 review flagged.
|
|
137
|
+
// ---------------------------------------------------------------------------
|
|
138
|
+
describe("runReviewInvokeCli full-dispatch consumer sequence — invariant", () => {
|
|
139
|
+
const originalEnv = { ...process.env };
|
|
140
|
+
let stderrSpy;
|
|
141
|
+
beforeEach(() => {
|
|
142
|
+
delete process.env.CLAUDECODE;
|
|
143
|
+
delete process.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS;
|
|
144
|
+
stderrSpy = vi.spyOn(process.stderr, "write").mockImplementation(() => true);
|
|
145
|
+
});
|
|
146
|
+
afterEach(() => {
|
|
147
|
+
stderrSpy.mockRestore();
|
|
148
|
+
for (const k of Object.keys(process.env)) {
|
|
149
|
+
if (!(k in originalEnv))
|
|
150
|
+
delete process.env[k];
|
|
151
|
+
}
|
|
152
|
+
for (const [k, v] of Object.entries(originalEnv)) {
|
|
153
|
+
process.env[k] = v;
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
function signalsTraceCount() {
|
|
157
|
+
return stderrSpy.mock.calls
|
|
158
|
+
.map((c) => String(c[0]))
|
|
159
|
+
.filter((l) => l.startsWith("[topology] signals:")).length;
|
|
160
|
+
}
|
|
161
|
+
it("3 consumers with shared cachedTopology → resolver runs 0 times", () => {
|
|
162
|
+
// Simulate the runReviewInvokeCli full-dispatch sequence:
|
|
163
|
+
// 1. runReviewInvokeCli resolves once at the top (we fabricate the
|
|
164
|
+
// result here as `cachedTopology` — NOT included in the spy count).
|
|
165
|
+
// 2. tryResolveTopologyForHandoff(config, cachedTopology) — coordinator_start
|
|
166
|
+
// path would have called this but it returns earlier; included here
|
|
167
|
+
// for completeness of the 3-consumer contract.
|
|
168
|
+
// 3. tryTopologyDerivedExecutor ×2 (default + synthesize via
|
|
169
|
+
// resolveExecutorConfig).
|
|
170
|
+
const cachedTopology = CACHED_LITELLM_TOPOLOGY;
|
|
171
|
+
const config = { llm_base_url: "http://localhost:4000" };
|
|
172
|
+
tryResolveTopologyForHandoff(config, cachedTopology);
|
|
173
|
+
tryTopologyDerivedExecutor(config, FAKE_HOME, cachedTopology);
|
|
174
|
+
tryTopologyDerivedExecutor(config, FAKE_HOME, cachedTopology);
|
|
175
|
+
// ZERO resolver calls: cache bypassed all 3 consumers.
|
|
176
|
+
expect(signalsTraceCount()).toBe(0);
|
|
177
|
+
});
|
|
178
|
+
it("regression probe: 3 consumers with cached=undefined → resolver runs 3 times", () => {
|
|
179
|
+
// This is the PRE-fix behaviour. If someone accidentally reverts the
|
|
180
|
+
// caching (drops the `cached` argument from all 3 consumers), the
|
|
181
|
+
// count would be 3 — proving the test catches the exact regression.
|
|
182
|
+
process.env.CLAUDECODE = "1";
|
|
183
|
+
const config = { llm_base_url: "http://localhost:4000" };
|
|
184
|
+
tryResolveTopologyForHandoff(config);
|
|
185
|
+
tryTopologyDerivedExecutor(config, FAKE_HOME);
|
|
186
|
+
tryTopologyDerivedExecutor(config, FAKE_HOME);
|
|
187
|
+
expect(signalsTraceCount()).toBe(3);
|
|
188
|
+
});
|
|
189
|
+
it("3 consumers with cachedTopology=null → resolver runs 0 times, all return null", () => {
|
|
190
|
+
// `null` propagation: all 3 consumers see cached=null and short-circuit
|
|
191
|
+
// without invoking the resolver.
|
|
192
|
+
const config = { llm_base_url: "http://localhost:4000" };
|
|
193
|
+
const descriptor = tryResolveTopologyForHandoff(config, null);
|
|
194
|
+
const exec1 = tryTopologyDerivedExecutor(config, FAKE_HOME, null);
|
|
195
|
+
const exec2 = tryTopologyDerivedExecutor(config, FAKE_HOME, null);
|
|
196
|
+
expect(descriptor).toBeNull();
|
|
197
|
+
expect(exec1).toBeNull();
|
|
198
|
+
expect(exec2).toBeNull();
|
|
199
|
+
expect(signalsTraceCount()).toBe(0);
|
|
200
|
+
});
|
|
201
|
+
});
|