onto-mcp 0.4.11 → 0.4.13

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.
Files changed (139) hide show
  1. package/.onto/authority/core-lexicon.yaml +1 -1
  2. package/.onto/authority/supported-models.yaml +153 -0
  3. package/.onto/domains/accounting-kr/competency_qs.md +153 -153
  4. package/.onto/processes/reconstruct/obligation-coverage-ledger.yaml +842 -0
  5. package/.onto/processes/reconstruct/obligation-coverage-recorded.yaml +225 -0
  6. package/.onto/processes/reconstruct/ontology-seeding-and-maturation-design.md +93 -54
  7. package/.onto/processes/reconstruct/reconstruct-contract-registry.yaml +202 -49
  8. package/.onto/processes/reconstruct/reconstruct-execution-ux-contract.md +72 -1
  9. package/.onto/processes/reconstruct/source-profiles/spreadsheet.md +35 -0
  10. package/.onto/processes/review/nesting-batch-worker-contract.md +1 -1
  11. package/.onto/processes/review/productized-live-path.md +9 -5
  12. package/.onto/processes/review/prompt-execution-runner-contract.md +32 -8
  13. package/.onto/processes/review/review-target-profile-contract.md +47 -4
  14. package/.onto/processes/shared/pipeline-execution-ledger-contract.md +11 -0
  15. package/.onto/processes/shared/target-material-kind-contract.md +1 -1
  16. package/README.md +64 -1
  17. package/dist/cli.js +11 -1
  18. package/dist/core-api/reconstruct-api.js +679 -18
  19. package/dist/core-api/review-api.js +70 -5
  20. package/dist/core-api/review-progress.js +7 -0
  21. package/dist/core-api/runtime-observation.js +7 -0
  22. package/dist/core-runtime/artifact-io.js +131 -0
  23. package/dist/core-runtime/cli/claude-code-review-unit-executor.js +21 -9
  24. package/dist/core-runtime/cli/claude-nesting-batch-worker.js +4 -2
  25. package/dist/core-runtime/cli/materialize-review-prompt-packets.js +68 -14
  26. package/dist/core-runtime/cli/prepare-review-session.js +34 -1
  27. package/dist/core-runtime/cli/render-review-final-output.js +2 -1
  28. package/dist/core-runtime/cli/run-review-prompt-execution.js +758 -48
  29. package/dist/core-runtime/cli/run-seats.js +18 -0
  30. package/dist/core-runtime/cli/runtime-submit-context.js +10 -2
  31. package/dist/core-runtime/cli/unit-resubmit.js +269 -0
  32. package/dist/core-runtime/cli/worker-structured-output.js +80 -2
  33. package/dist/core-runtime/discovery/host-detection.js +71 -22
  34. package/dist/core-runtime/discovery/review-cert-assemble.js +208 -0
  35. package/dist/core-runtime/discovery/review-cert-record.js +442 -0
  36. package/dist/core-runtime/discovery/review-execution-units.js +22 -0
  37. package/dist/core-runtime/discovery/seat-inventory.js +167 -0
  38. package/dist/core-runtime/discovery/settings-chain.js +311 -52
  39. package/dist/core-runtime/discovery/supported-models.js +289 -25
  40. package/dist/core-runtime/discovery/synthesize-cert-assemble.js +197 -0
  41. package/dist/core-runtime/discovery/synthesize-cert-capsule.js +399 -0
  42. package/dist/core-runtime/discovery/synthesize-cert-judge.js +340 -0
  43. package/dist/core-runtime/discovery/synthesize-cert-loop.js +234 -0
  44. package/dist/core-runtime/discovery/synthesize-cert-mutation.js +117 -0
  45. package/dist/core-runtime/discovery/synthesize-cert-packet.js +182 -0
  46. package/dist/core-runtime/discovery/synthesize-cert-record.js +831 -0
  47. package/dist/core-runtime/discovery/synthesize-cert-sampler.js +336 -0
  48. package/dist/core-runtime/effort-calibration-ingest.js +326 -0
  49. package/dist/core-runtime/effort-calibration-reconstruct.js +47 -0
  50. package/dist/core-runtime/effort-calibration-review.js +22 -0
  51. package/dist/core-runtime/effort-calibration-sweep.js +110 -0
  52. package/dist/core-runtime/effort-frontier.js +134 -0
  53. package/dist/core-runtime/llm/claude-bin.js +77 -0
  54. package/dist/core-runtime/llm/dispatch-breaker.js +412 -0
  55. package/dist/core-runtime/llm/dispatch-fallback-adapter-capabilities.js +33 -0
  56. package/dist/core-runtime/llm/llm-caller.js +316 -35
  57. package/dist/core-runtime/llm/mock-llm-realization.js +35 -4
  58. package/dist/core-runtime/llm/model-switcher.js +1 -1
  59. package/dist/core-runtime/llm/openai-responses-incomplete-error.js +46 -0
  60. package/dist/core-runtime/llm/sealed-dispatch-capability.js +359 -0
  61. package/dist/core-runtime/llm/structured-dispatch-error.js +15 -0
  62. package/dist/core-runtime/onboard/claude-profile-scan.js +65 -0
  63. package/dist/core-runtime/onboard/cli-host.js +5 -2
  64. package/dist/core-runtime/onboard/configure-provider.js +33 -1
  65. package/dist/core-runtime/onboard/host-target.js +28 -3
  66. package/dist/core-runtime/onboard/register.js +54 -12
  67. package/dist/core-runtime/pipeline-execution-ledger.js +10 -0
  68. package/dist/core-runtime/reconstruct/artifact-types.js +37 -0
  69. package/dist/core-runtime/reconstruct/benchmark-evidence.js +16 -0
  70. package/dist/core-runtime/reconstruct/claim-projection-validation.js +19 -5
  71. package/dist/core-runtime/reconstruct/competency-projection-contract.js +63 -0
  72. package/dist/core-runtime/reconstruct/comprehension-artifact.js +321 -0
  73. package/dist/core-runtime/reconstruct/comprehension-reduce.js +367 -0
  74. package/dist/core-runtime/reconstruct/comprehension-semantic-map.js +771 -0
  75. package/dist/core-runtime/reconstruct/contract-registry.js +20 -0
  76. package/dist/core-runtime/reconstruct/directive-validation.js +4 -3
  77. package/dist/core-runtime/reconstruct/dispatch-fallback-artifacts.js +640 -0
  78. package/dist/core-runtime/reconstruct/execution-telemetry.js +84 -9
  79. package/dist/core-runtime/reconstruct/final-output-sections.js +89 -0
  80. package/dist/core-runtime/reconstruct/governing-snapshot.js +36 -1
  81. package/dist/core-runtime/reconstruct/leaf-reader.js +305 -0
  82. package/dist/core-runtime/reconstruct/llm-dispatch-failure.js +270 -0
  83. package/dist/core-runtime/reconstruct/llm-touch-fingerprint.js +94 -0
  84. package/dist/core-runtime/reconstruct/material-admission-validation.js +20 -5
  85. package/dist/core-runtime/reconstruct/material-profile-validation.js +24 -6
  86. package/dist/core-runtime/reconstruct/materialize-preparation.js +380 -23
  87. package/dist/core-runtime/reconstruct/maturation-validation.js +1522 -67
  88. package/dist/core-runtime/reconstruct/mock-llm-realization.js +120 -1
  89. package/dist/core-runtime/reconstruct/obligation-assertion.js +18 -0
  90. package/dist/core-runtime/reconstruct/ontology-seed-validation.js +39 -7
  91. package/dist/core-runtime/reconstruct/output-budget.js +6 -0
  92. package/dist/core-runtime/reconstruct/pipeline-execution-ledger.js +112 -5
  93. package/dist/core-runtime/reconstruct/post-seed-validation.js +122 -11
  94. package/dist/core-runtime/reconstruct/proof-authority-validation.js +2 -6
  95. package/dist/core-runtime/reconstruct/purpose-authority-validation.js +119 -7
  96. package/dist/core-runtime/reconstruct/record.js +49 -3
  97. package/dist/core-runtime/reconstruct/registry-verification-validation.js +41 -5
  98. package/dist/core-runtime/reconstruct/run-control-validation.js +1019 -37
  99. package/dist/core-runtime/reconstruct/run.js +5409 -517
  100. package/dist/core-runtime/reconstruct/seed-authoring-readiness-validation.js +56 -8
  101. package/dist/core-runtime/reconstruct/semantic-quality-gate.js +112 -7
  102. package/dist/core-runtime/reconstruct/source-observation-delta-validation.js +53 -5
  103. package/dist/core-runtime/reconstruct/source-observations.js +166 -0
  104. package/dist/core-runtime/reconstruct/source-safety-validation.js +77 -188
  105. package/dist/core-runtime/reconstruct/source-scout-pack-validation.js +50 -6
  106. package/dist/core-runtime/reconstruct/terminal-validation.js +145 -13
  107. package/dist/core-runtime/review/continuation-plan.js +12 -5
  108. package/dist/core-runtime/review/issue-artifact-runtime.js +4 -1
  109. package/dist/core-runtime/review/materializers.js +100 -11
  110. package/dist/core-runtime/review/nesting-batch.js +6 -2
  111. package/dist/core-runtime/review/obligation-shardability.js +138 -0
  112. package/dist/core-runtime/review/pipeline-execution-ledger.js +42 -2
  113. package/dist/core-runtime/review/review-artifact-utils.js +219 -7
  114. package/dist/core-runtime/review/review-execution-steps.js +32 -8
  115. package/dist/core-runtime/review/review-progress-contract.js +8 -0
  116. package/dist/core-runtime/review/review-prompt-budget.js +97 -0
  117. package/dist/core-runtime/review/semantic-quality-gate.js +33 -7
  118. package/dist/core-runtime/review/spreadsheet-review-disposition.js +94 -0
  119. package/dist/core-runtime/route-identity.js +182 -0
  120. package/dist/core-runtime/spreadsheet-header-escalation.js +204 -0
  121. package/dist/core-runtime/spreadsheet-structure-observer.js +2689 -0
  122. package/dist/core-runtime/target-material-kind.js +58 -0
  123. package/dist/mcp/server.js +27 -5
  124. package/dist/mcp/tool-schemas.js +8 -0
  125. package/dist/tui/app.js +167 -0
  126. package/dist/tui/data/event-follower.js +116 -0
  127. package/dist/tui/data/node-detail.js +42 -0
  128. package/dist/tui/data/projection-poll.js +26 -0
  129. package/dist/tui/data/session-discovery.js +65 -0
  130. package/dist/tui/index.js +108 -0
  131. package/dist/tui/screens/log.js +25 -0
  132. package/dist/tui/screens/node-detail.js +17 -0
  133. package/dist/tui/screens/session-selector.js +26 -0
  134. package/dist/tui/screens/workflow-tree.js +90 -0
  135. package/dist/tui/view-model/reconstruct-adapter.js +162 -0
  136. package/dist/tui/view-model/review-adapter.js +270 -0
  137. package/dist/tui/view-model/tree-view-model.js +19 -0
  138. package/package.json +20 -3
  139. package/settings.example.json +77 -16
