onto-mcp 0.3.2 → 0.4.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/processes/reconstruct/actionable-ontology-seed-recomposition-design.md +447 -0
- package/.onto/processes/reconstruct/foundry-style-ontology-seed-contract.md +934 -0
- package/.onto/processes/reconstruct/reconstruct-boundary-contract.md +303 -725
- package/.onto/processes/reconstruct/reconstruct-contract-registry.yaml +1645 -0
- package/.onto/processes/reconstruct/reconstruct-execution-ux-contract.md +26 -22
- package/.onto/processes/reconstruct/source-profile-contract.md +49 -23
- package/.onto/processes/reconstruct/source-profiles/code.md +6 -3
- package/.onto/processes/reconstruct/source-profiles/database.md +5 -2
- package/.onto/processes/reconstruct/source-profiles/document.md +5 -2
- package/.onto/processes/reconstruct/source-profiles/spreadsheet.md +5 -4
- package/.onto/processes/review/review-execution-ux-contract.md +40 -0
- package/.onto/processes/shared/pipeline-execution-ledger-contract.md +26 -10
- package/.onto/processes/shared/target-material-kind-contract.md +29 -16
- package/AGENTS.md +6 -4
- package/README.md +135 -76
- package/dist/cli.js +8 -8
- package/dist/core-api/reconstruct-api.js +117 -31
- package/dist/core-api/review-api.js +47 -0
- package/dist/core-runtime/cli/codex-review-unit-executor.js +39 -2
- package/dist/core-runtime/cli/complete-review-session.js +2 -2
- package/dist/core-runtime/cli/mock-review-unit-executor.js +1 -1
- package/dist/core-runtime/cli/review-invoke.js +9 -9
- package/dist/core-runtime/cli/run-review-prompt-execution.js +39 -5
- package/dist/core-runtime/cli/spawn-watcher.js +266 -47
- package/dist/core-runtime/cli/start-review-session.js +3 -3
- package/dist/core-runtime/llm/llm-caller.js +11 -0
- package/dist/core-runtime/llm/llm-tool-loop.js +2 -0
- package/dist/core-runtime/observability/runtime-stream-observation.js +118 -0
- package/dist/core-runtime/onboard/cli-host.js +149 -0
- package/dist/core-runtime/onboard/host-target.js +22 -0
- package/dist/core-runtime/onboard/json-config-host.js +122 -0
- package/dist/core-runtime/onboard/path-scan.js +26 -0
- package/dist/core-runtime/onboard/prompt.js +51 -0
- package/dist/core-runtime/onboard/register.js +207 -0
- package/dist/core-runtime/onboard/types.js +27 -0
- package/dist/core-runtime/reconstruct/actionable-seed-validation.js +1777 -0
- package/dist/core-runtime/reconstruct/artifact-types.js +10 -4
- package/dist/core-runtime/reconstruct/contract-registry.js +623 -0
- package/dist/core-runtime/reconstruct/domain-id.js +10 -0
- package/dist/core-runtime/reconstruct/governing-snapshot.js +716 -0
- package/dist/core-runtime/reconstruct/material-profile-validation.js +191 -0
- package/dist/core-runtime/reconstruct/materialize-preparation.js +49 -11
- package/dist/core-runtime/reconstruct/pipeline-execution-ledger.js +269 -79
- package/dist/core-runtime/reconstruct/post-seed-validation.js +1194 -51
- package/dist/core-runtime/reconstruct/record.js +104 -20
- package/dist/core-runtime/reconstruct/run.js +2107 -413
- package/dist/core-runtime/reconstruct/seed-claim-projections.js +268 -0
- package/dist/core-runtime/reconstruct/source-profiles.js +93 -4
- package/dist/core-runtime/reconstruct/terminal-validation.js +807 -0
- package/dist/core-runtime/review/review-invocation-runner.js +4 -4
- package/dist/mcp/server.js +110 -38
- package/dist/mcp/tool-schemas.js +20 -6
- package/package.json +8 -17
- package/scripts/onto-review-watch.sh +486 -0
- package/scripts/onto-runtime-watch.sh +122 -0
- package/scripts/postinstall-hint.js +22 -0
- package/.onto/processes/reconstruct/top-level-concept-discovery-contract.md +0 -387
- package/dist/core-runtime/cli/bootstrap-review-binding.js +0 -186
- package/dist/core-runtime/cli/codex-nested-dispatch.test.js +0 -390
- package/dist/core-runtime/cli/codex-nested-teamlead-executor.test.js +0 -335
- package/dist/core-runtime/cli/coordinator-helpers.js +0 -583
- package/dist/core-runtime/cli/coordinator-state-machine-deliberation.test.js +0 -167
- package/dist/core-runtime/cli/coordinator-state-machine.js +0 -794
- package/dist/core-runtime/cli/e2e-codex-multi-agent-fixes.test.js +0 -615
- package/dist/core-runtime/cli/e2e-start-review-session.test.js +0 -312
- package/dist/core-runtime/cli/health.js +0 -44
- package/dist/core-runtime/cli/inline-http-review-unit-executor.test.js +0 -567
- package/dist/core-runtime/cli/materialize-review-execution-preparation.js +0 -104
- package/dist/core-runtime/cli/migrate-session-roots.js +0 -118
- package/dist/core-runtime/cli/repo-layout-migration-replace.smoke.test.js +0 -106
- package/dist/core-runtime/cli/review-invoke-auto-resolution.test.js +0 -268
- package/dist/core-runtime/cli/review-invoke-coordinator-topology.test.js +0 -136
- package/dist/core-runtime/cli/review-invoke-resolver-caching.test.js +0 -201
- package/dist/core-runtime/cli/review-invoke-topology-dispatch.test.js +0 -192
- package/dist/core-runtime/cli/session-root-guard.js +0 -168
- package/dist/core-runtime/cli/spawn-watcher.test.js +0 -457
- package/dist/core-runtime/cli/strip-wrapping-code-fence.test.js +0 -79
- package/dist/core-runtime/cli/teamcreate-lens-deliberation-executor.js +0 -412
- package/dist/core-runtime/cli/teamcreate-lens-deliberation-executor.test.js +0 -351
- package/dist/core-runtime/cli/topology-executor-mapping.js +0 -139
- package/dist/core-runtime/cli/topology-executor-mapping.test.js +0 -173
- package/dist/core-runtime/cli/write-review-interpretation.js +0 -81
- package/dist/core-runtime/config/onto-config-cli.js +0 -278
- package/dist/core-runtime/config/onto-config-key-path.js +0 -288
- package/dist/core-runtime/config/onto-config-key-path.test.js +0 -195
- package/dist/core-runtime/config/onto-config-preview.js +0 -108
- package/dist/core-runtime/config/onto-config-preview.test.js +0 -132
- package/dist/core-runtime/discovery/config-chain.js +0 -118
- package/dist/core-runtime/discovery/config-chain.test.js +0 -103
- package/dist/core-runtime/discovery/config-profile.js +0 -199
- package/dist/core-runtime/discovery/config-profile.test.js +0 -233
- package/dist/core-runtime/discovery/host-detection.test.js +0 -186
- package/dist/core-runtime/discovery/installation-paths.test.js +0 -65
- package/dist/core-runtime/discovery/lens-registry.test.js +0 -81
- package/dist/core-runtime/discovery/path-normalization.test.js +0 -22
- package/dist/core-runtime/discovery/plugin-path.js +0 -72
- package/dist/core-runtime/discovery/plugin-path.test.js +0 -95
- package/dist/core-runtime/evolve/adapters/code-product/compile/compile-defense.js +0 -344
- package/dist/core-runtime/evolve/adapters/code-product/compile/compile-defense.test.js +0 -915
- package/dist/core-runtime/evolve/adapters/code-product/compile/compile.js +0 -564
- package/dist/core-runtime/evolve/adapters/code-product/compile/compile.test.js +0 -708
- package/dist/core-runtime/evolve/adapters/code-product/parsers/brief-parser.js +0 -165
- package/dist/core-runtime/evolve/adapters/code-product/parsers/brief-parser.test.js +0 -227
- package/dist/core-runtime/evolve/adapters/code-product/validators/validate.js +0 -59
- package/dist/core-runtime/evolve/adapters/code-product/validators/validate.test.js +0 -205
- package/dist/core-runtime/evolve/adapters/methodology/adapter.js +0 -16
- package/dist/core-runtime/evolve/adapters/methodology/adapter.test.js +0 -9
- package/dist/core-runtime/evolve/adapters/methodology/perspectives/authority-consistency.js +0 -298
- package/dist/core-runtime/evolve/adapters/methodology/perspectives/authority-consistency.test.js +0 -70
- package/dist/core-runtime/evolve/adapters/methodology/scope-types/process.js +0 -46
- package/dist/core-runtime/evolve/adapters/methodology/scope-types/process.test.js +0 -73
- package/dist/core-runtime/evolve/adapters/registry.js +0 -47
- package/dist/core-runtime/evolve/adapters/registry.test.js +0 -67
- package/dist/core-runtime/evolve/cli.js +0 -256
- package/dist/core-runtime/evolve/commands/align.js +0 -194
- package/dist/core-runtime/evolve/commands/align.test.js +0 -82
- package/dist/core-runtime/evolve/commands/apply.js +0 -161
- package/dist/core-runtime/evolve/commands/apply.test.js +0 -138
- package/dist/core-runtime/evolve/commands/close.js +0 -39
- package/dist/core-runtime/evolve/commands/close.test.js +0 -99
- package/dist/core-runtime/evolve/commands/defer.js +0 -40
- package/dist/core-runtime/evolve/commands/defer.test.js +0 -134
- package/dist/core-runtime/evolve/commands/draft.js +0 -323
- package/dist/core-runtime/evolve/commands/draft.test.js +0 -178
- package/dist/core-runtime/evolve/commands/e2e-evolve-full-cycle.test.js +0 -208
- package/dist/core-runtime/evolve/commands/error-messages.js +0 -125
- package/dist/core-runtime/evolve/commands/error-messages.test.js +0 -167
- package/dist/core-runtime/evolve/commands/propose-align.js +0 -222
- package/dist/core-runtime/evolve/commands/propose-align.test.js +0 -136
- package/dist/core-runtime/evolve/commands/reconstruct.js +0 -330
- package/dist/core-runtime/evolve/commands/reconstruct.test.js +0 -278
- package/dist/core-runtime/evolve/commands/shared.js +0 -22
- package/dist/core-runtime/evolve/commands/stale-check.js +0 -103
- package/dist/core-runtime/evolve/commands/stale-check.test.js +0 -84
- package/dist/core-runtime/evolve/commands/start.js +0 -887
- package/dist/core-runtime/evolve/commands/start.test.js +0 -396
- package/dist/core-runtime/evolve/config/project-config.js +0 -99
- package/dist/core-runtime/evolve/config/project-config.test.js +0 -170
- package/dist/core-runtime/evolve/renderers/align-packet.js +0 -280
- package/dist/core-runtime/evolve/renderers/align-packet.test.js +0 -332
- package/dist/core-runtime/evolve/renderers/draft-packet.js +0 -303
- package/dist/core-runtime/evolve/renderers/draft-packet.test.js +0 -377
- package/dist/core-runtime/evolve/renderers/format.js +0 -5
- package/dist/core-runtime/evolve/renderers/scope-md.js +0 -237
- package/dist/core-runtime/evolve/renderers/scope-md.test.js +0 -306
- package/dist/core-runtime/govern/cli.js +0 -369
- package/dist/core-runtime/govern/cli.test.js +0 -314
- package/dist/core-runtime/govern/drift-engine.js +0 -103
- package/dist/core-runtime/govern/drift-engine.test.js +0 -319
- package/dist/core-runtime/govern/promote-principle.js +0 -206
- package/dist/core-runtime/govern/promote-principle.test.js +0 -368
- package/dist/core-runtime/govern/queue.js +0 -81
- package/dist/core-runtime/govern/types.js +0 -16
- package/dist/core-runtime/install/cli.js +0 -530
- package/dist/core-runtime/install/detect.js +0 -128
- package/dist/core-runtime/install/detect.test.js +0 -155
- package/dist/core-runtime/install/gitignore-update.js +0 -74
- package/dist/core-runtime/install/gitignore-update.test.js +0 -64
- package/dist/core-runtime/install/install-integration.test.js +0 -373
- package/dist/core-runtime/install/prompts.js +0 -389
- package/dist/core-runtime/install/prompts.test.js +0 -293
- package/dist/core-runtime/install/types.js +0 -26
- package/dist/core-runtime/install/validation.js +0 -295
- package/dist/core-runtime/install/validation.test.js +0 -313
- package/dist/core-runtime/install/writer.js +0 -254
- package/dist/core-runtime/install/writer.test.js +0 -218
- package/dist/core-runtime/learning/extractor.js +0 -461
- package/dist/core-runtime/learning/feedback.js +0 -179
- package/dist/core-runtime/learning/health-report.js +0 -165
- package/dist/core-runtime/learning/health-report.test.js +0 -169
- package/dist/core-runtime/learning/loader.js +0 -388
- package/dist/core-runtime/learning/loader.test.js +0 -102
- package/dist/core-runtime/learning/promote/apply-state.js +0 -240
- package/dist/core-runtime/learning/promote/audit-obligation.js +0 -195
- package/dist/core-runtime/learning/promote/collector.js +0 -432
- package/dist/core-runtime/learning/promote/degraded-state.js +0 -125
- package/dist/core-runtime/learning/promote/domain-doc-proposer.js +0 -166
- package/dist/core-runtime/learning/promote/e2e-promote.test.js +0 -6385
- package/dist/core-runtime/learning/promote/health-snapshot.js +0 -150
- package/dist/core-runtime/learning/promote/insight-reclassifier.js +0 -544
- package/dist/core-runtime/learning/promote/judgment-auditor.js +0 -517
- package/dist/core-runtime/learning/promote/panel-reviewer.js +0 -1158
- package/dist/core-runtime/learning/promote/promote-executor.js +0 -1675
- package/dist/core-runtime/learning/promote/promoter.js +0 -307
- package/dist/core-runtime/learning/promote/retirement.js +0 -122
- package/dist/core-runtime/learning/promote/types.js +0 -23
- package/dist/core-runtime/learning/prompt-sections.js +0 -51
- package/dist/core-runtime/learning/shared/artifact-registry-init.js +0 -45
- package/dist/core-runtime/learning/shared/artifact-registry.js +0 -254
- package/dist/core-runtime/learning/shared/audit-obligation-kernel.js +0 -73
- package/dist/core-runtime/learning/shared/audit-state.js +0 -99
- package/dist/core-runtime/learning/shared/duplicate-check.js +0 -28
- package/dist/core-runtime/learning/shared/llm-caller.js +0 -831
- package/dist/core-runtime/learning/shared/llm-caller.test.js +0 -601
- package/dist/core-runtime/learning/shared/llm-tool-loop.js +0 -393
- package/dist/core-runtime/learning/shared/mode.js +0 -25
- package/dist/core-runtime/learning/shared/paths.js +0 -84
- package/dist/core-runtime/learning/shared/paths.test.js +0 -79
- package/dist/core-runtime/learning/shared/patterns.js +0 -37
- package/dist/core-runtime/learning/shared/recoverability.js +0 -355
- package/dist/core-runtime/learning/shared/recovery-context.js +0 -374
- package/dist/core-runtime/learning/shared/scope.js +0 -1
- package/dist/core-runtime/learning/shared/semantic-classifier.js +0 -94
- package/dist/core-runtime/learning/shared/specs/apply-execution-state-spec.js +0 -42
- package/dist/core-runtime/learning/shared/specs/audit-state-spec.js +0 -37
- package/dist/core-runtime/learning/shared/specs/backup-metadata-spec.js +0 -39
- package/dist/core-runtime/learning/shared/specs/emergency-log-spec.js +0 -41
- package/dist/core-runtime/learning/shared/specs/layout-version-spec.js +0 -38
- package/dist/core-runtime/learning/shared/specs/promote-decisions-spec.js +0 -43
- package/dist/core-runtime/learning/shared/specs/promote-report-spec.js +0 -113
- package/dist/core-runtime/learning/shared/specs/prune-log-spec.js +0 -36
- package/dist/core-runtime/learning/shared/specs/recovery-resolution-spec.js +0 -48
- package/dist/core-runtime/learning/shared/specs/restore-manifest-spec.js +0 -43
- package/dist/core-runtime/learning/shared/specs/spec-helpers.js +0 -64
- package/dist/core-runtime/learning/usage-tracker.js +0 -190
- package/dist/core-runtime/learning/usage-tracker.test.js +0 -176
- package/dist/core-runtime/onboard/detect-review-axes.js +0 -122
- package/dist/core-runtime/onboard/detect-review-axes.test.js +0 -127
- package/dist/core-runtime/onboard/write-review-block.js +0 -188
- package/dist/core-runtime/onboard/write-review-block.test.js +0 -240
- package/dist/core-runtime/readers/brownfield-builder.js +0 -150
- package/dist/core-runtime/readers/brownfield-builder.test.js +0 -136
- package/dist/core-runtime/readers/code-chunk-collector.js +0 -53
- package/dist/core-runtime/readers/code-chunk-collector.test.js +0 -136
- package/dist/core-runtime/readers/file-utils.js +0 -240
- package/dist/core-runtime/readers/file-utils.test.js +0 -146
- package/dist/core-runtime/readers/lexicon-citation-check.js +0 -93
- package/dist/core-runtime/readers/lexicon-citation-check.test.js +0 -77
- package/dist/core-runtime/readers/mcp-figma.js +0 -30
- package/dist/core-runtime/readers/mcp-figma.test.js +0 -82
- package/dist/core-runtime/readers/mcp-generic.js +0 -31
- package/dist/core-runtime/readers/mcp-generic.test.js +0 -76
- package/dist/core-runtime/readers/ontology-index.js +0 -148
- package/dist/core-runtime/readers/ontology-index.test.js +0 -245
- package/dist/core-runtime/readers/ontology-query.js +0 -168
- package/dist/core-runtime/readers/ontology-query.test.js +0 -311
- package/dist/core-runtime/readers/ontology-resolve.js +0 -48
- package/dist/core-runtime/readers/ontology-resolve.test.js +0 -48
- package/dist/core-runtime/readers/patterns/index.js +0 -7
- package/dist/core-runtime/readers/review-log.js +0 -213
- package/dist/core-runtime/readers/review-log.test.js +0 -313
- package/dist/core-runtime/readers/scan-local.js +0 -102
- package/dist/core-runtime/readers/scan-local.test.js +0 -102
- package/dist/core-runtime/readers/scan-tarball.js +0 -121
- package/dist/core-runtime/readers/scan-tarball.test.js +0 -283
- package/dist/core-runtime/readers/scan-vault.js +0 -34
- package/dist/core-runtime/readers/scan-vault.test.js +0 -81
- package/dist/core-runtime/readers/types.js +0 -42
- package/dist/core-runtime/readers/types.test.js +0 -94
- package/dist/core-runtime/readers/viewpoint-collectors.js +0 -229
- package/dist/core-runtime/reconstruct/seed-candidate-validation.js +0 -385
- package/dist/core-runtime/review/citation-audit.test.js +0 -165
- package/dist/core-runtime/review/execution-plan-resolver.js +0 -247
- package/dist/core-runtime/review/execution-plan-resolver.test.js +0 -243
- package/dist/core-runtime/review/execution-topology-resolver-axis-first.test.js +0 -246
- package/dist/core-runtime/review/execution-topology-resolver.js +0 -401
- package/dist/core-runtime/review/execution-topology-resolver.test.js +0 -315
- package/dist/core-runtime/review/inline-context-embedder.test.js +0 -154
- package/dist/core-runtime/review/legacy-mode-policy.js +0 -88
- package/dist/core-runtime/review/materializers-effort-persist.test.js +0 -79
- package/dist/core-runtime/review/ontology-path-classifier.js +0 -179
- package/dist/core-runtime/review/ontology-path-classifier.test.js +0 -216
- package/dist/core-runtime/review/packet-boundary-policy.test.js +0 -107
- package/dist/core-runtime/review/participating-lens-paths.test.js +0 -73
- package/dist/core-runtime/review/review-config-legacy-translate.js +0 -244
- package/dist/core-runtime/review/review-config-legacy-translate.test.js +0 -161
- package/dist/core-runtime/review/review-config-validator.js +0 -289
- package/dist/core-runtime/review/review-config-validator.test.js +0 -236
- package/dist/core-runtime/review/shape-pipeline-audit.test.js +0 -311
- package/dist/core-runtime/review/shape-to-topology-id.js +0 -117
- package/dist/core-runtime/review/shape-to-topology-id.test.js +0 -132
- package/dist/core-runtime/review/topology-shape-derivation.js +0 -155
- package/dist/core-runtime/review/topology-shape-derivation.test.js +0 -195
- package/dist/core-runtime/scope-runtime/constants.js +0 -12
- package/dist/core-runtime/scope-runtime/constraint-pool.js +0 -166
- package/dist/core-runtime/scope-runtime/constraint-pool.test.js +0 -674
- package/dist/core-runtime/scope-runtime/domain-validation-log.js +0 -135
- package/dist/core-runtime/scope-runtime/domain-validation-log.test.js +0 -156
- package/dist/core-runtime/scope-runtime/eval-persistence.js +0 -65
- package/dist/core-runtime/scope-runtime/eval-persistence.test.js +0 -84
- package/dist/core-runtime/scope-runtime/event-pipeline.js +0 -64
- package/dist/core-runtime/scope-runtime/event-pipeline.test.js +0 -450
- package/dist/core-runtime/scope-runtime/event-store.js +0 -39
- package/dist/core-runtime/scope-runtime/event-store.test.js +0 -95
- package/dist/core-runtime/scope-runtime/gate-guard.js +0 -348
- package/dist/core-runtime/scope-runtime/gate-guard.test.js +0 -1047
- package/dist/core-runtime/scope-runtime/hash.js +0 -4
- package/dist/core-runtime/scope-runtime/hash.test.js +0 -33
- package/dist/core-runtime/scope-runtime/id.js +0 -4
- package/dist/core-runtime/scope-runtime/id.test.js +0 -17
- package/dist/core-runtime/scope-runtime/reducer.js +0 -297
- package/dist/core-runtime/scope-runtime/reducer.test.js +0 -759
- package/dist/core-runtime/scope-runtime/scope-manager.js +0 -161
- package/dist/core-runtime/scope-runtime/state-machine.js +0 -309
- package/dist/core-runtime/scope-runtime/state-machine.test.js +0 -704
- package/dist/core-runtime/scope-runtime/types.js +0 -116
- package/dist/core-runtime/scope-runtime/types.test.js +0 -69
- package/dist/core-runtime/translate/render-for-user.js +0 -169
- package/dist/core-runtime/translate/render-for-user.test.js +0 -122
- package/dist/providers/capability-contract.js +0 -1
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Session Root Migrator — DD-8 (Step 11b).
|
|
3
|
-
*
|
|
4
|
-
* Design authority:
|
|
5
|
-
* - learn-phase3-design-v4.md DD-8 (1-time idempotent migration)
|
|
6
|
-
* - learn-phase3-design-v9.md DD-8 (.layout-version.yaml seat)
|
|
7
|
-
*
|
|
8
|
-
* Responsibility:
|
|
9
|
-
* - Move pre-v3 session directories from `.onto/sessions/{id}/` to
|
|
10
|
-
* `.onto/sessions/review/{id}/`. Pre-v3 sessions were all review
|
|
11
|
-
* sessions; promote and reclassify-insights are post-v3 additions, so
|
|
12
|
-
* unscoped legacy ids are unambiguous.
|
|
13
|
-
* - Write the layout-version marker after migration succeeds so
|
|
14
|
-
* subsequent commands skip the gate.
|
|
15
|
-
* - Idempotent: re-running after a successful migration writes nothing,
|
|
16
|
-
* reports `migrated_count: 0`. Safe to re-run if a partial run was
|
|
17
|
-
* interrupted.
|
|
18
|
-
*
|
|
19
|
-
* Failure semantics:
|
|
20
|
-
* - Per-session move uses `fs.renameSync` (atomic on the same filesystem).
|
|
21
|
-
* If a move fails mid-list, the function records the partial state and
|
|
22
|
-
* surfaces it to the caller. The caller decides whether to retry.
|
|
23
|
-
* - Marker is only written when ALL legacy sessions migrated successfully
|
|
24
|
-
* — partial migration leaves the marker absent so the gate keeps firing.
|
|
25
|
-
*
|
|
26
|
-
* Dry-run support:
|
|
27
|
-
* - The CLI exposes `--dry-run` so operators can preview the plan without
|
|
28
|
-
* touching the filesystem. The dry-run path emits the same MigrationResult
|
|
29
|
-
* shape so plan output is structured.
|
|
30
|
-
*/
|
|
31
|
-
import fs from "node:fs";
|
|
32
|
-
import path from "node:path";
|
|
33
|
-
import { inspectMigrationStatus, writeLayoutMarker, getSessionsDir, } from "./session-root-guard.js";
|
|
34
|
-
// ---------------------------------------------------------------------------
|
|
35
|
-
// Migration entry point
|
|
36
|
-
// ---------------------------------------------------------------------------
|
|
37
|
-
export function migrateSessionRoots(config) {
|
|
38
|
-
const before = inspectMigrationStatus(config.projectRoot);
|
|
39
|
-
// Already-migrated case: just write the marker if needed.
|
|
40
|
-
if (before.legacy_session_count === 0) {
|
|
41
|
-
if (config.dryRun) {
|
|
42
|
-
return {
|
|
43
|
-
dry_run: true,
|
|
44
|
-
before,
|
|
45
|
-
migrated: [],
|
|
46
|
-
failures: [],
|
|
47
|
-
marker_written: false,
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
if (!before.marker_present) {
|
|
51
|
-
writeLayoutMarker(config.projectRoot);
|
|
52
|
-
return {
|
|
53
|
-
dry_run: false,
|
|
54
|
-
before,
|
|
55
|
-
migrated: [],
|
|
56
|
-
failures: [],
|
|
57
|
-
marker_written: true,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
return {
|
|
61
|
-
dry_run: false,
|
|
62
|
-
before,
|
|
63
|
-
migrated: [],
|
|
64
|
-
failures: [],
|
|
65
|
-
marker_written: false,
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
const sessionsDir = getSessionsDir(config.projectRoot);
|
|
69
|
-
const reviewDir = path.join(sessionsDir, "review");
|
|
70
|
-
const planned = before.legacy_session_ids.map((id) => ({
|
|
71
|
-
session_id: id,
|
|
72
|
-
from: path.join(sessionsDir, id),
|
|
73
|
-
to: path.join(reviewDir, id),
|
|
74
|
-
}));
|
|
75
|
-
if (config.dryRun) {
|
|
76
|
-
return {
|
|
77
|
-
dry_run: true,
|
|
78
|
-
before,
|
|
79
|
-
migrated: planned,
|
|
80
|
-
failures: [],
|
|
81
|
-
marker_written: false,
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
fs.mkdirSync(reviewDir, { recursive: true });
|
|
85
|
-
const migrated = [];
|
|
86
|
-
const failures = [];
|
|
87
|
-
for (const session of planned) {
|
|
88
|
-
try {
|
|
89
|
-
// Defensive: refuse to overwrite an existing destination.
|
|
90
|
-
if (fs.existsSync(session.to)) {
|
|
91
|
-
throw new Error(`destination ${session.to} already exists`);
|
|
92
|
-
}
|
|
93
|
-
fs.renameSync(session.from, session.to);
|
|
94
|
-
migrated.push(session);
|
|
95
|
-
}
|
|
96
|
-
catch (error) {
|
|
97
|
-
failures.push({
|
|
98
|
-
session_id: session.session_id,
|
|
99
|
-
error: error instanceof Error ? error.message : String(error),
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
// Marker is only written when ALL legacy sessions migrated successfully.
|
|
104
|
-
// Partial runs leave the marker absent so the gate keeps firing on the
|
|
105
|
-
// next invocation.
|
|
106
|
-
let marker_written = false;
|
|
107
|
-
if (failures.length === 0) {
|
|
108
|
-
writeLayoutMarker(config.projectRoot);
|
|
109
|
-
marker_written = true;
|
|
110
|
-
}
|
|
111
|
-
return {
|
|
112
|
-
dry_run: false,
|
|
113
|
-
before,
|
|
114
|
-
migrated,
|
|
115
|
-
failures,
|
|
116
|
-
marker_written,
|
|
117
|
-
};
|
|
118
|
-
}
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Smoke test for scripts/repo-layout-migration-replace.py.
|
|
3
|
-
*
|
|
4
|
-
* Phase 7 review follow-up (`coverage::migration-script-reuse-test-gap`):
|
|
5
|
-
* the script is retained as a generic tool for future similar migrations,
|
|
6
|
-
* but without a test surface its reuse claim has no executable evidence.
|
|
7
|
-
* These tests pin the load-bearing invariants:
|
|
8
|
-
* - `--old` trailing-slash contract (substring-safety)
|
|
9
|
-
* - marker-based double-prefix prevention (the guard that makes the
|
|
10
|
-
* Phase 6–style `new` ⊃ `old` case work)
|
|
11
|
-
* - `--dry-run` does not write files
|
|
12
|
-
*
|
|
13
|
-
* The script is Python; the tests invoke it via child_process.spawnSync.
|
|
14
|
-
*/
|
|
15
|
-
import { spawnSync } from "node:child_process";
|
|
16
|
-
import fs from "node:fs";
|
|
17
|
-
import os from "node:os";
|
|
18
|
-
import path from "node:path";
|
|
19
|
-
import { fileURLToPath } from "node:url";
|
|
20
|
-
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
21
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
22
|
-
const REPO_ROOT = path.resolve(path.dirname(__filename), "..", "..", "..");
|
|
23
|
-
const SCRIPT_PATH = path.join(REPO_ROOT, "scripts", "repo-layout-migration-replace.py");
|
|
24
|
-
function runScript(args, cwd) {
|
|
25
|
-
const result = spawnSync("python3", [SCRIPT_PATH, ...args], {
|
|
26
|
-
cwd,
|
|
27
|
-
encoding: "utf8",
|
|
28
|
-
});
|
|
29
|
-
return {
|
|
30
|
-
stdout: result.stdout ?? "",
|
|
31
|
-
stderr: result.stderr ?? "",
|
|
32
|
-
status: typeof result.status === "number" ? result.status : -1,
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
function makeTempRoot(prefix) {
|
|
36
|
-
return fs.mkdtempSync(path.join(os.tmpdir(), `onto-migration-smoke-${prefix}-`));
|
|
37
|
-
}
|
|
38
|
-
describe("scripts/repo-layout-migration-replace.py — smoke invariants", () => {
|
|
39
|
-
const tmpRoots = [];
|
|
40
|
-
beforeEach(() => {
|
|
41
|
-
tmpRoots.length = 0;
|
|
42
|
-
});
|
|
43
|
-
afterEach(() => {
|
|
44
|
-
for (const root of tmpRoots) {
|
|
45
|
-
try {
|
|
46
|
-
fs.rmSync(root, { recursive: true, force: true });
|
|
47
|
-
}
|
|
48
|
-
catch {
|
|
49
|
-
// ignore
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
it("rejects --old without trailing slash (substring-safe contract)", () => {
|
|
54
|
-
const root = makeTempRoot("no-slash");
|
|
55
|
-
tmpRoots.push(root);
|
|
56
|
-
const result = runScript(["--old", "foo", "--new", ".onto/foo/", "--root", root, "--dry-run"], root);
|
|
57
|
-
expect(result.status).not.toBe(0);
|
|
58
|
-
expect(result.stderr).toMatch(/substring-safe contract|must end with '\/'/);
|
|
59
|
-
});
|
|
60
|
-
it("performs a simple rewrite when new does not contain old", () => {
|
|
61
|
-
const root = makeTempRoot("simple");
|
|
62
|
-
tmpRoots.push(root);
|
|
63
|
-
const fixture = path.join(root, "notes.md");
|
|
64
|
-
fs.writeFileSync(fixture, "reference to oldpath/file.md and oldpath/other.md\n", "utf8");
|
|
65
|
-
const result = runScript(["--old", "oldpath/", "--new", "canon/", "--root", root], root);
|
|
66
|
-
expect(result.status).toBe(0);
|
|
67
|
-
expect(fs.readFileSync(fixture, "utf8")).toBe("reference to canon/file.md and canon/other.md\n");
|
|
68
|
-
});
|
|
69
|
-
it("marker guard: when --new contains --old, rewriting is idempotent across reruns", () => {
|
|
70
|
-
// This is the Phase 6 pattern — `.onto/authority/` contains `authority/`.
|
|
71
|
-
// Naive str.replace would produce `.onto/.onto/authority/authority/...`
|
|
72
|
-
// on rerun. The NUL-sentinel marker protects already-new references.
|
|
73
|
-
const root = makeTempRoot("marker");
|
|
74
|
-
tmpRoots.push(root);
|
|
75
|
-
const fixture = path.join(root, "refs.md");
|
|
76
|
-
fs.writeFileSync(fixture, "legacy authority/core.yaml and existing .onto/authority/other.yaml\n", "utf8");
|
|
77
|
-
// First run — rewrite legacy to canonical.
|
|
78
|
-
let result = runScript(["--old", "authority/", "--new", ".onto/authority/", "--root", root], root);
|
|
79
|
-
expect(result.status).toBe(0);
|
|
80
|
-
expect(fs.readFileSync(fixture, "utf8")).toBe("legacy .onto/authority/core.yaml and existing .onto/authority/other.yaml\n");
|
|
81
|
-
// Second run — file already fully canonical. Guard must keep it stable.
|
|
82
|
-
result = runScript(["--old", "authority/", "--new", ".onto/authority/", "--root", root], root);
|
|
83
|
-
expect(result.status).toBe(0);
|
|
84
|
-
expect(fs.readFileSync(fixture, "utf8")).toBe("legacy .onto/authority/core.yaml and existing .onto/authority/other.yaml\n");
|
|
85
|
-
});
|
|
86
|
-
it("--dry-run does not write files even when matches exist", () => {
|
|
87
|
-
const root = makeTempRoot("dry-run");
|
|
88
|
-
tmpRoots.push(root);
|
|
89
|
-
const fixture = path.join(root, "refs.md");
|
|
90
|
-
const original = "pointer to oldref/x.md\n";
|
|
91
|
-
fs.writeFileSync(fixture, original, "utf8");
|
|
92
|
-
const result = runScript(["--old", "oldref/", "--new", "newref/", "--root", root, "--dry-run"], root);
|
|
93
|
-
expect(result.status).toBe(0);
|
|
94
|
-
expect(fs.readFileSync(fixture, "utf8")).toBe(original);
|
|
95
|
-
});
|
|
96
|
-
it("excludes .onto/review/ by default (audit-artifact guard)", () => {
|
|
97
|
-
const root = makeTempRoot("review-exclude");
|
|
98
|
-
tmpRoots.push(root);
|
|
99
|
-
const reviewFile = path.join(root, ".onto", "review", "past-session", "final.md");
|
|
100
|
-
fs.mkdirSync(path.dirname(reviewFile), { recursive: true });
|
|
101
|
-
fs.writeFileSync(reviewFile, "historical reference to oldname/x.md\n", "utf8");
|
|
102
|
-
const result = runScript(["--old", "oldname/", "--new", "newname/", "--root", root], root);
|
|
103
|
-
expect(result.status).toBe(0);
|
|
104
|
-
expect(fs.readFileSync(reviewFile, "utf8")).toBe("historical reference to oldname/x.md\n");
|
|
105
|
-
});
|
|
106
|
-
});
|
|
@@ -1,268 +0,0 @@
|
|
|
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
|
-
});
|
|
@@ -1,136 +0,0 @@
|
|
|
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
|
-
});
|