onto-mcp 0.3.2 → 0.4.1
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 +149 -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 +174 -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 +214 -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,351 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs/promises";
|
|
2
|
-
import os from "node:os";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
5
|
-
import { DeliberationOptInError, buildDeliberationPlan, buildDeliberationRound1Prompt, buildDeliberationRound2Prompt, deliberationArtifactPath, extractDisagreements, readDeliberationArtifact, requireDeliberationOptIn, runLensAgentDeliberation, writeDeliberationArtifact, } from "./teamcreate-lens-deliberation-executor.js";
|
|
6
|
-
// ---------------------------------------------------------------------------
|
|
7
|
-
// These tests assert the PR-D deliberation protocol invariants:
|
|
8
|
-
//
|
|
9
|
-
// (1) Triple opt-in is enforced at module boundary — missing any of
|
|
10
|
-
// CLAUDECODE, CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS, or
|
|
11
|
-
// config.lens_agent_teams_mode throws DeliberationOptInError with
|
|
12
|
-
// the missing items enumerated.
|
|
13
|
-
// (2) Round 1 prompt embeds OTHER lens outputs (not own), asks for
|
|
14
|
-
// re-evaluation, declares the required response section headings.
|
|
15
|
-
// (3) Round 2 prompt embeds ALL round-1 responses, asks for convergence
|
|
16
|
-
// + explicit persistent disagreements.
|
|
17
|
-
// (4) Artifact paths are deterministic: <dir>/round{N}/<lens>-deliberation.md.
|
|
18
|
-
// (5) Read/write round-trip preserves content.
|
|
19
|
-
// (6) Disagreement extraction finds "## 지속적 이견" sections, parses
|
|
20
|
-
// "- **이견 항목**:" entries, tolerates English variant heading.
|
|
21
|
-
// (7) runLensAgentDeliberation produces a plan with N*round steps in
|
|
22
|
-
// stable order, each with prompt + artifact_path populated.
|
|
23
|
-
// ---------------------------------------------------------------------------
|
|
24
|
-
const LENSES = [
|
|
25
|
-
{ lens_id: "logic", output_path: "/tmp/fake/round0/logic.md" },
|
|
26
|
-
{ lens_id: "pragmatics", output_path: "/tmp/fake/round0/pragmatics.md" },
|
|
27
|
-
{ lens_id: "axiology", output_path: "/tmp/fake/round0/axiology.md" },
|
|
28
|
-
];
|
|
29
|
-
// ---------------------------------------------------------------------------
|
|
30
|
-
// requireDeliberationOptIn
|
|
31
|
-
// ---------------------------------------------------------------------------
|
|
32
|
-
describe("requireDeliberationOptIn", () => {
|
|
33
|
-
it("passes when all three flags satisfied", () => {
|
|
34
|
-
expect(() => requireDeliberationOptIn({ lens_agent_teams_mode: true }, {
|
|
35
|
-
CLAUDECODE: "1",
|
|
36
|
-
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: "1",
|
|
37
|
-
})).not.toThrow();
|
|
38
|
-
});
|
|
39
|
-
it("throws with CLAUDECODE missing", () => {
|
|
40
|
-
try {
|
|
41
|
-
requireDeliberationOptIn({ lens_agent_teams_mode: true }, { CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: "1" });
|
|
42
|
-
expect.fail("expected throw");
|
|
43
|
-
}
|
|
44
|
-
catch (err) {
|
|
45
|
-
expect(err).toBeInstanceOf(DeliberationOptInError);
|
|
46
|
-
expect(err.missing.join("\n")).toContain("CLAUDECODE=1");
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
it("throws with experimental flag missing", () => {
|
|
50
|
-
try {
|
|
51
|
-
requireDeliberationOptIn({ lens_agent_teams_mode: true }, { CLAUDECODE: "1" });
|
|
52
|
-
expect.fail("expected throw");
|
|
53
|
-
}
|
|
54
|
-
catch (err) {
|
|
55
|
-
const m = err.missing.join("\n");
|
|
56
|
-
expect(m).toContain("EXPERIMENTAL_AGENT_TEAMS");
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
it("throws with config.lens_agent_teams_mode missing", () => {
|
|
60
|
-
try {
|
|
61
|
-
requireDeliberationOptIn({}, {
|
|
62
|
-
CLAUDECODE: "1",
|
|
63
|
-
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: "1",
|
|
64
|
-
});
|
|
65
|
-
expect.fail("expected throw");
|
|
66
|
-
}
|
|
67
|
-
catch (err) {
|
|
68
|
-
const m = err.missing.join("\n");
|
|
69
|
-
expect(m).toContain("lens_agent_teams_mode");
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
it("message enumerates ALL missing flags (not just the first)", () => {
|
|
73
|
-
try {
|
|
74
|
-
requireDeliberationOptIn({ lens_agent_teams_mode: false }, {});
|
|
75
|
-
expect.fail("expected throw");
|
|
76
|
-
}
|
|
77
|
-
catch (err) {
|
|
78
|
-
const msg = err.message;
|
|
79
|
-
expect(msg).toContain("CLAUDECODE=1");
|
|
80
|
-
expect(msg).toContain("EXPERIMENTAL_AGENT_TEAMS");
|
|
81
|
-
expect(msg).toContain("lens_agent_teams_mode");
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
// ---------------------------------------------------------------------------
|
|
86
|
-
// Prompt templates
|
|
87
|
-
// ---------------------------------------------------------------------------
|
|
88
|
-
describe("buildDeliberationRound1Prompt", () => {
|
|
89
|
-
it("embeds every OTHER lens output as its own block", () => {
|
|
90
|
-
const prompt = buildDeliberationRound1Prompt({
|
|
91
|
-
own_lens_id: "logic",
|
|
92
|
-
own_output_summary: "logic 의 기존 결론",
|
|
93
|
-
other_lens_outputs: [
|
|
94
|
-
{ lens_id: "pragmatics", content: "pragmatics output body" },
|
|
95
|
-
{ lens_id: "axiology", content: "axiology output body" },
|
|
96
|
-
],
|
|
97
|
-
});
|
|
98
|
-
expect(prompt).toContain("## Lens: pragmatics");
|
|
99
|
-
expect(prompt).toContain("pragmatics output body");
|
|
100
|
-
expect(prompt).toContain("## Lens: axiology");
|
|
101
|
-
expect(prompt).toContain("axiology output body");
|
|
102
|
-
});
|
|
103
|
-
it("does NOT embed the lens's own output verbatim (it's already in its session memory)", () => {
|
|
104
|
-
const prompt = buildDeliberationRound1Prompt({
|
|
105
|
-
own_lens_id: "logic",
|
|
106
|
-
own_output_summary: "summary of logic body",
|
|
107
|
-
other_lens_outputs: [{ lens_id: "pragmatics", content: "other body" }],
|
|
108
|
-
});
|
|
109
|
-
expect(prompt).toContain("summary of logic body");
|
|
110
|
-
expect(prompt).not.toContain("## Lens: logic");
|
|
111
|
-
});
|
|
112
|
-
it("declares the required response section headings", () => {
|
|
113
|
-
const prompt = buildDeliberationRound1Prompt({
|
|
114
|
-
own_lens_id: "logic",
|
|
115
|
-
own_output_summary: "x",
|
|
116
|
-
other_lens_outputs: [],
|
|
117
|
-
});
|
|
118
|
-
expect(prompt).toContain("재평가 요약");
|
|
119
|
-
expect(prompt).toContain("동의/강화 지점");
|
|
120
|
-
expect(prompt).toContain("충돌/수정 지점");
|
|
121
|
-
expect(prompt).toContain("추가 발견");
|
|
122
|
-
});
|
|
123
|
-
});
|
|
124
|
-
describe("buildDeliberationRound2Prompt", () => {
|
|
125
|
-
it("embeds all round-1 responses", () => {
|
|
126
|
-
const prompt = buildDeliberationRound2Prompt({
|
|
127
|
-
own_lens_id: "logic",
|
|
128
|
-
round1_responses: [
|
|
129
|
-
{ lens_id: "logic", content: "logic r1" },
|
|
130
|
-
{ lens_id: "pragmatics", content: "pragmatics r1" },
|
|
131
|
-
],
|
|
132
|
-
});
|
|
133
|
-
expect(prompt).toContain("Round 1 response — lens: logic");
|
|
134
|
-
expect(prompt).toContain("Round 1 response — lens: pragmatics");
|
|
135
|
-
expect(prompt).toContain("logic r1");
|
|
136
|
-
expect(prompt).toContain("pragmatics r1");
|
|
137
|
-
});
|
|
138
|
-
it("declares required round-2 section headings (수렴 / 이견 / 최종)", () => {
|
|
139
|
-
const prompt = buildDeliberationRound2Prompt({
|
|
140
|
-
own_lens_id: "logic",
|
|
141
|
-
round1_responses: [],
|
|
142
|
-
});
|
|
143
|
-
expect(prompt).toContain("수렴 요약");
|
|
144
|
-
expect(prompt).toContain("지속적 이견");
|
|
145
|
-
expect(prompt).toContain("최종 입장");
|
|
146
|
-
});
|
|
147
|
-
it("explicitly instructs NOT to hide disagreement", () => {
|
|
148
|
-
const prompt = buildDeliberationRound2Prompt({
|
|
149
|
-
own_lens_id: "logic",
|
|
150
|
-
round1_responses: [],
|
|
151
|
-
});
|
|
152
|
-
expect(prompt).toContain("숨기지");
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
// ---------------------------------------------------------------------------
|
|
156
|
-
// Artifact path / read / write
|
|
157
|
-
// ---------------------------------------------------------------------------
|
|
158
|
-
describe("deliberationArtifactPath", () => {
|
|
159
|
-
it("composes <dir>/round{N}/<lens>-deliberation.md", () => {
|
|
160
|
-
expect(deliberationArtifactPath("/base", 1, "logic")).toBe(path.join("/base", "round1", "logic-deliberation.md"));
|
|
161
|
-
expect(deliberationArtifactPath("/base", 2, "axiology")).toBe(path.join("/base", "round2", "axiology-deliberation.md"));
|
|
162
|
-
});
|
|
163
|
-
});
|
|
164
|
-
describe("writeDeliberationArtifact / readDeliberationArtifact", () => {
|
|
165
|
-
let tmpRoot;
|
|
166
|
-
beforeEach(async () => {
|
|
167
|
-
tmpRoot = await fs.mkdtemp(path.join(os.tmpdir(), "onto-deliberation-"));
|
|
168
|
-
});
|
|
169
|
-
afterEach(async () => {
|
|
170
|
-
await fs.rm(tmpRoot, { recursive: true, force: true });
|
|
171
|
-
});
|
|
172
|
-
it("round-trips content through disk, creating parent directories", async () => {
|
|
173
|
-
const content = "## 재평가 요약\n\n유지.\n";
|
|
174
|
-
const filePath = await writeDeliberationArtifact(tmpRoot, 1, "logic", content);
|
|
175
|
-
expect(filePath).toBe(deliberationArtifactPath(tmpRoot, 1, "logic"));
|
|
176
|
-
const read = await readDeliberationArtifact(tmpRoot, 1, "logic");
|
|
177
|
-
expect(read).toBe(content);
|
|
178
|
-
});
|
|
179
|
-
it("readDeliberationArtifact returns null for missing artifact (not an error)", async () => {
|
|
180
|
-
const read = await readDeliberationArtifact(tmpRoot, 2, "never-written");
|
|
181
|
-
expect(read).toBeNull();
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
// ---------------------------------------------------------------------------
|
|
185
|
-
// extractDisagreements
|
|
186
|
-
// ---------------------------------------------------------------------------
|
|
187
|
-
describe("extractDisagreements", () => {
|
|
188
|
-
it("extracts items from a '## 지속적 이견' section", () => {
|
|
189
|
-
const round2 = [
|
|
190
|
-
{
|
|
191
|
-
lens_id: "logic",
|
|
192
|
-
content: [
|
|
193
|
-
"## 수렴 요약",
|
|
194
|
-
"- 모두 동의",
|
|
195
|
-
"",
|
|
196
|
-
"## 지속적 이견",
|
|
197
|
-
"- **이견 항목**: scope creep 정의",
|
|
198
|
-
" - 당신의 입장: task 내 한정",
|
|
199
|
-
" - 반대 입장 (axiology): 가치 질문 포함 필요",
|
|
200
|
-
"- **이견 항목**: severity 스케일",
|
|
201
|
-
" - 당신의 입장: 3단계",
|
|
202
|
-
" - 반대 입장 (pragmatics): 5단계",
|
|
203
|
-
"",
|
|
204
|
-
"## 최종 입장",
|
|
205
|
-
"입장 유지.",
|
|
206
|
-
].join("\n"),
|
|
207
|
-
},
|
|
208
|
-
];
|
|
209
|
-
const result = extractDisagreements(round2);
|
|
210
|
-
expect(result).toHaveLength(2);
|
|
211
|
-
expect(result[0].source_lens_id).toBe("logic");
|
|
212
|
-
expect(result[0].title).toBe("scope creep 정의");
|
|
213
|
-
expect(result[0].body).toContain("task 내 한정");
|
|
214
|
-
expect(result[1].title).toBe("severity 스케일");
|
|
215
|
-
});
|
|
216
|
-
it("empty section yields empty array", () => {
|
|
217
|
-
const round2 = [
|
|
218
|
-
{ lens_id: "logic", content: "## 수렴 요약\n- OK\n\n## 최종 입장\n입장 유지." },
|
|
219
|
-
];
|
|
220
|
-
expect(extractDisagreements(round2)).toEqual([]);
|
|
221
|
-
});
|
|
222
|
-
it("tolerates English heading 'Persistent Disagreements'", () => {
|
|
223
|
-
const round2 = [
|
|
224
|
-
{
|
|
225
|
-
lens_id: "pragmatics",
|
|
226
|
-
content: [
|
|
227
|
-
"## Persistent Disagreements",
|
|
228
|
-
"- **이견 항목**: naming convention",
|
|
229
|
-
" - details here",
|
|
230
|
-
].join("\n"),
|
|
231
|
-
},
|
|
232
|
-
];
|
|
233
|
-
const result = extractDisagreements(round2);
|
|
234
|
-
expect(result).toHaveLength(1);
|
|
235
|
-
expect(result[0].title).toBe("naming convention");
|
|
236
|
-
});
|
|
237
|
-
it("stops at the next ## heading", () => {
|
|
238
|
-
const round2 = [
|
|
239
|
-
{
|
|
240
|
-
lens_id: "logic",
|
|
241
|
-
content: [
|
|
242
|
-
"## 지속적 이견",
|
|
243
|
-
"- **이견 항목**: X",
|
|
244
|
-
" - detail",
|
|
245
|
-
"## 최종 입장",
|
|
246
|
-
"- **이견 항목**: should-not-appear",
|
|
247
|
-
].join("\n"),
|
|
248
|
-
},
|
|
249
|
-
];
|
|
250
|
-
const result = extractDisagreements(round2);
|
|
251
|
-
expect(result).toHaveLength(1);
|
|
252
|
-
expect(result[0].title).toBe("X");
|
|
253
|
-
});
|
|
254
|
-
it("aggregates across multiple round-2 artifacts", () => {
|
|
255
|
-
const round2 = [
|
|
256
|
-
{
|
|
257
|
-
lens_id: "logic",
|
|
258
|
-
content: "## 지속적 이견\n- **이견 항목**: A\n - body A",
|
|
259
|
-
},
|
|
260
|
-
{
|
|
261
|
-
lens_id: "pragmatics",
|
|
262
|
-
content: "## 지속적 이견\n- **이견 항목**: B\n - body B",
|
|
263
|
-
},
|
|
264
|
-
];
|
|
265
|
-
const result = extractDisagreements(round2);
|
|
266
|
-
expect(result).toHaveLength(2);
|
|
267
|
-
expect(result.map((d) => `${d.source_lens_id}:${d.title}`)).toEqual([
|
|
268
|
-
"logic:A",
|
|
269
|
-
"pragmatics:B",
|
|
270
|
-
]);
|
|
271
|
-
});
|
|
272
|
-
});
|
|
273
|
-
// ---------------------------------------------------------------------------
|
|
274
|
-
// buildDeliberationPlan
|
|
275
|
-
// ---------------------------------------------------------------------------
|
|
276
|
-
describe("buildDeliberationPlan", () => {
|
|
277
|
-
it("emits N round-1 steps when rounds=1", () => {
|
|
278
|
-
const plan = buildDeliberationPlan({ lenses: LENSES, deliberation_dir: "/tmp/d", rounds: 1 }, (lens) => `round1-prompt-for-${lens.lens_id}`);
|
|
279
|
-
expect(plan.steps).toHaveLength(3);
|
|
280
|
-
for (let i = 0; i < 3; i += 1) {
|
|
281
|
-
expect(plan.steps[i].round).toBe(1);
|
|
282
|
-
expect(plan.steps[i].lens_id).toBe(LENSES[i].lens_id);
|
|
283
|
-
expect(plan.steps[i].prompt).toContain(LENSES[i].lens_id);
|
|
284
|
-
}
|
|
285
|
-
});
|
|
286
|
-
it("emits 2N steps when rounds=2 with round1 before round2", () => {
|
|
287
|
-
const plan = buildDeliberationPlan({ lenses: LENSES, deliberation_dir: "/tmp/d", rounds: 2 }, (lens) => `round1-${lens.lens_id}`, (lens) => `round2-${lens.lens_id}`);
|
|
288
|
-
expect(plan.steps).toHaveLength(6);
|
|
289
|
-
expect(plan.steps.slice(0, 3).every((s) => s.round === 1)).toBe(true);
|
|
290
|
-
expect(plan.steps.slice(3).every((s) => s.round === 2)).toBe(true);
|
|
291
|
-
});
|
|
292
|
-
it("all_artifact_paths lists every step's target", () => {
|
|
293
|
-
const plan = buildDeliberationPlan({ lenses: LENSES, deliberation_dir: "/tmp/d", rounds: 2 }, (lens) => `r1-${lens.lens_id}`, (lens) => `r2-${lens.lens_id}`);
|
|
294
|
-
expect(plan.all_artifact_paths).toHaveLength(6);
|
|
295
|
-
expect(plan.all_artifact_paths[0]).toContain("round1");
|
|
296
|
-
expect(plan.all_artifact_paths[3]).toContain("round2");
|
|
297
|
-
});
|
|
298
|
-
});
|
|
299
|
-
// ---------------------------------------------------------------------------
|
|
300
|
-
// runLensAgentDeliberation
|
|
301
|
-
// ---------------------------------------------------------------------------
|
|
302
|
-
describe("runLensAgentDeliberation", () => {
|
|
303
|
-
const VALID_ENV = {
|
|
304
|
-
CLAUDECODE: "1",
|
|
305
|
-
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: "1",
|
|
306
|
-
};
|
|
307
|
-
it("throws DeliberationOptInError when opt-in not met", async () => {
|
|
308
|
-
await expect(runLensAgentDeliberation({
|
|
309
|
-
ontoConfig: {},
|
|
310
|
-
input: { lenses: LENSES, deliberation_dir: "/tmp/d", rounds: 1 },
|
|
311
|
-
env: {},
|
|
312
|
-
})).rejects.toThrow(DeliberationOptInError);
|
|
313
|
-
});
|
|
314
|
-
it("reads primary lens outputs via injected reader and builds round-1 prompts", async () => {
|
|
315
|
-
const primaries = new Map([
|
|
316
|
-
["logic", "LOGIC primary output body with findings."],
|
|
317
|
-
["pragmatics", "PRAG primary output body."],
|
|
318
|
-
["axiology", "AXIOLOGY primary output body."],
|
|
319
|
-
]);
|
|
320
|
-
const plan = await runLensAgentDeliberation({
|
|
321
|
-
ontoConfig: { lens_agent_teams_mode: true },
|
|
322
|
-
input: { lenses: LENSES, deliberation_dir: "/tmp/d", rounds: 1 },
|
|
323
|
-
env: VALID_ENV,
|
|
324
|
-
readPrimary: async (p) => {
|
|
325
|
-
const lensId = path.basename(p).replace(".md", "");
|
|
326
|
-
return primaries.get(lensId) ?? "";
|
|
327
|
-
},
|
|
328
|
-
});
|
|
329
|
-
expect(plan.steps).toHaveLength(3);
|
|
330
|
-
// Logic's prompt should contain PRAG + AXIOLOGY bodies (as "other" blocks)
|
|
331
|
-
// but should NOT include a "## Lens: logic" block — logic's own body
|
|
332
|
-
// stays in its session memory. The own_output_summary header may
|
|
333
|
-
// echo a truncated first paragraph (that's the name anchor) which
|
|
334
|
-
// is intentional; we check the block-shaped inclusion only.
|
|
335
|
-
const logicStep = plan.steps.find((s) => s.lens_id === "logic");
|
|
336
|
-
expect(logicStep.prompt).toContain("PRAG primary output body");
|
|
337
|
-
expect(logicStep.prompt).toContain("AXIOLOGY primary output body");
|
|
338
|
-
expect(logicStep.prompt).not.toContain("## Lens: logic");
|
|
339
|
-
});
|
|
340
|
-
it("rounds=2 produces round-1 + round-2 steps (round-2 prompt has runtime placeholder)", async () => {
|
|
341
|
-
const plan = await runLensAgentDeliberation({
|
|
342
|
-
ontoConfig: { lens_agent_teams_mode: true },
|
|
343
|
-
input: { lenses: LENSES, deliberation_dir: "/tmp/d", rounds: 2 },
|
|
344
|
-
env: VALID_ENV,
|
|
345
|
-
readPrimary: async () => "primary body",
|
|
346
|
-
});
|
|
347
|
-
expect(plan.steps).toHaveLength(6);
|
|
348
|
-
const round2Step = plan.steps.find((s) => s.round === 2);
|
|
349
|
-
expect(round2Step.prompt).toContain("coordinator-replace-at-runtime");
|
|
350
|
-
});
|
|
351
|
-
});
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Topology → ReviewUnitExecutor mapping.
|
|
3
|
-
*
|
|
4
|
-
* # What this module is
|
|
5
|
-
*
|
|
6
|
-
* A thin function seat that maps a resolved `ExecutionTopology` (from
|
|
7
|
-
* `src/core-runtime/review/execution-topology-resolver.ts`) to the concrete
|
|
8
|
-
* `ReviewUnitExecutorConfig` (bin + argv) used by
|
|
9
|
-
* `executeReviewPromptExecution` to spawn each lens / synthesize unit.
|
|
10
|
-
*
|
|
11
|
-
* # Why it exists
|
|
12
|
-
*
|
|
13
|
-
* Topology is the primary decision seat. This module maps topology metadata
|
|
14
|
-
* to the executor binary for per-lens reasoning.
|
|
15
|
-
*
|
|
16
|
-
* The mapping is deterministic — it reads only `topology.lens_spawn_mechanism`:
|
|
17
|
-
*
|
|
18
|
-
* - `codex-subprocess` → codex-review-unit-executor.ts
|
|
19
|
-
* - `claude-agent-tool` → coordinator-start handoff path
|
|
20
|
-
* (no standalone executor binary; the
|
|
21
|
-
* Claude coordinator subagent spawns
|
|
22
|
-
* lens subagents via its own Agent tool)
|
|
23
|
-
* - `claude-teamcreate-member` → controlled lens deliberation transport
|
|
24
|
-
*
|
|
25
|
-
* # How it relates
|
|
26
|
-
*
|
|
27
|
-
* - `resolveExecutionTopology()` decides WHICH topology applies.
|
|
28
|
-
* - `mapTopologyToExecutorConfig()` (here) decides HOW to run each lens
|
|
29
|
-
* under that topology at the TS subprocess level.
|
|
30
|
-
* - The TeamCreate teamlead layer (`cc-teams-*` variants vs `cc-main-*`)
|
|
31
|
-
* is an orthogonal coordinator-state-machine concern — same lens
|
|
32
|
-
* executor applies within either teamlead pattern.
|
|
33
|
-
*/
|
|
34
|
-
// ---------------------------------------------------------------------------
|
|
35
|
-
// Direct executor support set
|
|
36
|
-
// ---------------------------------------------------------------------------
|
|
37
|
-
/**
|
|
38
|
-
* Topology ids whose lens spawn path is wired to a direct executor.
|
|
39
|
-
*/
|
|
40
|
-
export const EXECUTOR_MAPPING_SUPPORTED_TOPOLOGIES = new Set([
|
|
41
|
-
"cc-main-agent-subagent",
|
|
42
|
-
"cc-main-codex-subprocess",
|
|
43
|
-
"codex-main-subprocess",
|
|
44
|
-
"cc-teams-agent-subagent",
|
|
45
|
-
"cc-teams-codex-subprocess",
|
|
46
|
-
]);
|
|
47
|
-
/**
|
|
48
|
-
* Mechanisms whose executor binary lives in the onto TS distribution.
|
|
49
|
-
*
|
|
50
|
-
* `claude-agent-tool` is NOT in this set — there is no standalone binary
|
|
51
|
-
* for it; lens subagents are spawned by the Claude coordinator via its
|
|
52
|
-
* own Agent tool invocation, not via `child_process.spawn` from TS.
|
|
53
|
-
*/
|
|
54
|
-
const TS_EXECUTABLE_MECHANISMS = new Set([
|
|
55
|
-
"codex-subprocess",
|
|
56
|
-
]);
|
|
57
|
-
/**
|
|
58
|
-
* True when the topology's lens spawn mechanism resolves to a TS-executable
|
|
59
|
-
* binary (`codex-review-unit-executor.ts`), i.e. the caller can invoke
|
|
60
|
-
* `mapTopologyToExecutorConfig()` and feed the result to
|
|
61
|
-
* `executeReviewPromptExecution()`.
|
|
62
|
-
*
|
|
63
|
-
* For `claude-agent-tool` topologies the caller must route via the
|
|
64
|
-
* coordinator-start handoff instead — no subprocess executor exists.
|
|
65
|
-
*/
|
|
66
|
-
export function hasStandaloneLensExecutor(topology) {
|
|
67
|
-
return TS_EXECUTABLE_MECHANISMS.has(topology.lens_spawn_mechanism);
|
|
68
|
-
}
|
|
69
|
-
// ---------------------------------------------------------------------------
|
|
70
|
-
// Error types
|
|
71
|
-
// ---------------------------------------------------------------------------
|
|
72
|
-
export class TopologyExecutorMappingError extends Error {
|
|
73
|
-
topologyId;
|
|
74
|
-
reason;
|
|
75
|
-
constructor(topologyId, reason) {
|
|
76
|
-
super(`ExecutionTopology id="${topologyId}" 를 ReviewUnitExecutor 로 매핑할 수 없습니다: ${reason}`);
|
|
77
|
-
this.topologyId = topologyId;
|
|
78
|
-
this.reason = reason;
|
|
79
|
-
this.name = "TopologyExecutorMappingError";
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
// ---------------------------------------------------------------------------
|
|
83
|
-
// Executor config builders (delegate to existing binary paths)
|
|
84
|
-
// ---------------------------------------------------------------------------
|
|
85
|
-
/**
|
|
86
|
-
* Kept local (not imported from review-invoke) to avoid circular imports
|
|
87
|
-
* — review-invoke.ts already imports from cli/run-review-prompt-execution,
|
|
88
|
-
* and this module imports from cli/run-review-prompt-execution's type
|
|
89
|
-
* exports. Direct dependency on review-invoke would close the cycle.
|
|
90
|
-
*/
|
|
91
|
-
import path from "node:path";
|
|
92
|
-
function codexExecutorConfig(ontoHome) {
|
|
93
|
-
return {
|
|
94
|
-
bin: "node",
|
|
95
|
-
args: [path.join(ontoHome, "dist", "core-runtime", "cli", "codex-review-unit-executor.js")],
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
// ---------------------------------------------------------------------------
|
|
99
|
-
// Main mapping function
|
|
100
|
-
// ---------------------------------------------------------------------------
|
|
101
|
-
/**
|
|
102
|
-
* Map a resolved topology to the review-unit executor that handles each
|
|
103
|
-
* lens / synthesize invocation under that topology.
|
|
104
|
-
*
|
|
105
|
-
* Throws `TopologyExecutorMappingError` when:
|
|
106
|
-
* - The topology id is not in `EXECUTOR_MAPPING_SUPPORTED_TOPOLOGIES` (caller should
|
|
107
|
-
* not reach this function for unsupported ids; guard upstream).
|
|
108
|
-
* - The lens_spawn_mechanism requires a TS-invisible dispatch path
|
|
109
|
-
* (`claude-agent-tool`, `claude-teamcreate-member`) —
|
|
110
|
-
* these are not subprocess executors; see `hasStandaloneLensExecutor`.
|
|
111
|
-
*
|
|
112
|
-
* This module's scope is mechanism→binary, not config→argv.
|
|
113
|
-
*/
|
|
114
|
-
export function mapTopologyToExecutorConfig(topology, ontoHome) {
|
|
115
|
-
if (!EXECUTOR_MAPPING_SUPPORTED_TOPOLOGIES.has(topology.id)) {
|
|
116
|
-
throw new TopologyExecutorMappingError(topology.id, `Executor mapping 지원 set 밖. 지원되는 옵션: ${[...EXECUTOR_MAPPING_SUPPORTED_TOPOLOGIES].join(", ")}`);
|
|
117
|
-
}
|
|
118
|
-
switch (topology.lens_spawn_mechanism) {
|
|
119
|
-
case "codex-subprocess":
|
|
120
|
-
return codexExecutorConfig(ontoHome);
|
|
121
|
-
case "claude-agent-tool":
|
|
122
|
-
throw new TopologyExecutorMappingError(topology.id, "claude-agent-tool lens spawn 은 coordinator-start handoff 로 route 하세요 " +
|
|
123
|
-
"(Claude coordinator subagent 가 Agent tool 로 lens subagent 를 spawn). " +
|
|
124
|
-
"Subprocess executor 가 존재하지 않습니다.");
|
|
125
|
-
case "claude-teamcreate-member":
|
|
126
|
-
throw new TopologyExecutorMappingError(topology.id, "claude-teamcreate-member lens spawn 은 controlled lens deliberation transport 에서 다룹니다.");
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
/** Drop `plan_trace` for handoff transmission. */
|
|
130
|
-
export function toCoordinatorTopologyDescriptor(topology) {
|
|
131
|
-
return {
|
|
132
|
-
id: topology.id,
|
|
133
|
-
teamlead_location: topology.teamlead_location,
|
|
134
|
-
lens_spawn_mechanism: topology.lens_spawn_mechanism,
|
|
135
|
-
max_concurrent_lenses: topology.max_concurrent_lenses,
|
|
136
|
-
transport_rank: topology.transport_rank,
|
|
137
|
-
deliberation_channel: topology.deliberation_channel,
|
|
138
|
-
};
|
|
139
|
-
}
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { TOPOLOGY_CATALOG, } from "../review/execution-topology-resolver.js";
|
|
3
|
-
import { PR_B_SUPPORTED_TOPOLOGIES, TopologyExecutorMappingError, hasStandaloneLensExecutor, mapTopologyToExecutorConfig, toCoordinatorTopologyDescriptor, } from "./topology-executor-mapping.js";
|
|
4
|
-
// ---------------------------------------------------------------------------
|
|
5
|
-
// These tests assert the PR-B mapping invariants:
|
|
6
|
-
//
|
|
7
|
-
// (1) The PR-B supported set is exactly {2-1, 2-2, codex-B, 1-1, 1-2, 3-1} —
|
|
8
|
-
// the 3 PR-A options plus the 3 TeamCreate-teamlead options whose lens
|
|
9
|
-
// spawn mechanism reuses existing executor binaries.
|
|
10
|
-
//
|
|
11
|
-
// (2) Mapping is deterministic per lens_spawn_mechanism:
|
|
12
|
-
// codex-subprocess → codex-review-unit-executor
|
|
13
|
-
// litellm-http → inline-http-review-unit-executor
|
|
14
|
-
// claude-agent-tool / claude-teamcreate-member / generic-subagent
|
|
15
|
-
// → throw (no subprocess binary exists)
|
|
16
|
-
//
|
|
17
|
-
// (3) `hasStandaloneLensExecutor` agrees with the mapping's throw/return shape.
|
|
18
|
-
//
|
|
19
|
-
// (4) `toCoordinatorTopologyDescriptor` strips plan_trace but preserves all
|
|
20
|
-
// other topology attributes — the handoff payload stays compact.
|
|
21
|
-
// ---------------------------------------------------------------------------
|
|
22
|
-
const FAKE_ONTO_HOME = "/tmp/fake-onto-home";
|
|
23
|
-
function synthesize(id) {
|
|
24
|
-
return {
|
|
25
|
-
...TOPOLOGY_CATALOG[id],
|
|
26
|
-
plan_trace: [`synthesized for test: ${id}`],
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
// ---------------------------------------------------------------------------
|
|
30
|
-
// Support set
|
|
31
|
-
// ---------------------------------------------------------------------------
|
|
32
|
-
describe("PR_B_SUPPORTED_TOPOLOGIES", () => {
|
|
33
|
-
it("contains exactly 6 topologies (PR-A 3 + PR-B 3)", () => {
|
|
34
|
-
expect(PR_B_SUPPORTED_TOPOLOGIES.size).toBe(6);
|
|
35
|
-
expect(PR_B_SUPPORTED_TOPOLOGIES.has("cc-main-agent-subagent")).toBe(true);
|
|
36
|
-
expect(PR_B_SUPPORTED_TOPOLOGIES.has("cc-main-codex-subprocess")).toBe(true);
|
|
37
|
-
expect(PR_B_SUPPORTED_TOPOLOGIES.has("codex-main-subprocess")).toBe(true);
|
|
38
|
-
expect(PR_B_SUPPORTED_TOPOLOGIES.has("cc-teams-agent-subagent")).toBe(true);
|
|
39
|
-
expect(PR_B_SUPPORTED_TOPOLOGIES.has("cc-teams-codex-subprocess")).toBe(true);
|
|
40
|
-
expect(PR_B_SUPPORTED_TOPOLOGIES.has("cc-teams-litellm-sessions")).toBe(true);
|
|
41
|
-
});
|
|
42
|
-
it("does NOT include 1-0 deliberation (PR-D scope)", () => {
|
|
43
|
-
expect(PR_B_SUPPORTED_TOPOLOGIES.has("cc-teams-lens-agent-deliberation")).toBe(false);
|
|
44
|
-
});
|
|
45
|
-
it("does NOT include codex-nested (PR-C scope)", () => {
|
|
46
|
-
expect(PR_B_SUPPORTED_TOPOLOGIES.has("codex-nested-subprocess")).toBe(false);
|
|
47
|
-
});
|
|
48
|
-
// P7 (2026-04-21): generic-* removed entirely from TopologyId enum.
|
|
49
|
-
// Previous test "does NOT include generic-*" is no longer meaningful —
|
|
50
|
-
// the type system now prevents generic-* from existing anywhere.
|
|
51
|
-
});
|
|
52
|
-
// ---------------------------------------------------------------------------
|
|
53
|
-
// mapTopologyToExecutorConfig — codex mechanisms
|
|
54
|
-
// ---------------------------------------------------------------------------
|
|
55
|
-
describe("mapTopologyToExecutorConfig — codex-subprocess", () => {
|
|
56
|
-
it("2-2 cc-main-codex-subprocess → codex executor", () => {
|
|
57
|
-
const cfg = mapTopologyToExecutorConfig(synthesize("cc-main-codex-subprocess"), FAKE_ONTO_HOME);
|
|
58
|
-
expect(cfg.bin).toBe("node");
|
|
59
|
-
expect(cfg.args[0]).toContain("codex-review-unit-executor.js");
|
|
60
|
-
expect(cfg.args[0]).toContain(FAKE_ONTO_HOME);
|
|
61
|
-
});
|
|
62
|
-
it("codex-B codex-main-subprocess → codex executor", () => {
|
|
63
|
-
const cfg = mapTopologyToExecutorConfig(synthesize("codex-main-subprocess"), FAKE_ONTO_HOME);
|
|
64
|
-
expect(cfg.args[0]).toContain("codex-review-unit-executor.js");
|
|
65
|
-
});
|
|
66
|
-
it("1-2 cc-teams-codex-subprocess → codex executor (same as 2-2 at TS level)", () => {
|
|
67
|
-
const cfg = mapTopologyToExecutorConfig(synthesize("cc-teams-codex-subprocess"), FAKE_ONTO_HOME);
|
|
68
|
-
expect(cfg.args[0]).toContain("codex-review-unit-executor.js");
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
// ---------------------------------------------------------------------------
|
|
72
|
-
// mapTopologyToExecutorConfig — litellm-http
|
|
73
|
-
// ---------------------------------------------------------------------------
|
|
74
|
-
describe("mapTopologyToExecutorConfig — litellm-http", () => {
|
|
75
|
-
it("3-1 cc-teams-litellm-sessions → inline-http executor", () => {
|
|
76
|
-
const cfg = mapTopologyToExecutorConfig(synthesize("cc-teams-litellm-sessions"), FAKE_ONTO_HOME);
|
|
77
|
-
expect(cfg.bin).toBe("node");
|
|
78
|
-
expect(cfg.args[0]).toContain("inline-http-review-unit-executor.js");
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
// ---------------------------------------------------------------------------
|
|
82
|
-
// mapTopologyToExecutorConfig — claude-agent-tool (no binary; throw)
|
|
83
|
-
// ---------------------------------------------------------------------------
|
|
84
|
-
describe("mapTopologyToExecutorConfig — claude-agent-tool", () => {
|
|
85
|
-
it("2-1 cc-main-agent-subagent throws (route via coordinator-start handoff)", () => {
|
|
86
|
-
expect(() => mapTopologyToExecutorConfig(synthesize("cc-main-agent-subagent"), FAKE_ONTO_HOME)).toThrow(TopologyExecutorMappingError);
|
|
87
|
-
});
|
|
88
|
-
it("1-1 cc-teams-agent-subagent throws (route via coordinator-start handoff)", () => {
|
|
89
|
-
expect(() => mapTopologyToExecutorConfig(synthesize("cc-teams-agent-subagent"), FAKE_ONTO_HOME)).toThrow(TopologyExecutorMappingError);
|
|
90
|
-
});
|
|
91
|
-
it("claude-agent-tool throw mentions coordinator-start handoff path", () => {
|
|
92
|
-
try {
|
|
93
|
-
mapTopologyToExecutorConfig(synthesize("cc-main-agent-subagent"), FAKE_ONTO_HOME);
|
|
94
|
-
expect.fail("expected throw");
|
|
95
|
-
}
|
|
96
|
-
catch (err) {
|
|
97
|
-
expect(err).toBeInstanceOf(TopologyExecutorMappingError);
|
|
98
|
-
expect(err.message).toContain("coordinator-start handoff");
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
// ---------------------------------------------------------------------------
|
|
103
|
-
// mapTopologyToExecutorConfig — unsupported ids
|
|
104
|
-
// ---------------------------------------------------------------------------
|
|
105
|
-
describe("mapTopologyToExecutorConfig — unsupported", () => {
|
|
106
|
-
it("1-0 cc-teams-lens-agent-deliberation throws (outside PR-B support set)", () => {
|
|
107
|
-
expect(() => mapTopologyToExecutorConfig(synthesize("cc-teams-lens-agent-deliberation"), FAKE_ONTO_HOME)).toThrow(TopologyExecutorMappingError);
|
|
108
|
-
});
|
|
109
|
-
it("codex-A codex-nested-subprocess throws (outside PR-B; PR-C scope)", () => {
|
|
110
|
-
expect(() => mapTopologyToExecutorConfig(synthesize("codex-nested-subprocess"), FAKE_ONTO_HOME)).toThrow(TopologyExecutorMappingError);
|
|
111
|
-
});
|
|
112
|
-
// P7 (2026-04-21): generic-* removed from TopologyId. Their "reserved"
|
|
113
|
-
// guard is no longer needed — the type system prevents the values from
|
|
114
|
-
// appearing at all.
|
|
115
|
-
it("error message lists all PR-B supported ids for discoverability", () => {
|
|
116
|
-
try {
|
|
117
|
-
mapTopologyToExecutorConfig(synthesize("codex-nested-subprocess"), FAKE_ONTO_HOME);
|
|
118
|
-
expect.fail("expected throw");
|
|
119
|
-
}
|
|
120
|
-
catch (err) {
|
|
121
|
-
const msg = err.message;
|
|
122
|
-
for (const id of PR_B_SUPPORTED_TOPOLOGIES) {
|
|
123
|
-
expect(msg).toContain(id);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
// ---------------------------------------------------------------------------
|
|
129
|
-
// hasStandaloneLensExecutor
|
|
130
|
-
// ---------------------------------------------------------------------------
|
|
131
|
-
describe("hasStandaloneLensExecutor", () => {
|
|
132
|
-
it("codex-subprocess mechanisms have a TS executor binary", () => {
|
|
133
|
-
expect(hasStandaloneLensExecutor(synthesize("cc-main-codex-subprocess"))).toBe(true);
|
|
134
|
-
expect(hasStandaloneLensExecutor(synthesize("cc-teams-codex-subprocess"))).toBe(true);
|
|
135
|
-
expect(hasStandaloneLensExecutor(synthesize("codex-main-subprocess"))).toBe(true);
|
|
136
|
-
expect(hasStandaloneLensExecutor(synthesize("codex-nested-subprocess"))).toBe(true);
|
|
137
|
-
});
|
|
138
|
-
it("litellm-http mechanism has a TS executor binary", () => {
|
|
139
|
-
expect(hasStandaloneLensExecutor(synthesize("cc-teams-litellm-sessions"))).toBe(true);
|
|
140
|
-
});
|
|
141
|
-
it("claude-agent-tool mechanisms do NOT have a TS executor binary", () => {
|
|
142
|
-
expect(hasStandaloneLensExecutor(synthesize("cc-main-agent-subagent"))).toBe(false);
|
|
143
|
-
expect(hasStandaloneLensExecutor(synthesize("cc-teams-agent-subagent"))).toBe(false);
|
|
144
|
-
});
|
|
145
|
-
it("claude-teamcreate-member (1-0 deliberation) does NOT have a TS executor binary", () => {
|
|
146
|
-
expect(hasStandaloneLensExecutor(synthesize("cc-teams-lens-agent-deliberation"))).toBe(false);
|
|
147
|
-
});
|
|
148
|
-
// P7 (2026-04-21): generic-subagent mechanism tests removed along with
|
|
149
|
-
// generic-* TopologyId values.
|
|
150
|
-
});
|
|
151
|
-
// ---------------------------------------------------------------------------
|
|
152
|
-
// toCoordinatorTopologyDescriptor
|
|
153
|
-
// ---------------------------------------------------------------------------
|
|
154
|
-
describe("toCoordinatorTopologyDescriptor", () => {
|
|
155
|
-
it("preserves all topology attributes except plan_trace", () => {
|
|
156
|
-
const topology = synthesize("cc-teams-codex-subprocess");
|
|
157
|
-
const descriptor = toCoordinatorTopologyDescriptor(topology);
|
|
158
|
-
expect(descriptor.id).toBe(topology.id);
|
|
159
|
-
expect(descriptor.teamlead_location).toBe(topology.teamlead_location);
|
|
160
|
-
expect(descriptor.lens_spawn_mechanism).toBe(topology.lens_spawn_mechanism);
|
|
161
|
-
expect(descriptor.max_concurrent_lenses).toBe(topology.max_concurrent_lenses);
|
|
162
|
-
expect(descriptor.transport_rank).toBe(topology.transport_rank);
|
|
163
|
-
expect(descriptor.deliberation_channel).toBe(topology.deliberation_channel);
|
|
164
|
-
expect(Object.keys(descriptor)).not.toContain("plan_trace");
|
|
165
|
-
});
|
|
166
|
-
it("is JSON-serializable (handoff transport requirement)", () => {
|
|
167
|
-
const topology = synthesize("cc-teams-lens-agent-deliberation");
|
|
168
|
-
const descriptor = toCoordinatorTopologyDescriptor(topology);
|
|
169
|
-
const json = JSON.stringify(descriptor);
|
|
170
|
-
const parsed = JSON.parse(json);
|
|
171
|
-
expect(parsed).toEqual(descriptor);
|
|
172
|
-
});
|
|
173
|
-
});
|