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,656 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Inline-HTTP review unit executor — Phase 2 of host runtime decoupling.
|
|
4
|
+
*
|
|
5
|
+
* Executes a single bounded review unit (lens or synthesize) by directly
|
|
6
|
+
* calling an LLM HTTP endpoint (Anthropic / OpenAI / Grok / LM Studio)
|
|
7
|
+
* from the TS process.
|
|
8
|
+
*
|
|
9
|
+
* # When to use
|
|
10
|
+
*
|
|
11
|
+
* - **standalone host**: TS process invocation with no Claude Code or Codex
|
|
12
|
+
* CLI session — direct LLM call is the only option.
|
|
13
|
+
* - **direct provider combinations**: any supported API-key/local provider.
|
|
14
|
+
*
|
|
15
|
+
* # Inline content mode (Phase 2 design decision)
|
|
16
|
+
*
|
|
17
|
+
* A direct HTTP LLM call has no host tools available. Therefore the executor
|
|
18
|
+
* must inline all needed context into the prompt:
|
|
19
|
+
*
|
|
20
|
+
* - Materialized input (target content): already inline in the prompt packet
|
|
21
|
+
* - Domain documents: NOT inlined by default — packet only references them
|
|
22
|
+
* - Review context: already bounded by the prompt packet contract
|
|
23
|
+
*
|
|
24
|
+
* Phase 2 inline embedding is **opt-in** via `--embed-domain-docs` flag.
|
|
25
|
+
* When enabled, domain doc references in the packet are expanded into inline
|
|
26
|
+
* content. When disabled, the executor warns that the LLM may produce
|
|
27
|
+
* "domain doc not accessible" notes — acceptable for first-pass exploration
|
|
28
|
+
* but not for production review.
|
|
29
|
+
*
|
|
30
|
+
* # Tool model
|
|
31
|
+
*
|
|
32
|
+
* No tools are made available to the LLM. The LLM produces a single
|
|
33
|
+
* completion that is the lens output markdown. No iterative tool-calling
|
|
34
|
+
* loop (deferred to Phase 3 if needed).
|
|
35
|
+
*
|
|
36
|
+
* # Provider selection
|
|
37
|
+
*
|
|
38
|
+
* Reuses the core LLM caller resolution:
|
|
39
|
+
* 1. --provider flag (caller-explicit)
|
|
40
|
+
* 2. `.onto/settings.json` `llm` switcher
|
|
41
|
+
* 3. explicit provider validation
|
|
42
|
+
*
|
|
43
|
+
* The `host_runtime` reported in the JSON output reflects the resolved
|
|
44
|
+
* provider (`anthropic` / `openai` / `grok` / `lmstudio`), not the orchestrator host.
|
|
45
|
+
*/
|
|
46
|
+
import fs from "node:fs/promises";
|
|
47
|
+
import path from "node:path";
|
|
48
|
+
import { parseArgs } from "node:util";
|
|
49
|
+
import { pathToFileURL } from "node:url";
|
|
50
|
+
import { callLlm, resolveLlmProviderConfig, } from "../llm/llm-caller.js";
|
|
51
|
+
import { callLlmWithTools, } from "../llm/llm-tool-loop.js";
|
|
52
|
+
import { ONTO_DEFAULT_TOOLS } from "./onto-tools.js";
|
|
53
|
+
import { embedInlineContext } from "../review/inline-context-embedder.js";
|
|
54
|
+
import { parsePacketBoundaryPolicy } from "../review/packet-boundary-policy.js";
|
|
55
|
+
import { parseParticipatingLensPaths } from "../review/participating-lens-paths.js";
|
|
56
|
+
import { auditCitations } from "../review/citation-audit.js";
|
|
57
|
+
import { assertNoUnsupportedConfigFiles, projectSettingsPath, } from "../discovery/settings-chain.js";
|
|
58
|
+
import { stripWrappingCodeFence } from "./strip-wrapping-code-fence.js";
|
|
59
|
+
function requireString(value, optionName) {
|
|
60
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
61
|
+
throw new Error(`Missing required option --${optionName}`);
|
|
62
|
+
}
|
|
63
|
+
return value;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* System prompt for inline (Tier 2) mode: no tools, all context inlined.
|
|
67
|
+
*
|
|
68
|
+
* The lens variant focuses on bounded finding production from inlined target +
|
|
69
|
+
* domain content. The synthesize variant emphasises deliberation across already-
|
|
70
|
+
* inlined lens outputs and preservation of the 8 required sections — even when
|
|
71
|
+
* disagreement cannot be resolved from inlined evidence alone.
|
|
72
|
+
*/
|
|
73
|
+
function buildSystemPromptInline(unitId, unitKind, packetPath, outputPath) {
|
|
74
|
+
if (unitKind === "synthesize") {
|
|
75
|
+
return buildSynthesizeSystemPromptInline(unitId, packetPath, outputPath);
|
|
76
|
+
}
|
|
77
|
+
return buildLensSystemPromptInline(unitId, unitKind, packetPath, outputPath);
|
|
78
|
+
}
|
|
79
|
+
function buildLensSystemPromptInline(unitId, unitKind, packetPath, outputPath) {
|
|
80
|
+
return `You are executing a single bounded review unit as a ContextIsolatedReasoningUnit.
|
|
81
|
+
|
|
82
|
+
Unit id: ${unitId}
|
|
83
|
+
Unit kind: ${unitKind}
|
|
84
|
+
Authoritative prompt packet path: ${packetPath}
|
|
85
|
+
Canonical output path: ${outputPath}
|
|
86
|
+
|
|
87
|
+
Rules:
|
|
88
|
+
- Treat the prompt packet (in the user message) as the authoritative contract.
|
|
89
|
+
- All content needed for this task has been inlined into the prompt packet.
|
|
90
|
+
You do NOT have file system access or any tools — produce your answer from
|
|
91
|
+
the inlined content alone.
|
|
92
|
+
- Treat the Boundary Policy and Effective Boundary State in the packet as hard constraints.
|
|
93
|
+
- Stay within the smallest sufficient finding set implied by the packet.
|
|
94
|
+
- Produce ONLY the final markdown content for the canonical output path.
|
|
95
|
+
- Do not wrap the answer in code fences.
|
|
96
|
+
- Do not add commentary before or after the markdown.
|
|
97
|
+
- Do not modify repository files (you cannot — no tools available).
|
|
98
|
+
- Do not change the required output structure from the packet.
|
|
99
|
+
- If the packet asks you to preserve disagreement or uncertainty, preserve it explicitly.
|
|
100
|
+
- If you cannot complete the task with the inlined content alone, state the
|
|
101
|
+
limitation as "insufficient content within boundary" rather than fabricating.`;
|
|
102
|
+
}
|
|
103
|
+
function buildSynthesizeSystemPromptInline(unitId, packetPath, outputPath) {
|
|
104
|
+
return `You are the synthesize actor for a 9-lens review. You are a ContextIsolatedReasoningUnit.
|
|
105
|
+
|
|
106
|
+
Unit id: ${unitId}
|
|
107
|
+
Unit kind: synthesize
|
|
108
|
+
Authoritative prompt packet path: ${packetPath}
|
|
109
|
+
Canonical output path: ${outputPath}
|
|
110
|
+
|
|
111
|
+
OUTPUT FORMAT — READ FIRST:
|
|
112
|
+
- Your entire response is written verbatim to the canonical output path as-is. No post-processing will change your first or last lines.
|
|
113
|
+
- The FIRST character of your response MUST be the YAML frontmatter delimiter "-" (three dashes on line 1). Do NOT begin your response with three backticks, a language tag like "yaml" or "markdown", or any prose preface.
|
|
114
|
+
- The LAST character of your response MUST be part of the final markdown section body. Do NOT end your response with three backticks or a closing code fence.
|
|
115
|
+
- Do NOT wrap the entire answer in a \`\`\`yaml, \`\`\`markdown, or any code block. The output file must be valid markdown with YAML frontmatter, not a markdown file that contains your answer as a code block.
|
|
116
|
+
- Inner code blocks INSIDE the markdown body (e.g. citing a small code snippet in a finding) are allowed. The rule applies only to an outer wrapper around the whole response.
|
|
117
|
+
|
|
118
|
+
Your job:
|
|
119
|
+
- Read every Participating Lens Output that is inlined in the prompt packet.
|
|
120
|
+
- Read the Controlled Lens Deliberation Result that is inlined in the prompt packet.
|
|
121
|
+
- Classify findings into Consensus, Conditional Consensus, Disagreement, and Unique Finding Tagging.
|
|
122
|
+
- Do not perform deliberation yourself. Controlled lens deliberation already produced the authoritative resolution or unresolved-disagreement record.
|
|
123
|
+
- Integrate Axiology proposed perspectives without erasing the lens-level evidence.
|
|
124
|
+
- Write a comprehensive Final Review Result section grounded in the full inlined artifact set.
|
|
125
|
+
|
|
126
|
+
Rules:
|
|
127
|
+
- Treat the prompt packet (in the user message) as the authoritative contract.
|
|
128
|
+
- All content needed for this task has been inlined into the prompt packet.
|
|
129
|
+
You do NOT have file system access or any tools — produce your answer from
|
|
130
|
+
the inlined content alone.
|
|
131
|
+
- Treat the Boundary Policy and Effective Boundary State in the packet as hard constraints.
|
|
132
|
+
- Every required output section in the packet is MANDATORY. Do not rename, merge, or omit required headings, even if a section is empty (state "(none)" instead).
|
|
133
|
+
- Preserve lens-level evidence in your output — never paraphrase a lens away from its citation.
|
|
134
|
+
- Set deliberation_status in the YAML frontmatter to "performed".
|
|
135
|
+
- Produce ONLY the final markdown content for the canonical output path.
|
|
136
|
+
- Do not add commentary before or after the markdown.
|
|
137
|
+
- If controlled deliberation preserved an unresolved disagreement, preserve that limitation explicitly under Deliberation Decision.`;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* System prompt for tool-native (Tier 1) mode: read-only tools available,
|
|
141
|
+
* boundary enforced by the TS process at tool-call time.
|
|
142
|
+
*
|
|
143
|
+
* lens vs synthesize variants differ in role framing and which subdirectories
|
|
144
|
+
* the model is encouraged to traverse. For synthesize, .onto traversal is
|
|
145
|
+
* unlocked at the boundary layer (allowOntoTraversal=true) so search/list can
|
|
146
|
+
* discover lens outputs under .onto/review/<session>/round1.
|
|
147
|
+
*/
|
|
148
|
+
function buildSystemPromptToolNative(unitId, unitKind, packetPath, outputPath) {
|
|
149
|
+
if (unitKind === "synthesize") {
|
|
150
|
+
return buildSynthesizeSystemPromptToolNative(unitId, packetPath, outputPath);
|
|
151
|
+
}
|
|
152
|
+
return buildLensSystemPromptToolNative(unitId, unitKind, packetPath, outputPath);
|
|
153
|
+
}
|
|
154
|
+
function buildLensSystemPromptToolNative(unitId, unitKind, packetPath, outputPath) {
|
|
155
|
+
return `You are executing a single bounded review unit as a ContextIsolatedReasoningUnit.
|
|
156
|
+
|
|
157
|
+
Unit id: ${unitId}
|
|
158
|
+
Unit kind: ${unitKind}
|
|
159
|
+
Authoritative prompt packet path: ${packetPath}
|
|
160
|
+
Canonical output path: ${outputPath}
|
|
161
|
+
|
|
162
|
+
You have THREE read-only tools to fetch additional context as needed:
|
|
163
|
+
- read_file(path, start_line?, end_line?) — read up to 2000 lines of a file
|
|
164
|
+
- list_directory(path) — list entries in a directory (skips .git, node_modules, .onto, dist, build)
|
|
165
|
+
- search_content(pattern, path?, case_insensitive?) — find literal substring matches under a directory
|
|
166
|
+
|
|
167
|
+
Tools are bounded:
|
|
168
|
+
- Paths must resolve inside projectRoot or ontoHome. Boundary violations return an error you can recover from by trying a different path.
|
|
169
|
+
- Use search_content to locate references first, then read_file to inspect specific sections.
|
|
170
|
+
- Prefer narrow reads (start_line/end_line) over re-reading the same large file.
|
|
171
|
+
|
|
172
|
+
Rules:
|
|
173
|
+
- Treat the prompt packet (in the user message) as the authoritative contract.
|
|
174
|
+
- Treat the Boundary Policy and Effective Boundary State in the packet as hard constraints.
|
|
175
|
+
- Use tools ONLY when the packet's inlined content is insufficient — do not browse for browsing's sake.
|
|
176
|
+
- Stay within the smallest sufficient finding set implied by the packet.
|
|
177
|
+
- After your tool exploration, produce ONLY the final markdown content for the canonical output path.
|
|
178
|
+
- Do not wrap the answer in code fences.
|
|
179
|
+
- Do not add commentary before or after the markdown.
|
|
180
|
+
- Do not change the required output structure from the packet.
|
|
181
|
+
- If the packet asks you to preserve disagreement or uncertainty, preserve it explicitly.
|
|
182
|
+
- If even with tools you cannot complete the task, state the limitation as "insufficient content within boundary" rather than fabricating.`;
|
|
183
|
+
}
|
|
184
|
+
function buildSynthesizeSystemPromptToolNative(unitId, packetPath, outputPath) {
|
|
185
|
+
return `You are the synthesize actor for a 9-lens review. You are a ContextIsolatedReasoningUnit.
|
|
186
|
+
|
|
187
|
+
Unit id: ${unitId}
|
|
188
|
+
Unit kind: synthesize
|
|
189
|
+
Authoritative prompt packet path: ${packetPath}
|
|
190
|
+
Canonical output path: ${outputPath}
|
|
191
|
+
|
|
192
|
+
OUTPUT FORMAT — READ FIRST:
|
|
193
|
+
- Your FINAL message (after any tool calls complete) is written verbatim to the canonical output path.
|
|
194
|
+
- The FIRST character of your final message MUST be the YAML frontmatter delimiter "-" (three dashes on line 1). Do NOT begin with three backticks, a language tag like "yaml" or "markdown", or any prose preface.
|
|
195
|
+
- The LAST character of your final message MUST be part of the final markdown section body. Do NOT end with three backticks or a closing code fence.
|
|
196
|
+
- Do NOT wrap the entire answer in a \`\`\`yaml, \`\`\`markdown, or any code block. The output file must be valid markdown with YAML frontmatter, not a markdown file that contains your answer as a code block.
|
|
197
|
+
- Inner code blocks INSIDE the markdown body (e.g. citing a small code snippet in a finding) are allowed. The rule applies only to an outer wrapper around the whole response.
|
|
198
|
+
|
|
199
|
+
You have THREE read-only tools:
|
|
200
|
+
- read_file(path, start_line?, end_line?) — read up to 2000 lines of a file
|
|
201
|
+
- list_directory(path) — list entries in a directory
|
|
202
|
+
- search_content(pattern, path?, case_insensitive?) — find literal substring matches under a directory
|
|
203
|
+
|
|
204
|
+
Tool boundary for synthesize:
|
|
205
|
+
- Paths must resolve inside projectRoot or ontoHome.
|
|
206
|
+
- Lens outputs live under \`.onto/review/<session>/round1/<lens>.md\`. The packet's "Participating Lens Outputs" section lists the exact paths — call read_file on those paths to read each lens's findings.
|
|
207
|
+
- The controlled lens deliberation result lives at the packet's "Controlled Lens Deliberation Result" path — call read_file on that path before classifying disagreements.
|
|
208
|
+
- The materialized input (the actual review target) is also referenced in the packet — read_file it whenever you need to verify a contested claim against the source.
|
|
209
|
+
- For synthesize, .onto traversal IS allowed (unlike lens runs) so list_directory and search_content work under .onto/review.
|
|
210
|
+
|
|
211
|
+
Your job:
|
|
212
|
+
- Read every Participating Lens Output via read_file. Do not skip any successful lens.
|
|
213
|
+
- Read the Controlled Lens Deliberation Result via read_file.
|
|
214
|
+
- Classify findings: Consensus, Conditional Consensus, Disagreement, Unique Finding Tagging.
|
|
215
|
+
- Do not perform deliberation yourself. Controlled lens deliberation already produced the authoritative resolution or unresolved-disagreement record.
|
|
216
|
+
- Integrate Axiology proposed perspectives without erasing lens-level evidence.
|
|
217
|
+
- Write a comprehensive Final Review Result section grounded in the full artifact set.
|
|
218
|
+
|
|
219
|
+
Rules:
|
|
220
|
+
- Treat the prompt packet (in the user message) as the authoritative contract.
|
|
221
|
+
- Treat the Boundary Policy and Effective Boundary State in the packet as hard constraints.
|
|
222
|
+
- Every required output section in the packet is MANDATORY. Do not rename, merge, or omit required headings — write "(none)" if a section has no content.
|
|
223
|
+
- Preserve lens-level evidence — never paraphrase a lens away from its citation.
|
|
224
|
+
- Set deliberation_status in the YAML frontmatter to "performed".
|
|
225
|
+
- Produce ONLY the final markdown content for the canonical output path.
|
|
226
|
+
- Do not add commentary before or after the markdown.
|
|
227
|
+
- If a lens output file is missing or unreadable via read_file, list it under Degraded Lens Failures rather than fabricating its findings.`;
|
|
228
|
+
}
|
|
229
|
+
function parseToolMode(raw) {
|
|
230
|
+
if (raw === "native" || raw === "inline" || raw === "auto")
|
|
231
|
+
return raw;
|
|
232
|
+
if (raw === undefined || raw === "")
|
|
233
|
+
return "auto";
|
|
234
|
+
throw new Error(`Invalid --tool-mode value: ${String(raw)} (expected native | inline | auto)`);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Map a resolved provider to the tool-loop driver's provider enum. Returns
|
|
238
|
+
* `null` for `codex` because the Codex worker path has its own
|
|
239
|
+
* agentic scaffold and isn't routed through callLlmWithTools — auto mode
|
|
240
|
+
* should fall back to inline in that case.
|
|
241
|
+
*/
|
|
242
|
+
function asToolLoopProvider(provider) {
|
|
243
|
+
if (provider === "anthropic" ||
|
|
244
|
+
provider === "openai" ||
|
|
245
|
+
provider === "grok" ||
|
|
246
|
+
provider === "lmstudio") {
|
|
247
|
+
return provider;
|
|
248
|
+
}
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
async function loadOntoConfig(projectRoot) {
|
|
252
|
+
await assertNoUnsupportedConfigFiles(projectRoot);
|
|
253
|
+
const configPath = projectSettingsPath(projectRoot);
|
|
254
|
+
try {
|
|
255
|
+
const parsed = JSON.parse(await fs.readFile(configPath, "utf8"));
|
|
256
|
+
if (parsed && typeof parsed === "object") {
|
|
257
|
+
return parsed;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
catch (error) {
|
|
261
|
+
if (error.code === "ENOENT")
|
|
262
|
+
return {};
|
|
263
|
+
throw error;
|
|
264
|
+
}
|
|
265
|
+
return {};
|
|
266
|
+
}
|
|
267
|
+
async function readPacketAndEmbed(packetPath, ontoHome, projectRoot, embedDomainDocs) {
|
|
268
|
+
const packetText = await fs.readFile(packetPath, "utf8");
|
|
269
|
+
if (!embedDomainDocs) {
|
|
270
|
+
return packetText;
|
|
271
|
+
}
|
|
272
|
+
return embedInlineContext(packetText, { ontoHome, projectRoot });
|
|
273
|
+
}
|
|
274
|
+
function deriveHostRuntime(provider) {
|
|
275
|
+
if (provider === "anthropic")
|
|
276
|
+
return "anthropic";
|
|
277
|
+
if (provider === "openai")
|
|
278
|
+
return "openai";
|
|
279
|
+
if (provider === "grok")
|
|
280
|
+
return "grok";
|
|
281
|
+
if (provider === "lmstudio")
|
|
282
|
+
return "lmstudio";
|
|
283
|
+
if (provider === "codex")
|
|
284
|
+
return "codex";
|
|
285
|
+
throw new Error("inline-http executor requires an explicit llm provider.");
|
|
286
|
+
}
|
|
287
|
+
export async function runInlineHttpReviewUnitExecutorCli(argv) {
|
|
288
|
+
const { values } = parseArgs({
|
|
289
|
+
options: {
|
|
290
|
+
"project-root": { type: "string", default: "." },
|
|
291
|
+
"session-root": { type: "string" },
|
|
292
|
+
"onto-home": { type: "string" },
|
|
293
|
+
"unit-id": { type: "string" },
|
|
294
|
+
"unit-kind": { type: "string" },
|
|
295
|
+
"packet-path": { type: "string" },
|
|
296
|
+
"output-path": { type: "string" },
|
|
297
|
+
// LLM provider selection (reuses llm-caller bridge)
|
|
298
|
+
provider: { type: "string" }, // anthropic | openai | grok | lmstudio | codex
|
|
299
|
+
auth: { type: "string" },
|
|
300
|
+
"api-key-env": { type: "string" },
|
|
301
|
+
"llm-base-url": { type: "string" },
|
|
302
|
+
model: { type: "string" },
|
|
303
|
+
"reasoning-effort": { type: "string" },
|
|
304
|
+
"max-tokens": { type: "string" },
|
|
305
|
+
// Inline embedding control
|
|
306
|
+
"embed-domain-docs": { type: "boolean", default: false },
|
|
307
|
+
// Tool mode: native (Tier 1 function-calling loop) | inline (Tier 2,
|
|
308
|
+
// current behavior) | auto (try native, fall back to inline if the
|
|
309
|
+
// provider rejects tools or no tool_calls came back).
|
|
310
|
+
"tool-mode": { type: "string", default: "auto" },
|
|
311
|
+
// Citation audit (A5) configuration. The audit is post-flight and
|
|
312
|
+
// warning-only; this flag tunes how aggressive the extractor is about
|
|
313
|
+
// what counts as a "significant quote". Default 20 skips noise like
|
|
314
|
+
// `"performed"`, `` `x.ts` ``, etc. Lower to audit shorter citations;
|
|
315
|
+
// raise to suppress moderate-length quotes that produce false positives
|
|
316
|
+
// for a given synthesize template.
|
|
317
|
+
"min-quote-length": { type: "string" },
|
|
318
|
+
},
|
|
319
|
+
strict: true,
|
|
320
|
+
allowPositionals: false,
|
|
321
|
+
args: argv,
|
|
322
|
+
});
|
|
323
|
+
const projectRoot = path.resolve(requireString(values["project-root"], "project-root"));
|
|
324
|
+
const sessionRoot = path.resolve(requireString(values["session-root"], "session-root"));
|
|
325
|
+
const ontoHome = path.resolve(typeof values["onto-home"] === "string" && values["onto-home"].length > 0
|
|
326
|
+
? values["onto-home"]
|
|
327
|
+
: path.join(process.env.HOME ?? "", ".onto"));
|
|
328
|
+
const unitId = requireString(values["unit-id"], "unit-id");
|
|
329
|
+
const unitKind = requireString(values["unit-kind"], "unit-kind");
|
|
330
|
+
const packetPath = path.resolve(requireString(values["packet-path"], "packet-path"));
|
|
331
|
+
const outputPath = path.resolve(requireString(values["output-path"], "output-path"));
|
|
332
|
+
const embedDomainDocs = Boolean(values["embed-domain-docs"]);
|
|
333
|
+
const maxTokensRaw = values["max-tokens"];
|
|
334
|
+
const maxTokens = typeof maxTokensRaw === "string" && maxTokensRaw.length > 0
|
|
335
|
+
? Number.parseInt(maxTokensRaw, 10)
|
|
336
|
+
: 4096;
|
|
337
|
+
// Resolve LLM provider config: CLI flags → OntoConfig.
|
|
338
|
+
const ontoConfig = await loadOntoConfig(projectRoot);
|
|
339
|
+
const cliOverrides = {};
|
|
340
|
+
const providerValue = values.provider;
|
|
341
|
+
if (providerValue === "anthropic" ||
|
|
342
|
+
providerValue === "openai" ||
|
|
343
|
+
providerValue === "grok" ||
|
|
344
|
+
providerValue === "lmstudio" ||
|
|
345
|
+
providerValue === "codex") {
|
|
346
|
+
cliOverrides.provider = providerValue;
|
|
347
|
+
}
|
|
348
|
+
const authValue = values.auth;
|
|
349
|
+
if (authValue === "api_key" || authValue === "oauth" || authValue === "local") {
|
|
350
|
+
cliOverrides.auth = authValue;
|
|
351
|
+
}
|
|
352
|
+
if (typeof values["llm-base-url"] === "string") {
|
|
353
|
+
cliOverrides.base_url = values["llm-base-url"];
|
|
354
|
+
}
|
|
355
|
+
if (typeof values["api-key-env"] === "string") {
|
|
356
|
+
cliOverrides.api_key_env = values["api-key-env"];
|
|
357
|
+
}
|
|
358
|
+
if (typeof values.model === "string") {
|
|
359
|
+
cliOverrides.model = values.model;
|
|
360
|
+
}
|
|
361
|
+
if (typeof values["reasoning-effort"] === "string") {
|
|
362
|
+
cliOverrides.reasoning_effort = values["reasoning-effort"];
|
|
363
|
+
}
|
|
364
|
+
const llmPartial = resolveLlmProviderConfig({
|
|
365
|
+
config: ontoConfig,
|
|
366
|
+
cliOverrides,
|
|
367
|
+
});
|
|
368
|
+
// Review Recovery PR-1 (R1 observability symmetry): each executor process
|
|
369
|
+
// emits `[plan:executor]` once at startup so the parent's `[plan]` lines and
|
|
370
|
+
// the executor's LLM-call lines are stitchable into a single stderr trace.
|
|
371
|
+
// Before PR-1, the process boundary was a blind spot: the parent resolved
|
|
372
|
+
// a provider, but the child could silently re-resolve differently and
|
|
373
|
+
// operators had no way to see it.
|
|
374
|
+
process.stderr.write(`[plan:executor] kind=inline-http unit_id=${unitId} provider=${llmPartial.provider ?? "(unresolved)"} model=${llmPartial.model_id ?? "(unresolved)"} base_url=${llmPartial.base_url ?? "(default)"} tool_mode_request=${values["tool-mode"] ?? "auto"}\n`);
|
|
375
|
+
const requestedToolMode = parseToolMode(values["tool-mode"]);
|
|
376
|
+
// Determine which Tier the auto/native paths should attempt. codex provider
|
|
377
|
+
// bypasses callLlmWithTools entirely — auto
|
|
378
|
+
// collapses to inline there.
|
|
379
|
+
const toolLoopProvider = asToolLoopProvider(llmPartial.provider);
|
|
380
|
+
if (requestedToolMode === "native" && toolLoopProvider === null) {
|
|
381
|
+
throw new Error(`--tool-mode=native requires provider in {anthropic, openai, grok, lmstudio}; got "${llmPartial.provider ?? "(auto)"}".`);
|
|
382
|
+
}
|
|
383
|
+
// Read packet (raw) first so we can inspect its declared Boundary Policy
|
|
384
|
+
// BEFORE deciding whether native mode is admissible. Embedding happens
|
|
385
|
+
// after, so boundary policy is taken from the authored packet, not from
|
|
386
|
+
// any embedded material.
|
|
387
|
+
const rawPacketText = await fs.readFile(packetPath, "utf8");
|
|
388
|
+
const packetPolicy = parsePacketBoundaryPolicy(rawPacketText);
|
|
389
|
+
// A1 + A4 consistency check: a packet cannot BOTH deny filesystem AND require
|
|
390
|
+
// tools, because today's tools (read_file / list_directory / search_content)
|
|
391
|
+
// are all filesystem-scoped. Reject the packet upfront rather than letting
|
|
392
|
+
// the two blocks below reach contradictory conclusions.
|
|
393
|
+
if (packetPolicy.filesystem === "denied" &&
|
|
394
|
+
packetPolicy.tools === "required") {
|
|
395
|
+
throw new Error(`Packet Boundary Policy is internally inconsistent for unit ${unitId}: ` +
|
|
396
|
+
`Filesystem: ${packetPolicy.filesystemRaw ?? "denied"} AND Tools: ${packetPolicy.toolsRaw ?? "required"}. ` +
|
|
397
|
+
"All current executor tools (read_file / list_directory / search_content) require filesystem access, " +
|
|
398
|
+
"so a packet cannot deny filesystem while also requiring tools. " +
|
|
399
|
+
"Remove one of the two declarations.");
|
|
400
|
+
}
|
|
401
|
+
// A1 precedence rule: packet-declared Filesystem: denied forbids tool-native
|
|
402
|
+
// mode regardless of CLI flag, because the packet is the authoritative
|
|
403
|
+
// contract for this unit. If the caller explicitly asked for native, surface
|
|
404
|
+
// the conflict as a fail-fast precondition error (rather than silently
|
|
405
|
+
// changing the requested mode). Otherwise (auto), downgrade to inline and
|
|
406
|
+
// emit a one-time STDERR notice so operators can see why the tier changed.
|
|
407
|
+
let packetForcedInline = false;
|
|
408
|
+
if (packetPolicy.filesystem === "denied") {
|
|
409
|
+
if (requestedToolMode === "native") {
|
|
410
|
+
throw new Error(`--tool-mode=native conflicts with packet's Boundary Policy (Filesystem: ${packetPolicy.filesystemRaw ?? "denied"}). ` +
|
|
411
|
+
"The packet declares no filesystem access; tool-native mode would hand the LLM file tools in violation. " +
|
|
412
|
+
"Use --tool-mode=inline or remove the packet-level Filesystem: denied declaration.");
|
|
413
|
+
}
|
|
414
|
+
if (requestedToolMode === "auto") {
|
|
415
|
+
packetForcedInline = true;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
// A4 precedence rule (mirror of A1): packet-declared Tools: required forbids
|
|
419
|
+
// inline mode regardless of CLI flag, because a packet with path-only lens
|
|
420
|
+
// outputs CANNOT produce a faithful synthesis without tools — the LLM would
|
|
421
|
+
// fabricate citations (demonstrated in Phase 3-4 A3 benchmark, 2026-04-17,
|
|
422
|
+
// with Qwen3-30B-A3B producing a quote that grep returned 0 matches for).
|
|
423
|
+
//
|
|
424
|
+
// If the caller explicitly asked for inline, fail-fast. Under auto, try to
|
|
425
|
+
// promote to native; if the provider has no tool-loop support, fail-fast
|
|
426
|
+
// rather than silently falling back to fabrication-prone inline.
|
|
427
|
+
let packetForcedNative = false;
|
|
428
|
+
if (packetPolicy.tools === "required") {
|
|
429
|
+
if (requestedToolMode === "inline") {
|
|
430
|
+
throw new Error(`--tool-mode=inline conflicts with packet's Boundary Policy (Tools: ${packetPolicy.toolsRaw ?? "required"}). ` +
|
|
431
|
+
"The packet declares that tools are required to complete this unit (e.g. path-only lens outputs). " +
|
|
432
|
+
"Running inline mode would force the LLM to answer without the cited sources, which has been " +
|
|
433
|
+
"shown to produce fabricated citations. Use --tool-mode=native or --tool-mode=auto (with a " +
|
|
434
|
+
"provider that supports function calling), or remove the packet-level Tools: required declaration.");
|
|
435
|
+
}
|
|
436
|
+
if (requestedToolMode === "auto" && toolLoopProvider === null) {
|
|
437
|
+
throw new Error(`--tool-mode=auto + packet Boundary Policy (Tools: ${packetPolicy.toolsRaw ?? "required"}) cannot be satisfied: ` +
|
|
438
|
+
`the resolved provider (${cliOverrides.provider ?? "default-auto"}) does not support the function-calling tool loop. ` +
|
|
439
|
+
"Select a provider in {anthropic, openai, grok, lmstudio} via --provider, or edit the packet to remove Tools: required.");
|
|
440
|
+
}
|
|
441
|
+
if (requestedToolMode === "auto") {
|
|
442
|
+
packetForcedNative = true;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
const tryNative = !packetForcedInline &&
|
|
446
|
+
(requestedToolMode === "native" ||
|
|
447
|
+
packetForcedNative ||
|
|
448
|
+
(requestedToolMode === "auto" && toolLoopProvider !== null));
|
|
449
|
+
// Read packet, optionally embed inline content. Embedding is independent of
|
|
450
|
+
// tool_mode — even tool-native runs benefit from packet pre-population so
|
|
451
|
+
// the LLM doesn't have to re-discover the obvious targets.
|
|
452
|
+
const userPrompt = await readPacketAndEmbed(packetPath, ontoHome, projectRoot, embedDomainDocs);
|
|
453
|
+
if (packetForcedInline) {
|
|
454
|
+
process.stderr.write(`[onto] tool-native downgraded to inline for unit ${unitId}: packet declares Boundary Policy Filesystem: ${packetPolicy.filesystemRaw ?? "denied"}. ` +
|
|
455
|
+
"The packet's policy takes precedence over --tool-mode=auto.\n");
|
|
456
|
+
}
|
|
457
|
+
if (packetForcedNative) {
|
|
458
|
+
process.stderr.write(`[onto] inline auto-promoted to tool-native for unit ${unitId}: packet declares Boundary Policy Tools: ${packetPolicy.toolsRaw ?? "required"}. ` +
|
|
459
|
+
"The packet's policy takes precedence over --tool-mode=auto. " +
|
|
460
|
+
"Running inline would risk fabrication when lens outputs are path-only.\n");
|
|
461
|
+
}
|
|
462
|
+
let outputText = "";
|
|
463
|
+
let modelIdUsed;
|
|
464
|
+
let inputTokensUsed = 0;
|
|
465
|
+
let outputTokensUsed = 0;
|
|
466
|
+
let toolModeUsed = "inline";
|
|
467
|
+
let toolIterations;
|
|
468
|
+
let toolCallsExecuted;
|
|
469
|
+
let nativeAttemptError;
|
|
470
|
+
if (tryNative && toolLoopProvider) {
|
|
471
|
+
const systemPrompt = buildSystemPromptToolNative(unitId, unitKind, packetPath, outputPath);
|
|
472
|
+
const modelForLoop = llmPartial.model_id ?? llmPartial.models_per_provider?.[toolLoopProvider];
|
|
473
|
+
if (!modelForLoop) {
|
|
474
|
+
throw new Error(`tool-native mode requires a model id (set --model or .onto/settings.json llm.model).`);
|
|
475
|
+
}
|
|
476
|
+
try {
|
|
477
|
+
const loopResult = await callLlmWithTools(systemPrompt, userPrompt, ONTO_DEFAULT_TOOLS, {
|
|
478
|
+
provider: toolLoopProvider,
|
|
479
|
+
model_id: modelForLoop,
|
|
480
|
+
max_tokens: maxTokens,
|
|
481
|
+
...(llmPartial.base_url ? { base_url: llmPartial.base_url } : {}),
|
|
482
|
+
}, {
|
|
483
|
+
projectRoot,
|
|
484
|
+
ontoHome,
|
|
485
|
+
// synthesize must traverse .onto/review/<session>/round1 to discover
|
|
486
|
+
// lens outputs; lens runs keep the default skip to avoid session noise.
|
|
487
|
+
allowOntoTraversal: unitKind === "synthesize",
|
|
488
|
+
});
|
|
489
|
+
outputText = loopResult.text.trim();
|
|
490
|
+
modelIdUsed = loopResult.model_id;
|
|
491
|
+
inputTokensUsed = loopResult.input_tokens;
|
|
492
|
+
outputTokensUsed = loopResult.output_tokens;
|
|
493
|
+
toolIterations = loopResult.iterations;
|
|
494
|
+
toolCallsExecuted = loopResult.tool_calls;
|
|
495
|
+
toolModeUsed = "native";
|
|
496
|
+
// Empty final text after a tool loop usually means the model only ever
|
|
497
|
+
// returned tool_use blocks and never produced a final answer (or hit
|
|
498
|
+
// the iteration cap). In ordinary auto mode we fall back to inline; when
|
|
499
|
+
// the packet declares Tools: required, native execution is the boundary.
|
|
500
|
+
if (outputText.length === 0) {
|
|
501
|
+
if (requestedToolMode === "auto" && !packetForcedNative) {
|
|
502
|
+
nativeAttemptError = `tool-native produced empty final text${loopResult.truncated_by_iteration_cap ? " (iteration cap hit)" : ""}`;
|
|
503
|
+
toolModeUsed = "inline";
|
|
504
|
+
}
|
|
505
|
+
else {
|
|
506
|
+
throw new Error(`tool-native mode produced empty final text for unit ${unitId} (iterations=${loopResult.iterations}, tool_calls=${loopResult.tool_calls}).`);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
catch (err) {
|
|
511
|
+
if (requestedToolMode === "auto" && !packetForcedNative) {
|
|
512
|
+
nativeAttemptError = err instanceof Error ? err.message : String(err);
|
|
513
|
+
toolModeUsed = "inline";
|
|
514
|
+
toolIterations = undefined;
|
|
515
|
+
toolCallsExecuted = undefined;
|
|
516
|
+
}
|
|
517
|
+
else {
|
|
518
|
+
throw err;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
if (toolModeUsed === "inline") {
|
|
523
|
+
if (nativeAttemptError) {
|
|
524
|
+
process.stderr.write(`[onto] tool-native attempt failed (${nativeAttemptError}); falling back to inline mode.\n`);
|
|
525
|
+
}
|
|
526
|
+
const systemPrompt = buildSystemPromptInline(unitId, unitKind, packetPath, outputPath);
|
|
527
|
+
const llmConfig = { ...llmPartial, max_tokens: maxTokens };
|
|
528
|
+
const result = await callLlm(systemPrompt, userPrompt, llmConfig);
|
|
529
|
+
outputText = result.text.trim();
|
|
530
|
+
modelIdUsed = result.model_id;
|
|
531
|
+
inputTokensUsed = result.input_tokens;
|
|
532
|
+
outputTokensUsed = result.output_tokens;
|
|
533
|
+
}
|
|
534
|
+
// Defensive post-process: some models (observed on Qwen3-30B-A3B in Phase
|
|
535
|
+
// 3-4 A2 bench) ignore the "Do not wrap in code fences" prompt rule and
|
|
536
|
+
// emit the entire markdown answer inside a ```yaml or ```markdown block.
|
|
537
|
+
// Strip a single outer wrapping fence pair if present; leave inner code
|
|
538
|
+
// blocks and well-formed markdown untouched. See strip-wrapping-code-fence.ts.
|
|
539
|
+
outputText = stripWrappingCodeFence(outputText);
|
|
540
|
+
if (outputText.length === 0) {
|
|
541
|
+
throw new Error(`Inline-HTTP executor produced empty output for unit ${unitId} (provider: ${cliOverrides.provider ?? "auto"}, tool_mode: ${toolModeUsed}).`);
|
|
542
|
+
}
|
|
543
|
+
// Write output file.
|
|
544
|
+
await fs.mkdir(path.dirname(outputPath), { recursive: true });
|
|
545
|
+
await fs.writeFile(outputPath, `${outputText}\n`, "utf8");
|
|
546
|
+
// A5 citation audit — post-flight fabrication detector for synthesize units.
|
|
547
|
+
// Parses the packet's Participating Lens Outputs section, reads each file,
|
|
548
|
+
// and checks whether every significant quoted string in the output exists
|
|
549
|
+
// in at least one lens. Warning-only: never fails the executor. Wrapped in
|
|
550
|
+
// try/catch so parser or filesystem errors never escape the audit layer.
|
|
551
|
+
const minQuoteLengthRaw = values["min-quote-length"];
|
|
552
|
+
let minQuoteLength;
|
|
553
|
+
if (typeof minQuoteLengthRaw === "string" && minQuoteLengthRaw.length > 0) {
|
|
554
|
+
const parsed = Number.parseInt(minQuoteLengthRaw, 10);
|
|
555
|
+
if (Number.isFinite(parsed) && parsed > 0) {
|
|
556
|
+
minQuoteLength = parsed;
|
|
557
|
+
}
|
|
558
|
+
else {
|
|
559
|
+
throw new Error(`Invalid --min-quote-length value: ${String(minQuoteLengthRaw)} (expected a positive integer).`);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
let citationAudit;
|
|
563
|
+
if (unitKind === "synthesize") {
|
|
564
|
+
try {
|
|
565
|
+
citationAudit = await runCitationAudit(rawPacketText, outputText, projectRoot, unitId, minQuoteLength);
|
|
566
|
+
}
|
|
567
|
+
catch (err) {
|
|
568
|
+
process.stderr.write(`[onto] citation audit skipped for unit ${unitId}: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
const executorResult = {
|
|
572
|
+
unit_id: unitId,
|
|
573
|
+
unit_kind: unitKind,
|
|
574
|
+
packet_path: packetPath,
|
|
575
|
+
output_path: outputPath,
|
|
576
|
+
realization: "ts_inline_http",
|
|
577
|
+
host_runtime: deriveHostRuntime(llmPartial.provider),
|
|
578
|
+
tool_mode: toolModeUsed,
|
|
579
|
+
input_tokens: inputTokensUsed,
|
|
580
|
+
output_tokens: outputTokensUsed,
|
|
581
|
+
...(modelIdUsed !== undefined ? { model_id: modelIdUsed } : {}),
|
|
582
|
+
...(toolIterations !== undefined ? { tool_iterations: toolIterations } : {}),
|
|
583
|
+
...(toolCallsExecuted !== undefined ? { tool_calls: toolCallsExecuted } : {}),
|
|
584
|
+
...(packetForcedInline ? { packet_policy_downgrade: true } : {}),
|
|
585
|
+
...(packetForcedNative ? { packet_policy_promotion: true } : {}),
|
|
586
|
+
...(citationAudit !== undefined ? { citation_audit: citationAudit } : {}),
|
|
587
|
+
};
|
|
588
|
+
console.log(JSON.stringify(executorResult, null, 2));
|
|
589
|
+
return 0;
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* A5 citation audit helper. Reads the lens output files referenced in the
|
|
593
|
+
* packet's Participating Lens Outputs section, runs the audit against the
|
|
594
|
+
* synthesize output text, and emits a STDERR warning if any quoted strings
|
|
595
|
+
* in the synthesize output don't substring-match any lens.
|
|
596
|
+
*
|
|
597
|
+
* Returns the audit result (undefined when the packet has no participating
|
|
598
|
+
* paths, or when no lens file could be read — audit requires at least one
|
|
599
|
+
* readable lens pool to be meaningful).
|
|
600
|
+
*/
|
|
601
|
+
async function runCitationAudit(rawPacketText, outputText, projectRoot, unitId, minQuoteLength) {
|
|
602
|
+
const participating = parseParticipatingLensPaths(rawPacketText);
|
|
603
|
+
if (participating.length === 0)
|
|
604
|
+
return undefined;
|
|
605
|
+
const lensContents = [];
|
|
606
|
+
const unreadable = [];
|
|
607
|
+
for (const { lensId, path: lensPath } of participating) {
|
|
608
|
+
const absPath = path.isAbsolute(lensPath)
|
|
609
|
+
? lensPath
|
|
610
|
+
: path.resolve(projectRoot, lensPath);
|
|
611
|
+
try {
|
|
612
|
+
const content = await fs.readFile(absPath, "utf8");
|
|
613
|
+
lensContents.push(content);
|
|
614
|
+
}
|
|
615
|
+
catch {
|
|
616
|
+
unreadable.push(`${lensId} (${lensPath})`);
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
if (lensContents.length === 0) {
|
|
620
|
+
// No lens file readable — don't audit against an empty pool (every quote
|
|
621
|
+
// would trivially be unmatched, producing noise). Surface the state.
|
|
622
|
+
process.stderr.write(`[onto] citation audit skipped for unit ${unitId}: no lens outputs readable (${unreadable.length}/${participating.length} failed). ` +
|
|
623
|
+
"Audit requires at least one readable lens for meaningful detection.\n");
|
|
624
|
+
return undefined;
|
|
625
|
+
}
|
|
626
|
+
const auditOptions = typeof minQuoteLength === "number" ? { minQuoteLength } : undefined;
|
|
627
|
+
const result = auditCitations(outputText, lensContents, auditOptions);
|
|
628
|
+
if (unreadable.length > 0) {
|
|
629
|
+
process.stderr.write(`[onto] citation audit partial for unit ${unitId}: ${unreadable.length}/${participating.length} lens file(s) unreadable (${unreadable.join(", ")}). ` +
|
|
630
|
+
"Remaining lens files used as audit pool.\n");
|
|
631
|
+
}
|
|
632
|
+
if (result.quotes_unmatched.length > 0) {
|
|
633
|
+
const sample = result.quotes_unmatched
|
|
634
|
+
.slice(0, 3)
|
|
635
|
+
.map((q) => JSON.stringify(q.length > 80 ? `${q.slice(0, 77)}...` : q))
|
|
636
|
+
.join(", ");
|
|
637
|
+
process.stderr.write(`[onto] citation audit WARNING for unit ${unitId}: ${result.quotes_unmatched.length} attribution-style quote(s) in synthesize output not found in any lens. ` +
|
|
638
|
+
`This may indicate fabrication. Sample: ${sample}. ` +
|
|
639
|
+
"See citation_audit.quotes_unmatched in the result JSON for the full list.\n");
|
|
640
|
+
}
|
|
641
|
+
if (result.quotes_unmatched_meta.length > 0) {
|
|
642
|
+
process.stderr.write(`[onto] citation audit advisory for unit ${unitId}: ${result.quotes_unmatched_meta.length} non-attribution quote(s) in synthesize output not found in any lens. ` +
|
|
643
|
+
"These may be taxonomy labels or paraphrased references — advisory only, not a fabrication warning. " +
|
|
644
|
+
"See citation_audit.quotes_unmatched_meta in the result JSON.\n");
|
|
645
|
+
}
|
|
646
|
+
return result;
|
|
647
|
+
}
|
|
648
|
+
async function main() {
|
|
649
|
+
return runInlineHttpReviewUnitExecutorCli(process.argv.slice(2));
|
|
650
|
+
}
|
|
651
|
+
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
652
|
+
main().then((exitCode) => process.exit(exitCode), (error) => {
|
|
653
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
654
|
+
process.exit(1);
|
|
655
|
+
});
|
|
656
|
+
}
|