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,208 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Evolve full cycle E2E test (W-B-01).
|
|
3
|
-
*
|
|
4
|
-
* scope-runtime kernel 위에서 evolve 활동의 전체 lifecycle 을 검증한다:
|
|
5
|
-
* draft → grounded → align_proposed → align_locked → surface_iterating →
|
|
6
|
-
* surface_confirmed → constraints_resolved → target_locked → compiled →
|
|
7
|
-
* applied → validated → closed
|
|
8
|
-
*
|
|
9
|
-
* 초기 scope 생성(grounding)은 appendScopeEvent 로 직접 설정하고,
|
|
10
|
-
* align 이후는 실제 command 함수(executeAlign/executeDraft/executeApply/executeClose)를 사용.
|
|
11
|
-
*/
|
|
12
|
-
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
13
|
-
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
14
|
-
import { join } from "node:path";
|
|
15
|
-
import { tmpdir } from "node:os";
|
|
16
|
-
import { createScope } from "../../scope-runtime/scope-manager.js";
|
|
17
|
-
import { appendScopeEvent } from "../../scope-runtime/event-pipeline.js";
|
|
18
|
-
import { readEvents } from "../../scope-runtime/event-store.js";
|
|
19
|
-
import { reduce } from "../../scope-runtime/reducer.js";
|
|
20
|
-
import { executeAlign } from "./align.js";
|
|
21
|
-
import { executeDraft } from "./draft.js";
|
|
22
|
-
import { executeApply } from "./apply.js";
|
|
23
|
-
import { executeClose } from "./close.js";
|
|
24
|
-
let tmpDir;
|
|
25
|
-
beforeEach(() => { tmpDir = mkdtempSync(join(tmpdir(), "e2e-evolve-")); });
|
|
26
|
-
afterEach(() => { rmSync(tmpDir, { recursive: true, force: true }); });
|
|
27
|
-
describe("evolve full cycle E2E", () => {
|
|
28
|
-
it("draft → closed: 전체 lifecycle 을 command 함수로 통과한다", () => {
|
|
29
|
-
// ── Phase 0: Scope 생성 + Grounding ──
|
|
30
|
-
writeFileSync(join(tmpDir, ".sprint-kit.yaml"), "apply_enabled: true\ndefault_sources: []\n", "utf-8");
|
|
31
|
-
const paths = createScope(tmpDir, "E2E-FULL-001");
|
|
32
|
-
appendScopeEvent(paths, {
|
|
33
|
-
type: "scope.created",
|
|
34
|
-
actor: "user",
|
|
35
|
-
payload: { title: "E2E Full Cycle", description: "evolve full cycle test", entry_mode: "experience" },
|
|
36
|
-
});
|
|
37
|
-
appendScopeEvent(paths, {
|
|
38
|
-
type: "grounding.started",
|
|
39
|
-
actor: "system",
|
|
40
|
-
payload: { sources: [{ type: "add-dir", path_or_url: "/test-project" }] },
|
|
41
|
-
});
|
|
42
|
-
appendScopeEvent(paths, {
|
|
43
|
-
type: "grounding.completed",
|
|
44
|
-
actor: "system",
|
|
45
|
-
payload: { snapshot_revision: 1, source_hashes: { "add-dir:/test-project": "h1" }, perspective_summary: { experience: 1, code: 1, policy: 1 } },
|
|
46
|
-
});
|
|
47
|
-
appendScopeEvent(paths, {
|
|
48
|
-
type: "align.proposed",
|
|
49
|
-
actor: "system",
|
|
50
|
-
payload: { packet_path: "build/align-packet.md", packet_hash: "ap1", snapshot_revision: 1 },
|
|
51
|
-
});
|
|
52
|
-
let state = reduce(readEvents(paths.events));
|
|
53
|
-
expect(state.current_state).toBe("align_proposed");
|
|
54
|
-
// ── Phase 1: Align (executeAlign) ──
|
|
55
|
-
const alignResult = executeAlign({
|
|
56
|
-
paths,
|
|
57
|
-
verdict: {
|
|
58
|
-
type: "approve",
|
|
59
|
-
direction: "사용자 온보딩 흐름 개선",
|
|
60
|
-
scope_in: ["login", "signup"],
|
|
61
|
-
scope_out: ["admin"],
|
|
62
|
-
},
|
|
63
|
-
});
|
|
64
|
-
expect(alignResult.success).toBe(true);
|
|
65
|
-
if (!alignResult.success)
|
|
66
|
-
return;
|
|
67
|
-
expect(alignResult.nextState).toBe("align_locked");
|
|
68
|
-
state = reduce(readEvents(paths.events));
|
|
69
|
-
expect(state.current_state).toBe("align_locked");
|
|
70
|
-
// ── Phase 2: Draft — Surface 생성 (executeDraft) ──
|
|
71
|
-
const genResult = executeDraft({
|
|
72
|
-
paths,
|
|
73
|
-
action: { type: "generate_surface", surfacePath: "surface/preview/", surfaceHash: "sf1", snapshotRevision: 1 },
|
|
74
|
-
});
|
|
75
|
-
expect(genResult.success).toBe(true);
|
|
76
|
-
if (!genResult.success)
|
|
77
|
-
return;
|
|
78
|
-
expect(genResult.nextState).toBe("surface_iterating");
|
|
79
|
-
// ── Phase 2b: Surface 확인 ──
|
|
80
|
-
const confirmResult = executeDraft({
|
|
81
|
-
paths,
|
|
82
|
-
action: { type: "confirm_surface", surfacePath: "surface/preview/", surfaceHash: "sf1" },
|
|
83
|
-
});
|
|
84
|
-
expect(confirmResult.success).toBe(true);
|
|
85
|
-
if (!confirmResult.success)
|
|
86
|
-
return;
|
|
87
|
-
expect(confirmResult.nextState).toBe("surface_confirmed");
|
|
88
|
-
// ── Phase 2c: Constraint 발견 + 결정 ──
|
|
89
|
-
const constraintResult = executeDraft({
|
|
90
|
-
paths,
|
|
91
|
-
action: {
|
|
92
|
-
type: "record_constraint",
|
|
93
|
-
constraintPayload: {
|
|
94
|
-
constraint_id: "CST-E2E-001",
|
|
95
|
-
perspective: "code",
|
|
96
|
-
summary: "기존 인증 모듈과 호환성 필요",
|
|
97
|
-
severity: "required",
|
|
98
|
-
discovery_stage: "draft_phase2",
|
|
99
|
-
decision_owner: "product_owner",
|
|
100
|
-
impact_if_ignored: "로그인 기능 장애",
|
|
101
|
-
source_refs: [{ source: "auth.ts", detail: "OAuth 의존성" }],
|
|
102
|
-
},
|
|
103
|
-
},
|
|
104
|
-
});
|
|
105
|
-
expect(constraintResult.success).toBe(true);
|
|
106
|
-
const decisionResult = executeDraft({
|
|
107
|
-
paths,
|
|
108
|
-
action: {
|
|
109
|
-
type: "record_decision",
|
|
110
|
-
decisionPayload: {
|
|
111
|
-
constraint_id: "CST-E2E-001",
|
|
112
|
-
decision: "inject",
|
|
113
|
-
selected_option: "호환 래퍼 추가",
|
|
114
|
-
decision_owner: "product_owner",
|
|
115
|
-
rationale: "기존 모듈 변경 최소화",
|
|
116
|
-
},
|
|
117
|
-
},
|
|
118
|
-
});
|
|
119
|
-
expect(decisionResult.success).toBe(true);
|
|
120
|
-
state = reduce(readEvents(paths.events));
|
|
121
|
-
expect(state.current_state).toBe("constraints_resolved");
|
|
122
|
-
// ── Phase 2d: Target 잠금 ──
|
|
123
|
-
const lockResult = executeDraft({
|
|
124
|
-
paths,
|
|
125
|
-
action: { type: "lock_target" },
|
|
126
|
-
});
|
|
127
|
-
expect(lockResult.success).toBe(true);
|
|
128
|
-
if (!lockResult.success)
|
|
129
|
-
return;
|
|
130
|
-
expect(lockResult.nextState).toBe("target_locked");
|
|
131
|
-
// ── Phase 2e: Compile ──
|
|
132
|
-
// compile 은 code-product adapter 를 호출하므로, compile.started/completed 를 직접 기록
|
|
133
|
-
appendScopeEvent(paths, {
|
|
134
|
-
type: "compile.started",
|
|
135
|
-
actor: "system",
|
|
136
|
-
payload: { snapshot_revision: 1, surface_hash: "sf1" },
|
|
137
|
-
});
|
|
138
|
-
appendScopeEvent(paths, {
|
|
139
|
-
type: "compile.completed",
|
|
140
|
-
actor: "system",
|
|
141
|
-
payload: {
|
|
142
|
-
build_spec_path: "build/build-spec.md", build_spec_hash: "bs1",
|
|
143
|
-
brownfield_detail_path: "build/brownfield-detail.md", brownfield_detail_hash: "bf1",
|
|
144
|
-
delta_set_path: "build/delta-set.json", delta_set_hash: "ds1",
|
|
145
|
-
validation_plan_path: "build/validation-plan.md", validation_plan_hash: "vp1",
|
|
146
|
-
},
|
|
147
|
-
});
|
|
148
|
-
state = reduce(readEvents(paths.events));
|
|
149
|
-
expect(state.current_state).toBe("compiled");
|
|
150
|
-
// ── Phase 3: Apply (executeApply) ──
|
|
151
|
-
// pre-apply + PRD review gate 통과
|
|
152
|
-
appendScopeEvent(paths, { type: "pre_apply.review_completed", actor: "agent", payload: { verdict: "pass", findings: [] } });
|
|
153
|
-
appendScopeEvent(paths, { type: "prd.review_completed", actor: "agent", payload: { verdict: "pass", perspectives: ["prd_logic"], findings: [] } });
|
|
154
|
-
const applyStartResult = executeApply(paths, { type: "start_apply", buildSpecHash: "bs1" }, { projectRoot: tmpDir });
|
|
155
|
-
expect(applyStartResult.success).toBe(true);
|
|
156
|
-
const applyCompleteResult = executeApply(paths, { type: "complete_apply", result: "success" });
|
|
157
|
-
expect(applyCompleteResult.success).toBe(true);
|
|
158
|
-
if (!applyCompleteResult.success)
|
|
159
|
-
return;
|
|
160
|
-
expect(applyCompleteResult.nextState).toBe("applied");
|
|
161
|
-
// ── Phase 4: Validation (executeApply) ──
|
|
162
|
-
const valStartResult = executeApply(paths, { type: "start_validation", validationPlanHash: "vp1" });
|
|
163
|
-
expect(valStartResult.success).toBe(true);
|
|
164
|
-
const valCompleteResult = executeApply(paths, {
|
|
165
|
-
type: "complete_validation",
|
|
166
|
-
plan: [{
|
|
167
|
-
val_id: "VAL-001",
|
|
168
|
-
related_cst: "CST-E2E-001",
|
|
169
|
-
decision_type: "inject",
|
|
170
|
-
target: "auth.ts",
|
|
171
|
-
method: "수동 테스트",
|
|
172
|
-
pass_criteria: "온보딩 흐름 정상 동작",
|
|
173
|
-
fail_action: "호환 래퍼 재구현",
|
|
174
|
-
}],
|
|
175
|
-
results: [{ val_id: "VAL-001", related_cst: "CST-E2E-001", result: "pass", detail: "수동 테스트 통과" }],
|
|
176
|
-
actualPlanHash: "vp1",
|
|
177
|
-
});
|
|
178
|
-
expect(valCompleteResult.success).toBe(true);
|
|
179
|
-
if (!valCompleteResult.success)
|
|
180
|
-
return;
|
|
181
|
-
expect(valCompleteResult.nextState).toBe("validated");
|
|
182
|
-
state = reduce(readEvents(paths.events));
|
|
183
|
-
expect(state.current_state).toBe("validated");
|
|
184
|
-
// ── Phase 5: Close (executeClose) ──
|
|
185
|
-
const closeResult = executeClose(paths);
|
|
186
|
-
expect(closeResult.success).toBe(true);
|
|
187
|
-
if (!closeResult.success)
|
|
188
|
-
return;
|
|
189
|
-
expect(closeResult.nextState).toBe("closed");
|
|
190
|
-
// ── Final verification ──
|
|
191
|
-
state = reduce(readEvents(paths.events));
|
|
192
|
-
expect(state.current_state).toBe("closed");
|
|
193
|
-
const events = readEvents(paths.events);
|
|
194
|
-
expect(events.length).toBeGreaterThanOrEqual(18);
|
|
195
|
-
// 핵심 상태 전이가 모두 기록되었는지 확인
|
|
196
|
-
const eventTypes = events.map(e => e.type);
|
|
197
|
-
expect(eventTypes).toContain("scope.created");
|
|
198
|
-
expect(eventTypes).toContain("grounding.completed");
|
|
199
|
-
expect(eventTypes).toContain("align.locked");
|
|
200
|
-
expect(eventTypes).toContain("surface.confirmed");
|
|
201
|
-
expect(eventTypes).toContain("constraint.decision_recorded");
|
|
202
|
-
expect(eventTypes).toContain("target.locked");
|
|
203
|
-
expect(eventTypes).toContain("compile.completed");
|
|
204
|
-
expect(eventTypes).toContain("apply.completed");
|
|
205
|
-
expect(eventTypes).toContain("validation.completed");
|
|
206
|
-
expect(eventTypes).toContain("scope.closed");
|
|
207
|
-
});
|
|
208
|
-
});
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Gate-guard error wrapping — Principal-facing Korean messages.
|
|
3
|
-
*
|
|
4
|
-
* W-B-08 (BL-044): 기존 문자열 매칭 switch 를 .onto/authority/diagnostic-codes.yaml
|
|
5
|
-
* 기반 code registry 로 전환. 매칭 우선순위는 registry entry 순서를 따른다.
|
|
6
|
-
*
|
|
7
|
-
* Registry seat: .onto/authority/diagnostic-codes.yaml (authority-adjacent data seat).
|
|
8
|
-
* Concept SSOT 아님 — citation check 대상 아님.
|
|
9
|
-
*
|
|
10
|
-
* 보증:
|
|
11
|
-
* - Registry load 시 schema validation (code 유일성 + 최소 1 matcher + matcher 형식).
|
|
12
|
-
* violation 발견 시 load 실패 → fail-fast.
|
|
13
|
-
* - lookupDiagnosticCode 미매칭 시 console.warn — silent fail 방지.
|
|
14
|
-
* (영문 reason 원문이 Principal 에 노출되는 UX 버그를 즉시 감지 가능.)
|
|
15
|
-
*/
|
|
16
|
-
import { readFileSync } from "node:fs";
|
|
17
|
-
import { fileURLToPath } from "node:url";
|
|
18
|
-
import { dirname, join } from "node:path";
|
|
19
|
-
import { parse as yamlParse } from "yaml";
|
|
20
|
-
import { resolveInstallationPath } from "../../discovery/installation-paths.js";
|
|
21
|
-
// ─── Registry load ───
|
|
22
|
-
let cachedRegistry = null;
|
|
23
|
-
function resolveRegistryPath() {
|
|
24
|
-
// dist / src 양쪽에서 작동:
|
|
25
|
-
// src: src/core-runtime/evolve/commands/error-messages.ts
|
|
26
|
-
// dist: dist/core-runtime/evolve/commands/error-messages.js
|
|
27
|
-
// 양쪽 모두 4 단계 위가 repo root. Authority dir 선택은 Phase 0
|
|
28
|
-
// 공유 resolver 에 위임 — canonical `.onto/authority/` 에서 resolve.
|
|
29
|
-
// Phase 7 (2026-04-21) 에서 legacy fallback 제거됨.
|
|
30
|
-
const here = dirname(fileURLToPath(import.meta.url));
|
|
31
|
-
const repoRoot = join(here, "..", "..", "..", "..");
|
|
32
|
-
const authorityDir = resolveInstallationPath("authority", repoRoot);
|
|
33
|
-
return join(authorityDir, "diagnostic-codes.yaml");
|
|
34
|
-
}
|
|
35
|
-
function loadRegistry() {
|
|
36
|
-
if (cachedRegistry !== null)
|
|
37
|
-
return cachedRegistry;
|
|
38
|
-
const raw = readFileSync(resolveRegistryPath(), "utf-8");
|
|
39
|
-
const parsed = yamlParse(raw);
|
|
40
|
-
if (!parsed || !Array.isArray(parsed.diagnostic_codes)) {
|
|
41
|
-
throw new Error("[diagnostic-codes] invalid registry — diagnostic_codes 배열 없음");
|
|
42
|
-
}
|
|
43
|
-
validateRegistry(parsed);
|
|
44
|
-
cachedRegistry = parsed;
|
|
45
|
-
return parsed;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Registry schema 검증 — code 유일성 + matcher 형식.
|
|
49
|
-
* loadRegistry 내부에서 호출되며, 테스트 용도로도 export.
|
|
50
|
-
*/
|
|
51
|
-
export function validateRegistry(registry) {
|
|
52
|
-
const seenCodes = new Set();
|
|
53
|
-
for (const entry of registry.diagnostic_codes) {
|
|
54
|
-
if (seenCodes.has(entry.code)) {
|
|
55
|
-
throw new Error(`[diagnostic-codes] duplicate code "${entry.code}" — code는 registry 내에서 유일해야 합니다.`);
|
|
56
|
-
}
|
|
57
|
-
seenCodes.add(entry.code);
|
|
58
|
-
if (!Array.isArray(entry.matchers) || entry.matchers.length === 0) {
|
|
59
|
-
throw new Error(`[diagnostic-codes] entry "${entry.code}" has no matchers — 최소 1개 matcher가 필요합니다.`);
|
|
60
|
-
}
|
|
61
|
-
for (let i = 0; i < entry.matchers.length; i++) {
|
|
62
|
-
const m = entry.matchers[i];
|
|
63
|
-
const hasIncludes = typeof m.includes === "string" && m.includes.length > 0;
|
|
64
|
-
const hasIncludesAll = Array.isArray(m.includes_all) && m.includes_all.length > 0;
|
|
65
|
-
if (!hasIncludes && !hasIncludesAll) {
|
|
66
|
-
throw new Error(`[diagnostic-codes] entry "${entry.code}" matcher[${i}] — includes 또는 includes_all 중 하나를 비어있지 않은 값으로 지정해야 합니다.`);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
/** 테스트용 registry 초기화 */
|
|
72
|
-
export function __resetDiagnosticRegistryCache() {
|
|
73
|
-
cachedRegistry = null;
|
|
74
|
-
}
|
|
75
|
-
/** 테스트용 registry 주입 */
|
|
76
|
-
export function __setDiagnosticRegistryForTesting(registry) {
|
|
77
|
-
cachedRegistry = registry;
|
|
78
|
-
}
|
|
79
|
-
// ─── Matching ───
|
|
80
|
-
function matcherMatches(m, reason) {
|
|
81
|
-
if (m.includes !== undefined) {
|
|
82
|
-
return reason.includes(m.includes);
|
|
83
|
-
}
|
|
84
|
-
if (Array.isArray(m.includes_all) && m.includes_all.length > 0) {
|
|
85
|
-
return m.includes_all.every((s) => reason.includes(s));
|
|
86
|
-
}
|
|
87
|
-
return false;
|
|
88
|
-
}
|
|
89
|
-
function entryMatches(entry, reason) {
|
|
90
|
-
return entry.matchers.some((m) => matcherMatches(m, reason));
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* reason 문자열에 매칭되는 diagnostic entry 를 반환한다.
|
|
94
|
-
* 매칭 없으면 null.
|
|
95
|
-
*/
|
|
96
|
-
export function lookupDiagnosticCode(reason) {
|
|
97
|
-
const registry = loadRegistry();
|
|
98
|
-
for (const entry of registry.diagnostic_codes) {
|
|
99
|
-
if (entryMatches(entry, reason)) {
|
|
100
|
-
const message = entry.passthrough ? reason : (entry.message_ko ?? reason);
|
|
101
|
-
return {
|
|
102
|
-
code: entry.code,
|
|
103
|
-
category: entry.category,
|
|
104
|
-
message,
|
|
105
|
-
passthrough: entry.passthrough === true,
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
// Silent failure 방지 — 매칭되지 않은 reason 은 영문 원문이 Principal 에 노출된다.
|
|
110
|
-
// 개발자용 경고를 남겨 registry entry 누락 또는 reason 문구 drift 를 즉시 감지 가능하게.
|
|
111
|
-
console.warn(`[diagnostic-codes] no matching entry for reason: "${reason}". Registry에 새 entry 추가 또는 기존 matcher 보강이 필요합니다.`);
|
|
112
|
-
return null;
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* gate-guard English reason → Principal-facing 한국어 메시지 변환.
|
|
116
|
-
* 매칭 없으면 reason 원문을 그대로 반환.
|
|
117
|
-
*/
|
|
118
|
-
export function wrapGateError(reason) {
|
|
119
|
-
const hit = lookupDiagnosticCode(reason);
|
|
120
|
-
return hit ? hit.message : reason;
|
|
121
|
-
}
|
|
122
|
-
/** 등록된 모든 diagnostic code 의 snapshot (telemetry / 문서화용) */
|
|
123
|
-
export function listDiagnosticCodes() {
|
|
124
|
-
return [...loadRegistry().diagnostic_codes];
|
|
125
|
-
}
|
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, vi } from "vitest";
|
|
2
|
-
import { wrapGateError, lookupDiagnosticCode, listDiagnosticCodes, validateRegistry, __resetDiagnosticRegistryCache, } from "./error-messages.js";
|
|
3
|
-
beforeEach(() => {
|
|
4
|
-
__resetDiagnosticRegistryCache();
|
|
5
|
-
});
|
|
6
|
-
describe("wrapGateError — backward-compatible behavior (기존 7 tests)", () => {
|
|
7
|
-
it("wraps Transition denied → Korean message", () => {
|
|
8
|
-
const reason = 'Transition denied: "draft" does not allow "align.locked"';
|
|
9
|
-
expect(wrapGateError(reason)).toBe("현재 단계에서 이 작업을 수행할 수 없습니다.");
|
|
10
|
-
});
|
|
11
|
-
it("wraps Referential integrity → Korean message", () => {
|
|
12
|
-
const reason = 'Referential integrity: constraint_id "CST-999" not found in pool';
|
|
13
|
-
expect(wrapGateError(reason)).toBe("내부 참조 오류가 발생했습니다. 에이전트가 이벤트를 재확인해야 합니다.");
|
|
14
|
-
});
|
|
15
|
-
it("wraps Required constraint + rationale → Korean message", () => {
|
|
16
|
-
const reason = 'Required constraint "CST-001" with override decision requires non-empty rationale';
|
|
17
|
-
expect(wrapGateError(reason)).toBe("필수 제약 사항을 무시하려면 이유를 반드시 입력해야 합니다.");
|
|
18
|
-
});
|
|
19
|
-
it("wraps Convergence blocked → Korean message", () => {
|
|
20
|
-
const reason = 'Convergence blocked: cannot "align.revised" until convergence.action_taken is recorded';
|
|
21
|
-
expect(wrapGateError(reason)).toBe("수렴 차단 상태입니다. 방향 변경, scope 축소, 또는 보류 중 하나를 선택하세요.");
|
|
22
|
-
});
|
|
23
|
-
it("wraps Compile retry limit → Korean message", () => {
|
|
24
|
-
const reason = "Compile retry limit exceeded (3 gap_found cycles). Consider scope.deferred or redirect.to_align.";
|
|
25
|
-
expect(wrapGateError(reason)).toBe("compile 재시도 한도(3회)를 초과했습니다. scope를 보류하거나 방향을 재검토하세요.");
|
|
26
|
-
});
|
|
27
|
-
it("passes through Target lock messages (already Korean)", () => {
|
|
28
|
-
const reason = "Target lock 불가: 미결정 2건. 모든 constraint 결정이 완료되어야 합니다.";
|
|
29
|
-
expect(wrapGateError(reason)).toBe(reason);
|
|
30
|
-
});
|
|
31
|
-
it("passes through unknown error messages unchanged and warns developer", () => {
|
|
32
|
-
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
33
|
-
const reason = "Some unknown error occurred";
|
|
34
|
-
expect(wrapGateError(reason)).toBe(reason);
|
|
35
|
-
expect(warnSpy).toHaveBeenCalledTimes(1);
|
|
36
|
-
expect(warnSpy.mock.calls[0]?.[0]).toContain("no matching entry");
|
|
37
|
-
expect(warnSpy.mock.calls[0]?.[0]).toContain(reason);
|
|
38
|
-
warnSpy.mockRestore();
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
describe("wrapGateError — 신규 coverage (기존 migrate 된 분기)", () => {
|
|
42
|
-
it("wraps cannot be invalidated → Korean message", () => {
|
|
43
|
-
const reason = "CST-007 is required and cannot be invalidated by system alone";
|
|
44
|
-
expect(wrapGateError(reason)).toBe("필수 제약 사항은 시스템이 단독으로 무효화할 수 없습니다. 주체자의 확인이 필요합니다.");
|
|
45
|
-
});
|
|
46
|
-
it("wraps Compile 실패: → Korean message (Korean pattern)", () => {
|
|
47
|
-
const reason = "Compile 실패: state mismatch at step 2";
|
|
48
|
-
expect(wrapGateError(reason)).toBe("구현 명세 생성에 실패했습니다. 에이전트가 구현 계획을 수정한 뒤 재시도합니다.");
|
|
49
|
-
});
|
|
50
|
-
it("wraps Compile Defense failed → Korean message (OR branch of same code)", () => {
|
|
51
|
-
const reason = "Compile Defense failed: shortcut not covered";
|
|
52
|
-
expect(wrapGateError(reason)).toBe("구현 명세 생성에 실패했습니다. 에이전트가 구현 계획을 수정한 뒤 재시도합니다.");
|
|
53
|
-
});
|
|
54
|
-
it("wraps 'must be X state' → Korean message (AND match via includes_all)", () => {
|
|
55
|
-
const reason = "scope must be in align_locked state before draft.surface.generated";
|
|
56
|
-
expect(wrapGateError(reason)).toBe("현재 단계에서 이 작업을 수행할 수 없습니다.");
|
|
57
|
-
});
|
|
58
|
-
it("wraps compile_ready is false → Korean message", () => {
|
|
59
|
-
const reason = "compile_ready is false: constraint decisions pending";
|
|
60
|
-
expect(wrapGateError(reason)).toBe("아직 구현 명세를 생성할 수 없습니다. 제약 사항 결정이 완료되지 않았거나 소스가 변경되었습니다.");
|
|
61
|
-
});
|
|
62
|
-
it("wraps validation_plan_hash mismatch → Korean message", () => {
|
|
63
|
-
const reason = "validation_plan_hash mismatch — recompute required";
|
|
64
|
-
expect(wrapGateError(reason)).toBe("검증 계획이 변경되었습니다. compile을 다시 실행해야 합니다.");
|
|
65
|
-
});
|
|
66
|
-
it("wraps no matching injectValidation → Korean message", () => {
|
|
67
|
-
const reason = "plan has no matching injectValidation for CST-003";
|
|
68
|
-
expect(wrapGateError(reason)).toBe("구현 계획에 누락된 검증 항목이 있습니다. 에이전트가 수정한 뒤 재시도합니다.");
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
describe("lookupDiagnosticCode — code 기반 routing", () => {
|
|
72
|
-
it("Transition denied → DIAG-STATE-TRANSITION-01 code + category", () => {
|
|
73
|
-
const hit = lookupDiagnosticCode('Transition denied: "draft" does not allow "x"');
|
|
74
|
-
expect(hit).not.toBeNull();
|
|
75
|
-
expect(hit.code).toBe("DIAG-STATE-TRANSITION-01");
|
|
76
|
-
expect(hit.category).toBe("state-transition");
|
|
77
|
-
expect(hit.passthrough).toBe(false);
|
|
78
|
-
});
|
|
79
|
-
it("Target lock → passthrough=true + 원문 message", () => {
|
|
80
|
-
const reason = "Target lock 불가: 예시";
|
|
81
|
-
const hit = lookupDiagnosticCode(reason);
|
|
82
|
-
expect(hit).not.toBeNull();
|
|
83
|
-
expect(hit.code).toBe("DIAG-TARGET-LOCK-01");
|
|
84
|
-
expect(hit.passthrough).toBe(true);
|
|
85
|
-
expect(hit.message).toBe(reason);
|
|
86
|
-
});
|
|
87
|
-
it("미매칭 reason → null (+ console.warn 발행)", () => {
|
|
88
|
-
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
89
|
-
expect(lookupDiagnosticCode("totally unknown error")).toBeNull();
|
|
90
|
-
expect(warnSpy).toHaveBeenCalledTimes(1);
|
|
91
|
-
warnSpy.mockRestore();
|
|
92
|
-
});
|
|
93
|
-
it("우선순위: 가장 먼저 매칭되는 entry 가 이긴다 (registry 순서)", () => {
|
|
94
|
-
// "Transition denied" 가 먼저, "must be ... state" 가 나중이므로
|
|
95
|
-
// 둘 다 매칭될 수 있는 reason 에 대해 앞엣 것이 이겨야 한다.
|
|
96
|
-
const reason = 'Transition denied: scope must be in grounded state';
|
|
97
|
-
const hit = lookupDiagnosticCode(reason);
|
|
98
|
-
expect(hit.code).toBe("DIAG-STATE-TRANSITION-01");
|
|
99
|
-
});
|
|
100
|
-
});
|
|
101
|
-
describe("listDiagnosticCodes — registry 내용 노출", () => {
|
|
102
|
-
it("모든 등록된 code 를 반환", () => {
|
|
103
|
-
const codes = listDiagnosticCodes();
|
|
104
|
-
expect(codes.length).toBeGreaterThanOrEqual(12);
|
|
105
|
-
const codeIds = codes.map((c) => c.code);
|
|
106
|
-
expect(codeIds).toContain("DIAG-STATE-TRANSITION-01");
|
|
107
|
-
expect(codeIds).toContain("DIAG-TARGET-LOCK-01");
|
|
108
|
-
expect(codeIds).toContain("DIAG-VALIDATION-MISSING-01");
|
|
109
|
-
});
|
|
110
|
-
it("각 entry 는 code·matchers·category 필드를 가진다", () => {
|
|
111
|
-
const codes = listDiagnosticCodes();
|
|
112
|
-
for (const c of codes) {
|
|
113
|
-
expect(typeof c.code).toBe("string");
|
|
114
|
-
expect(Array.isArray(c.matchers)).toBe(true);
|
|
115
|
-
expect(c.matchers.length).toBeGreaterThan(0);
|
|
116
|
-
expect(typeof c.category).toBe("string");
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
});
|
|
120
|
-
describe("validateRegistry — schema check (fail-fast on malformed registry)", () => {
|
|
121
|
-
it("throws on duplicate code", () => {
|
|
122
|
-
expect(() => validateRegistry({
|
|
123
|
-
version: "test",
|
|
124
|
-
diagnostic_codes: [
|
|
125
|
-
{ code: "DUP", matchers: [{ includes: "x" }], category: "test" },
|
|
126
|
-
{ code: "DUP", matchers: [{ includes: "y" }], category: "test" },
|
|
127
|
-
],
|
|
128
|
-
})).toThrow(/duplicate code.*DUP/);
|
|
129
|
-
});
|
|
130
|
-
it("throws when entry has no matchers", () => {
|
|
131
|
-
expect(() => validateRegistry({
|
|
132
|
-
version: "test",
|
|
133
|
-
diagnostic_codes: [
|
|
134
|
-
{ code: "C1", matchers: [], category: "test" },
|
|
135
|
-
],
|
|
136
|
-
})).toThrow(/no matchers/);
|
|
137
|
-
});
|
|
138
|
-
it("throws on matcher without includes / includes_all", () => {
|
|
139
|
-
expect(() => validateRegistry({
|
|
140
|
-
version: "test",
|
|
141
|
-
diagnostic_codes: [
|
|
142
|
-
{ code: "C1", matchers: [{}], category: "test" },
|
|
143
|
-
],
|
|
144
|
-
})).toThrow(/includes.*includes_all/);
|
|
145
|
-
});
|
|
146
|
-
it("throws on matcher with empty includes_all array", () => {
|
|
147
|
-
expect(() => validateRegistry({
|
|
148
|
-
version: "test",
|
|
149
|
-
diagnostic_codes: [
|
|
150
|
-
{ code: "C1", matchers: [{ includes_all: [] }], category: "test" },
|
|
151
|
-
],
|
|
152
|
-
})).toThrow(/includes.*includes_all/);
|
|
153
|
-
});
|
|
154
|
-
it("passes a well-formed registry without throwing", () => {
|
|
155
|
-
expect(() => validateRegistry({
|
|
156
|
-
version: "test",
|
|
157
|
-
diagnostic_codes: [
|
|
158
|
-
{ code: "C1", matchers: [{ includes: "x" }], category: "test" },
|
|
159
|
-
{ code: "C2", matchers: [{ includes_all: ["a", "b"] }], category: "test" },
|
|
160
|
-
],
|
|
161
|
-
})).not.toThrow();
|
|
162
|
-
});
|
|
163
|
-
it("production registry (.onto/authority/diagnostic-codes.yaml) passes validation", () => {
|
|
164
|
-
// loadRegistry 내부에서 validateRegistry 호출 — listDiagnosticCodes 로 간접 트리거
|
|
165
|
-
expect(() => listDiagnosticCodes()).not.toThrow();
|
|
166
|
-
});
|
|
167
|
-
});
|