@@ -0,0 +1,270 @@
1
+ import { REVIEW_PROGRESS_STEPS, } from "../../core-api/review-progress.js";
2
+ /** Phase that collects units the projection has not bound to a progress step. */
3
+ const UNCATEGORIZED_PHASE_ID = "unassigned";
4
+ const UNCATEGORIZED_PHASE_LABEL = "unassigned units";
5
+ /** Canonical progress-step ids — used to reject non-step `completed_steps` keys. */
6
+ const VALID_PROGRESS_STEP_IDS = new Set(REVIEW_PROGRESS_STEPS.map((step) => step.id));
7
+ function isRecord(value) {
8
+ return typeof value === "object" && value !== null && !Array.isArray(value);
9
+ }
10
+ /** Narrow the `unknown` presentation payload to the read-only fields we use. */
11
+ function readProgressPresentationInput(status) {
12
+ const input = status.llmPresentation?.progress?.input;
13
+ return isRecord(input) ? input : {};
14
+ }
15
+ /**
16
+ * Map a runtime unit status to the shared {@link NodeState}. `retrying` and
17
+ * `running_stale` are both still in-flight (the HUD surfaces the retry count /
18
+ * stale signal age separately), so they collapse to `running`.
19
+ */
20
+ function unitStatusToNodeState(unitStatus) {
21
+ switch (unitStatus) {
22
+ case "pending":
23
+ return "pending";
24
+ case "running":
25
+ case "retrying":
26
+ case "running_stale":
27
+ return "running";
28
+ case "completed":
29
+ return "completed";
30
+ case "failed":
31
+ return "failed";
32
+ }
33
+ }
34
+ function unitToNode(unit) {
35
+ return {
36
+ id: unit.unitId,
37
+ label: unit.publicAlias,
38
+ status: unitStatusToNodeState(unit.status),
39
+ kind: unit.unitKind,
40
+ signalAgeSec: unit.secondsSinceLatestSignal,
41
+ attempts: unit.attemptCount,
42
+ failureMessage: unit.failureMessage,
43
+ outputPath: drillDownPath(unit),
44
+ };
45
+ }
46
+ /**
47
+ * Drill-down target for a unit. A completed unit's authored output is the
48
+ * authoritative artifact. For an active/failed unit that planned output may not
49
+ * exist yet, so prefer the live running-log (the projection only sets
50
+ * `runningLogRef` when that file is present) and fall back to the planned output.
51
+ */
52
+ function drillDownPath(unit) {
53
+ if (unit.status === "completed") {
54
+ return unit.outputPath ?? unit.runningLogRef ?? null;
55
+ }
56
+ return unit.runningLogRef ?? unit.outputPath ?? null;
57
+ }
58
+ /**
59
+ * State of the current (in-flight) progress step, given the workflow's own
60
+ * status: a halted or failed run is terminal, and its current step is the
61
+ * halt/failure locus — surface that rather than a misleading "running". A live
62
+ * run's current step is running.
63
+ */
64
+ function currentStepState(workflowStatus) {
65
+ if (workflowStatus === "failed")
66
+ return "failed";
67
+ if (workflowStatus === "halted")
68
+ return "halted";
69
+ return "running";
70
+ }
71
+ /**
72
+ * Phase state from its nodes (+ the projection's completed step ids). A failed
73
+ * node fails the phase; any in-flight node makes it running; a step listed in
74
+ * `completed_steps` (or all nodes completed) completes it; a halted node halts
75
+ * it. A step at the current step whose units exist but have not signalled yet
76
+ * takes the workflow's current-step state — matching {@link emptyStepState}'s
77
+ * current-step branch so the same current step reports the same state whether or
78
+ * not it carries units. Otherwise it is pending.
79
+ */
80
+ function derivePhaseState(nodes, stepId, completedStepIds, stepNumber, currentStep, workflowStatus) {
81
+ if (nodes.some((node) => node.status === "failed"))
82
+ return "failed";
83
+ if (nodes.some((node) => node.status === "running"))
84
+ return "running";
85
+ if (nodes.some((node) => node.status === "halted"))
86
+ return "halted";
87
+ if (stepId !== null && completedStepIds.has(stepId))
88
+ return "completed";
89
+ if (nodes.length > 0 && nodes.every((node) => node.status === "completed")) {
90
+ return "completed";
91
+ }
92
+ if (nodes.length > 0 && nodes.every((node) => node.status === "skipped")) {
93
+ return "skipped";
94
+ }
95
+ if (stepNumber != null && currentStep != null && stepNumber === currentStep) {
96
+ return currentStepState(workflowStatus);
97
+ }
98
+ return "pending";
99
+ }
100
+ /**
101
+ * State for a progress step that has no bound units: completed when the workflow
102
+ * itself completed, when the step is in `completed_steps`, or when it sits before
103
+ * the current step; the workflow's current-step state at the current step (so a
104
+ * halted/failed run points at its halt/failure locus, not a phantom "running");
105
+ * otherwise pending. This keeps idle/completed steps visible so the HUD shows the
106
+ * whole pipeline (not only the steps that happened to carry units).
107
+ */
108
+ function emptyStepState(stepId, stepNumber, completedStepIds, currentStep, workflowStatus) {
109
+ if (workflowStatus === "completed")
110
+ return "completed";
111
+ if (completedStepIds.has(stepId))
112
+ return "completed";
113
+ if (currentStep != null) {
114
+ if (stepNumber < currentStep)
115
+ return "completed";
116
+ if (stepNumber === currentStep)
117
+ return currentStepState(workflowStatus);
118
+ }
119
+ return "pending";
120
+ }
121
+ /**
122
+ * Emit a phase for EVERY progress step (in canonical order), attaching any units
123
+ * bound to it, so completed/idle steps stay visible. Units the projection left
124
+ * unbound (`progressStepId === null`) collect into a trailing uncategorized phase.
125
+ */
126
+ function derivePhases(status, completedStepIds, currentStep, workflowStatus) {
127
+ const byStep = new Map();
128
+ for (const unit of status.unitProgress ?? []) {
129
+ const key = unit.progressStepId;
130
+ const bucket = byStep.get(key);
131
+ if (bucket)
132
+ bucket.push(unitToNode(unit));
133
+ else
134
+ byStep.set(key, [unitToNode(unit)]);
135
+ }
136
+ const phases = REVIEW_PROGRESS_STEPS.map((spec) => {
137
+ const nodes = byStep.get(spec.id) ?? [];
138
+ const state = nodes.length > 0
139
+ ? derivePhaseState(nodes, spec.id, completedStepIds, spec.step, currentStep, workflowStatus)
140
+ : emptyStepState(spec.id, spec.step, completedStepIds, currentStep, workflowStatus);
141
+ return { id: spec.id, label: spec.label, state, nodes };
142
+ });
143
+ const unassigned = byStep.get(null);
144
+ if (unassigned && unassigned.length > 0) {
145
+ phases.push({
146
+ id: UNCATEGORIZED_PHASE_ID,
147
+ label: UNCATEGORIZED_PHASE_LABEL,
148
+ state: derivePhaseState(unassigned, null, completedStepIds, null, currentStep, workflowStatus),
149
+ nodes: unassigned,
150
+ });
151
+ }
152
+ return phases;
153
+ }
154
+ /**
155
+ * Map the review status union to the shared {@link WorkflowStatus}. A degraded
156
+ * completion is still a completion; `halted_partial` is the operator-facing halt;
157
+ * `prepared` / `unknown` are pre-run states the HUD shows as still-running (the
158
+ * narrator/liveness convey the finer state).
159
+ */
160
+ function deriveWorkflowStatus(status) {
161
+ switch (status) {
162
+ case "completed":
163
+ case "completed_with_degradation":
164
+ return "completed";
165
+ case "halted_partial":
166
+ return "halted";
167
+ case "failed":
168
+ return "failed";
169
+ case "running":
170
+ case "prepared":
171
+ case "unknown":
172
+ return "running";
173
+ }
174
+ }
175
+ /**
176
+ * Run control from the review projection. `cancellationAvailable` /
177
+ * `continuationAvailable` are the authoritative flags; review has no per-round
178
+ * advance, so `advanceable` is left undefined.
179
+ */
180
+ function deriveRunControl(runControl) {
181
+ return {
182
+ cancellable: runControl?.cancellationAvailable ?? false,
183
+ continuable: runControl?.continuationAvailable ?? false,
184
+ };
185
+ }
186
+ const EMPTY_SEVERITY_COUNTS = {
187
+ blocker: 0,
188
+ high: 0,
189
+ medium: 0,
190
+ low: 0,
191
+ info: 0,
192
+ };
193
+ /**
194
+ * Footer findings: severity counts + material issue titles. Works for both the
195
+ * full and compact result-classification projections — material titles come from
196
+ * `material_issues[]` (full) or `material_issue_signals[]` (compact).
197
+ */
198
+ function deriveFindings(summary) {
199
+ if (!summary) {
200
+ return { ...EMPTY_SEVERITY_COUNTS, material: [] };
201
+ }
202
+ const counts = {
203
+ blocker: summary.severity_counts.blocker,
204
+ high: summary.severity_counts.high,
205
+ medium: summary.severity_counts.medium,
206
+ low: summary.severity_counts.low,
207
+ info: summary.severity_counts.info,
208
+ };
209
+ return { ...counts, material: materialIssueTitles(summary) };
210
+ }
211
+ function isCompactSummary(summary) {
212
+ return "material_issue_signals" in summary;
213
+ }
214
+ function materialIssueTitles(summary) {
215
+ if (isCompactSummary(summary)) {
216
+ return summary.material_issue_signals.map((signal) => titleLine(signal.issue_id, signal.signal));
217
+ }
218
+ return summary.material_issues.map((issue) => titleLine(issue.issue_id, issue.problem_definition ?? issue.issue_statement ?? issue.impact));
219
+ }
220
+ function titleLine(issueId, text) {
221
+ const trimmed = (text ?? "").trim();
222
+ return trimmed.length > 0 ? `${issueId}: ${trimmed}` : issueId;
223
+ }
224
+ /**
225
+ * Narrator line: prefer the latest progress signal summary, fall back to the
226
+ * liveness summary, then to the bare status. Mirrors the design's
227
+ * `latest_update.summary / liveness.summary` rule.
228
+ */
229
+ function deriveNarrator(input, workflowStatus) {
230
+ const latest = input.latest_update?.summary?.trim();
231
+ if (latest)
232
+ return latest;
233
+ const liveness = input.liveness?.summary?.trim();
234
+ if (liveness)
235
+ return liveness;
236
+ return `review ${workflowStatus}`;
237
+ }
238
+ /**
239
+ * Pure projection: {@link ReviewStatus} → {@link TreeViewModel}.
240
+ *
241
+ * `sessionRoot` is threaded explicitly (the caller already knows it) so the view
242
+ * model header is independent of how the status was fetched.
243
+ */
244
+ export function reviewStatusToTreeViewModel(status, sessionRoot) {
245
+ const input = readProgressPresentationInput(status);
246
+ const workflowStatus = deriveWorkflowStatus(status.status);
247
+ // Consume only real progress-step ids: a prepared session fills
248
+ // `completed_steps` with preparation-artifact keys (interpretation/binding/
249
+ // execution_plan), a different vocabulary, which must not be matched against
250
+ // (or mistaken for) progress-step ids during phase rollup.
251
+ const completedStepIds = new Set((input.progress?.completed_steps ?? []).filter((id) => VALID_PROGRESS_STEP_IDS.has(id)));
252
+ const phases = derivePhases(status, completedStepIds, input.progress?.current_step ?? null, workflowStatus);
253
+ return {
254
+ pipeline: "review",
255
+ sessionId: status.sessionId,
256
+ sessionRoot,
257
+ status: workflowStatus,
258
+ narrator: deriveNarrator(input, workflowStatus),
259
+ liveness: {
260
+ state: input.liveness?.state ?? "unknown",
261
+ secondsSinceSignal: input.liveness?.seconds_since_last_observed_artifact ?? null,
262
+ pollMs: input.liveness?.poll_after_seconds == null
263
+ ? null
264
+ : input.liveness.poll_after_seconds * 1000,
265
+ },
266
+ phases,
267
+ summary: { findings: deriveFindings(input.result_classification_summary) },
268
+ runControl: deriveRunControl(status.runControl),
269
+ };
270
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Pipeline-agnostic view model rendered by the `onto watch` HUD.
3
+ *
4
+ * review and reconstruct expose progress in different shapes (review = per-UNIT
5
+ * live signal; reconstruct = per-STAGE state + owner + domain counts). The
6
+ * review/reconstruct adapters normalize both into this single shape, so the Ink
7
+ * HUD never branches on pipeline. This is a pure derived VIEW — it carries no
8
+ * authority and is never persisted.
9
+ */
10
+ /**
11
+ * True when the workflow has reached a terminal state (stop polling). `halted`
12
+ * is terminal for the watch loop too: it sits paused awaiting an explicit
13
+ * operator continuation that may be a long way off, so the live loop stops
14
+ * rather than re-reading an unchanging projection every interval. The operator
15
+ * re-engages with [r]efresh after continuing (consistent with completed/failed).
16
+ */
17
+ export function isTerminalStatus(status) {
18
+ return status === "completed" || status === "failed" || status === "halted";
19
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "onto-mcp",
3
- "version": "0.4.11",
3
+ "version": "0.4.13",
4
4
  "description": "MCP-native ontology review runtime with context-isolated lenses and controlled deliberation",
5
5
  "homepage": "https://github.com/kangminlee-maker/onto-mcp#readme",
6
6
  "bugs": {
@@ -49,22 +49,39 @@
49
49
  "check:invariant-change": "tsx scripts/check-invariant-change-marker.ts",
50
50
  "check:invariant-drift": "tsx scripts/check-invariant-drift.ts",
51
51
  "check:supported-models": "tsx scripts/check-supported-models.ts",
52
+ "check:prompt-projection-parity": "tsx scripts/check-prompt-projection-parity.ts",
53
+ "check:final-output-sections-parity": "tsx scripts/check-final-output-sections-parity.ts",
54
+ "check:obligation-coverage": "tsx scripts/check-obligation-coverage.ts",
55
+ "check:dispatch-fallback-package-parity": "tsx scripts/check-dispatch-fallback-package-parity.ts",
56
+ "check:graceful-signal-rethrow": "tsx scripts/check-graceful-signal-rethrow.ts",
52
57
  "test": "npm run test:e2e",
58
+ "test:vitest": "vitest run",
53
59
  "test:review:live": "npm run build:ts-core && tsx scripts/review-mcp-live-e2e.ts",
54
60
  "test:review:live:cli": "npm run build:ts-core && tsx scripts/review-live-e2e.ts",
61
+ "test:reconstruct:dispatch-fallback:live": "node --env-file=.env --import tsx scripts/reconstruct-dispatch-fallback-live-e2e.mts",
62
+ "test:reconstruct:output-headroom:live": "node --env-file=.env --import tsx scripts/reconstruct-output-headroom-live-e2e.mts",
55
63
  "benchmark:review:pipeline": "tsx scripts/review-pipeline-benchmark.ts",
56
64
  "benchmark:reconstruct:pipeline": "tsx scripts/reconstruct-pipeline-benchmark.ts",
65
+ "calibration:effort:report": "tsx scripts/effort-calibration-report.ts",
57
66
  "migrate:reconstruct-artifact-fields": "tsx scripts/migrate-reconstruct-artifact-fields.ts",
58
67
  "test:e2e": "npm run build:ts-core && tsx scripts/review-mcp-live-e2e.ts"
59
68
  },
60
69
  "dependencies": {
61
- "@anthropic-ai/sdk": "^0.99.0",
62
- "openai": "^6.33.0",
70
+ "@anthropic-ai/sdk": "0.99.0",
71
+ "fflate": "^0.8.3",
72
+ "ink": "^5.2.1",
73
+ "openai": "6.39.0",
74
+ "proper-lockfile": "^4.1.2",
75
+ "react": "^18.3.1",
76
+ "saxes": "^6.0.0",
63
77
  "yaml": "^2.8.2",
64
78
  "zod": "^4.3.6"
65
79
  },
66
80
  "devDependencies": {
67
81
  "@types/node": "^25.3.5",
82
+ "@types/proper-lockfile": "^4.1.4",
83
+ "@types/react": "^18.3.31",
84
+ "ink-testing-library": "^4.0.0",
68
85
  "tsx": "^4.21.0",
69
86
  "typescript": "^5.9.3",
70
87
  "vitest": "^4.0.18"
@@ -47,6 +47,19 @@
47
47
 
48
48
  # actors는 review 안에서 역할별로 실제 모델 설정을 소유합니다.
49
49
  # 즉 teamlead, lens, synthesize를 서로 독립적으로 바꿀 수 있습니다.
50
+ #
51
+ # ── provider 전환 ───────────────────────────────────────────────
52
+ # 손으로 고치는 대신 `onto configure-provider`가 아래 actor 블록을 검증 후
53
+ # 기록합니다(units 등 다른 설정은 보존). 예:
54
+ # onto configure-provider --provider openai --model gpt-5.5 --auth oauth --effort medium --service-tier fast
55
+ # onto configure-provider --provider anthropic --model claude-opus-4-8 --auth oauth --effort high
56
+ # anthropic(Claude Code)로 손수 바꿀 때: 각 llm에서 provider를 "anthropic",
57
+ # model을 "claude-opus-4-8"로 바꾸고 "service_tier" 줄을 삭제합니다
58
+ # (service_tier는 openai+oauth 전용 — anthropic에 주면 거부됨).
59
+ # configure-provider는 actor만 기록하므로, 아래 units[].llm.model도 같은
60
+ # model로 바꾸거나 그 "model" 키를 지워 actor 값을 상속하게 하세요.
61
+ # 지원 model id: .onto/authority/supported-models.yaml
62
+ # ────────────────────────────────────────────────────────────────
50
63
  "actors": {
51
64
  # teamlead는 review 전체 진행과 숙의 조율을 담당합니다.
52
65
  "teamlead": {
@@ -60,7 +73,7 @@
60
73
  # provider는 사용할 모델 제공자입니다.
61
74
  "provider": "openai",
62
75
  # model은 사용할 모델 이름입니다.
63
- "model": "gpt-5.5",
76
+ "model": "gpt-5.6-sol",
64
77
  # effort는 추론 강도입니다. 보통 medium이면 충분합니다.
65
78
  "effort": "medium",
66
79
  # service_tier는 Codex OAuth 경로에서 사용할 응답 속도 계층입니다.
@@ -80,7 +93,7 @@
80
93
  # provider는 사용할 모델 제공자입니다.
81
94
  "provider": "openai",
82
95
  # model은 사용할 모델 이름입니다.
83
- "model": "gpt-5.5",
96
+ "model": "gpt-5.6-sol",
84
97
  # effort는 추론 강도입니다. 보통 medium이면 충분합니다.
85
98
  "effort": "medium",
86
99
  # service_tier는 Codex OAuth 경로에서 사용할 응답 속도 계층입니다.
@@ -100,7 +113,7 @@
100
113
  # provider는 사용할 모델 제공자입니다.
101
114
  "provider": "openai",
102
115
  # model은 사용할 모델 이름입니다.
103
- "model": "gpt-5.5",
116
+ "model": "gpt-5.6-sol",
104
117
  # effort는 추론 강도입니다. xhigh는 더 깊게 검토하지만 비용과 시간이 늘 수 있습니다.
105
118
  "effort": "xhigh",
106
119
  # service_tier는 Codex OAuth 경로에서 사용할 응답 속도 계층입니다.
@@ -120,11 +133,11 @@
120
133
  # max_tokens/tool_mode은 direct_call/inline HTTP executor에서만 강제 가능합니다.
121
134
  # 기본 Codex OAuth worker 경로는 해당 knob를 강제할 수 없으므로 설정 시 fail-loud합니다.
122
135
  "units": {
123
- # lens는 9개 관점별 독립 검토입니다. 아래 값들은 시작 기준 예시입니다.
124
- # 실제 튜닝은 benchmark:review:pipeline의 unit-sweep 결과를 보고 조정하세요.
136
+ # lens는 9개 관점별 독립 검토입니다. 아래 값들은 decision-grade unit-sweep 결과입니다.
137
+ # 기준: development-records/benchmark/review-unit-effort-all-units-low-medium-high-decision-rerun2-20260610-winner-selection-merged.json
125
138
  "lens": {
126
139
  "llm": {
127
- "model": "gpt-5.5",
140
+ "model": "gpt-5.6-sol",
128
141
  "effort": "medium"
129
142
  },
130
143
  "timeout_ms": 240000,
@@ -134,7 +147,7 @@
134
147
  },
135
148
  "finding_ledger": {
136
149
  "llm": {
137
- "model": "gpt-5.5",
150
+ "model": "gpt-5.6-sol",
138
151
  "effort": "medium"
139
152
  },
140
153
  "timeout_ms": 240000,
@@ -144,7 +157,7 @@
144
157
  },
145
158
  "finding_relation_graph": {
146
159
  "llm": {
147
- "model": "gpt-5.5",
160
+ "model": "gpt-5.6-sol",
148
161
  "effort": "medium"
149
162
  },
150
163
  "timeout_ms": 240000,
@@ -154,7 +167,7 @@
154
167
  },
155
168
  "issue_ledger": {
156
169
  "llm": {
157
- "model": "gpt-5.5",
170
+ "model": "gpt-5.6-sol",
158
171
  "effort": "medium"
159
172
  },
160
173
  "timeout_ms": 240000,
@@ -164,7 +177,7 @@
164
177
  },
165
178
  "deliberation_plan": {
166
179
  "llm": {
167
- "model": "gpt-5.5",
180
+ "model": "gpt-5.6-sol",
168
181
  "effort": "medium"
169
182
  },
170
183
  "timeout_ms": 240000,
@@ -174,7 +187,7 @@
174
187
  },
175
188
  "problem_framing": {
176
189
  "llm": {
177
- "model": "gpt-5.5",
190
+ "model": "gpt-5.6-sol",
178
191
  "effort": "medium"
179
192
  },
180
193
  "timeout_ms": 240000,
@@ -191,7 +204,7 @@
191
204
 
192
205
  "issue_stance_response": {
193
206
  "llm": {
194
- "model": "gpt-5.5",
207
+ "model": "gpt-5.6-sol",
195
208
  "effort": "medium"
196
209
  },
197
210
  "timeout_ms": 180000,
@@ -201,7 +214,7 @@
201
214
  },
202
215
  "deliberation_response": {
203
216
  "llm": {
204
- "model": "gpt-5.5",
217
+ "model": "gpt-5.6-sol",
205
218
  "effort": "medium"
206
219
  },
207
220
  "timeout_ms": 180000,
@@ -211,8 +224,8 @@
211
224
  },
212
225
  "deliberation_resolution": {
213
226
  "llm": {
214
- "model": "gpt-5.5",
215
- "effort": "medium"
227
+ "model": "gpt-5.6-sol",
228
+ "effort": "low"
216
229
  },
217
230
  "timeout_ms": 240000,
218
231
  "max_retries": 2,
@@ -221,7 +234,7 @@
221
234
  },
222
235
  "synthesis_response": {
223
236
  "llm": {
224
- "model": "gpt-5.5",
237
+ "model": "gpt-5.6-sol",
225
238
  "effort": "medium"
226
239
  },
227
240
  "timeout_ms": 180000,
@@ -231,5 +244,53 @@
231
244
  }
232
245
  }
233
246
  }
247
+ },
248
+
249
+ # reconstruct의 breaker-trip provider fallback은 기본적으로 꺼져 있습니다.
250
+ # 활성화할 때는 enabled만 바꾸지 말고 strict enabled 형식의 trigger/limit/llm
251
+ # 필드를 모두 명시해야 합니다. api_key 값 자체는 파일에 쓰지 않습니다.
252
+ # enabled 형식:
253
+ # "dispatch_fallback": {
254
+ # "enabled": true,
255
+ # "trigger": "rate_limit",
256
+ # "max_fallback_passes": 1,
257
+ # "per_dispatch_max_provider_attempts": 1,
258
+ # "systemic_failure_threshold": 1,
259
+ # "llm": {
260
+ # "provider": "anthropic", "auth": "api_key",
261
+ # "model": "<supported-model>", "effort": "medium",
262
+ # "api_key_env": "ANTHROPIC_API_KEY"
263
+ # }
264
+ # }
265
+ "reconstruct": {
266
+ "execution": {
267
+ # reconstruct actor도 역할별 독립 설정을 사용합니다.
268
+ # semantic_author를 openai + api_key direct API 경로로 명시 전환한 경우에만
269
+ # actor의 llm sibling인 llm_runtime.openai_responses_output_headroom_tokens를
270
+ # 양의 정수로 추가할 수 있습니다. 생략하면 기존 stage output ceiling을 그대로 씁니다.
271
+ "actors": {
272
+ "semantic_author": {
273
+ "llm": {
274
+ "auth": "oauth",
275
+ "provider": "openai",
276
+ "model": "gpt-5.5",
277
+ "effort": "medium",
278
+ "service_tier": "fast"
279
+ }
280
+ },
281
+ "confirmation_provider": {
282
+ "llm": {
283
+ "auth": "oauth",
284
+ "provider": "openai",
285
+ "model": "gpt-5.5",
286
+ "effort": "medium",
287
+ "service_tier": "fast"
288
+ }
289
+ }
290
+ },
291
+ "dispatch_fallback": {
292
+ "enabled": false
293
+ }
294
+ }
234
295
  }
235
296
  }