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.
- package/.onto/authority/core-lexicon.yaml +1 -1
- package/.onto/authority/supported-models.yaml +153 -0
- package/.onto/domains/accounting-kr/competency_qs.md +153 -153
- package/.onto/processes/reconstruct/obligation-coverage-ledger.yaml +842 -0
- package/.onto/processes/reconstruct/obligation-coverage-recorded.yaml +225 -0
- package/.onto/processes/reconstruct/ontology-seeding-and-maturation-design.md +93 -54
- package/.onto/processes/reconstruct/reconstruct-contract-registry.yaml +202 -49
- package/.onto/processes/reconstruct/reconstruct-execution-ux-contract.md +72 -1
- package/.onto/processes/reconstruct/source-profiles/spreadsheet.md +35 -0
- package/.onto/processes/review/nesting-batch-worker-contract.md +1 -1
- package/.onto/processes/review/productized-live-path.md +9 -5
- package/.onto/processes/review/prompt-execution-runner-contract.md +32 -8
- package/.onto/processes/review/review-target-profile-contract.md +47 -4
- package/.onto/processes/shared/pipeline-execution-ledger-contract.md +11 -0
- package/.onto/processes/shared/target-material-kind-contract.md +1 -1
- package/README.md +64 -1
- package/dist/cli.js +11 -1
- package/dist/core-api/reconstruct-api.js +679 -18
- package/dist/core-api/review-api.js +70 -5
- package/dist/core-api/review-progress.js +7 -0
- package/dist/core-api/runtime-observation.js +7 -0
- package/dist/core-runtime/artifact-io.js +131 -0
- package/dist/core-runtime/cli/claude-code-review-unit-executor.js +21 -9
- package/dist/core-runtime/cli/claude-nesting-batch-worker.js +4 -2
- package/dist/core-runtime/cli/materialize-review-prompt-packets.js +68 -14
- package/dist/core-runtime/cli/prepare-review-session.js +34 -1
- package/dist/core-runtime/cli/render-review-final-output.js +2 -1
- package/dist/core-runtime/cli/run-review-prompt-execution.js +758 -48
- package/dist/core-runtime/cli/run-seats.js +18 -0
- package/dist/core-runtime/cli/runtime-submit-context.js +10 -2
- package/dist/core-runtime/cli/unit-resubmit.js +269 -0
- package/dist/core-runtime/cli/worker-structured-output.js +80 -2
- package/dist/core-runtime/discovery/host-detection.js +71 -22
- package/dist/core-runtime/discovery/review-cert-assemble.js +208 -0
- package/dist/core-runtime/discovery/review-cert-record.js +442 -0
- package/dist/core-runtime/discovery/review-execution-units.js +22 -0
- package/dist/core-runtime/discovery/seat-inventory.js +167 -0
- package/dist/core-runtime/discovery/settings-chain.js +311 -52
- package/dist/core-runtime/discovery/supported-models.js +289 -25
- package/dist/core-runtime/discovery/synthesize-cert-assemble.js +197 -0
- package/dist/core-runtime/discovery/synthesize-cert-capsule.js +399 -0
- package/dist/core-runtime/discovery/synthesize-cert-judge.js +340 -0
- package/dist/core-runtime/discovery/synthesize-cert-loop.js +234 -0
- package/dist/core-runtime/discovery/synthesize-cert-mutation.js +117 -0
- package/dist/core-runtime/discovery/synthesize-cert-packet.js +182 -0
- package/dist/core-runtime/discovery/synthesize-cert-record.js +831 -0
- package/dist/core-runtime/discovery/synthesize-cert-sampler.js +336 -0
- package/dist/core-runtime/effort-calibration-ingest.js +326 -0
- package/dist/core-runtime/effort-calibration-reconstruct.js +47 -0
- package/dist/core-runtime/effort-calibration-review.js +22 -0
- package/dist/core-runtime/effort-calibration-sweep.js +110 -0
- package/dist/core-runtime/effort-frontier.js +134 -0
- package/dist/core-runtime/llm/claude-bin.js +77 -0
- package/dist/core-runtime/llm/dispatch-breaker.js +412 -0
- package/dist/core-runtime/llm/dispatch-fallback-adapter-capabilities.js +33 -0
- package/dist/core-runtime/llm/llm-caller.js +316 -35
- package/dist/core-runtime/llm/mock-llm-realization.js +35 -4
- package/dist/core-runtime/llm/model-switcher.js +1 -1
- package/dist/core-runtime/llm/openai-responses-incomplete-error.js +46 -0
- package/dist/core-runtime/llm/sealed-dispatch-capability.js +359 -0
- package/dist/core-runtime/llm/structured-dispatch-error.js +15 -0
- package/dist/core-runtime/onboard/claude-profile-scan.js +65 -0
- package/dist/core-runtime/onboard/cli-host.js +5 -2
- package/dist/core-runtime/onboard/configure-provider.js +33 -1
- package/dist/core-runtime/onboard/host-target.js +28 -3
- package/dist/core-runtime/onboard/register.js +54 -12
- package/dist/core-runtime/pipeline-execution-ledger.js +10 -0
- package/dist/core-runtime/reconstruct/artifact-types.js +37 -0
- package/dist/core-runtime/reconstruct/benchmark-evidence.js +16 -0
- package/dist/core-runtime/reconstruct/claim-projection-validation.js +19 -5
- package/dist/core-runtime/reconstruct/competency-projection-contract.js +63 -0
- package/dist/core-runtime/reconstruct/comprehension-artifact.js +321 -0
- package/dist/core-runtime/reconstruct/comprehension-reduce.js +367 -0
- package/dist/core-runtime/reconstruct/comprehension-semantic-map.js +771 -0
- package/dist/core-runtime/reconstruct/contract-registry.js +20 -0
- package/dist/core-runtime/reconstruct/directive-validation.js +4 -3
- package/dist/core-runtime/reconstruct/dispatch-fallback-artifacts.js +640 -0
- package/dist/core-runtime/reconstruct/execution-telemetry.js +84 -9
- package/dist/core-runtime/reconstruct/final-output-sections.js +89 -0
- package/dist/core-runtime/reconstruct/governing-snapshot.js +36 -1
- package/dist/core-runtime/reconstruct/leaf-reader.js +305 -0
- package/dist/core-runtime/reconstruct/llm-dispatch-failure.js +270 -0
- package/dist/core-runtime/reconstruct/llm-touch-fingerprint.js +94 -0
- package/dist/core-runtime/reconstruct/material-admission-validation.js +20 -5
- package/dist/core-runtime/reconstruct/material-profile-validation.js +24 -6
- package/dist/core-runtime/reconstruct/materialize-preparation.js +380 -23
- package/dist/core-runtime/reconstruct/maturation-validation.js +1522 -67
- package/dist/core-runtime/reconstruct/mock-llm-realization.js +120 -1
- package/dist/core-runtime/reconstruct/obligation-assertion.js +18 -0
- package/dist/core-runtime/reconstruct/ontology-seed-validation.js +39 -7
- package/dist/core-runtime/reconstruct/output-budget.js +6 -0
- package/dist/core-runtime/reconstruct/pipeline-execution-ledger.js +112 -5
- package/dist/core-runtime/reconstruct/post-seed-validation.js +122 -11
- package/dist/core-runtime/reconstruct/proof-authority-validation.js +2 -6
- package/dist/core-runtime/reconstruct/purpose-authority-validation.js +119 -7
- package/dist/core-runtime/reconstruct/record.js +49 -3
- package/dist/core-runtime/reconstruct/registry-verification-validation.js +41 -5
- package/dist/core-runtime/reconstruct/run-control-validation.js +1019 -37
- package/dist/core-runtime/reconstruct/run.js +5409 -517
- package/dist/core-runtime/reconstruct/seed-authoring-readiness-validation.js +56 -8
- package/dist/core-runtime/reconstruct/semantic-quality-gate.js +112 -7
- package/dist/core-runtime/reconstruct/source-observation-delta-validation.js +53 -5
- package/dist/core-runtime/reconstruct/source-observations.js +166 -0
- package/dist/core-runtime/reconstruct/source-safety-validation.js +77 -188
- package/dist/core-runtime/reconstruct/source-scout-pack-validation.js +50 -6
- package/dist/core-runtime/reconstruct/terminal-validation.js +145 -13
- package/dist/core-runtime/review/continuation-plan.js +12 -5
- package/dist/core-runtime/review/issue-artifact-runtime.js +4 -1
- package/dist/core-runtime/review/materializers.js +100 -11
- package/dist/core-runtime/review/nesting-batch.js +6 -2
- package/dist/core-runtime/review/obligation-shardability.js +138 -0
- package/dist/core-runtime/review/pipeline-execution-ledger.js +42 -2
- package/dist/core-runtime/review/review-artifact-utils.js +219 -7
- package/dist/core-runtime/review/review-execution-steps.js +32 -8
- package/dist/core-runtime/review/review-progress-contract.js +8 -0
- package/dist/core-runtime/review/review-prompt-budget.js +97 -0
- package/dist/core-runtime/review/semantic-quality-gate.js +33 -7
- package/dist/core-runtime/review/spreadsheet-review-disposition.js +94 -0
- package/dist/core-runtime/route-identity.js +182 -0
- package/dist/core-runtime/spreadsheet-header-escalation.js +204 -0
- package/dist/core-runtime/spreadsheet-structure-observer.js +2689 -0
- package/dist/core-runtime/target-material-kind.js +58 -0
- package/dist/mcp/server.js +27 -5
- package/dist/mcp/tool-schemas.js +8 -0
- package/dist/tui/app.js +167 -0
- package/dist/tui/data/event-follower.js +116 -0
- package/dist/tui/data/node-detail.js +42 -0
- package/dist/tui/data/projection-poll.js +26 -0
- package/dist/tui/data/session-discovery.js +65 -0
- package/dist/tui/index.js +108 -0
- package/dist/tui/screens/log.js +25 -0
- package/dist/tui/screens/node-detail.js +17 -0
- package/dist/tui/screens/session-selector.js +26 -0
- package/dist/tui/screens/workflow-tree.js +90 -0
- package/dist/tui/view-model/reconstruct-adapter.js +162 -0
- package/dist/tui/view-model/review-adapter.js +270 -0
- package/dist/tui/view-model/tree-view-model.js +19 -0
- package/package.json +20 -3
- 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.
|
|
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": "
|
|
62
|
-
"
|
|
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"
|
package/settings.example.json
CHANGED
|
@@ -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.
|
|
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.
|
|
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.
|
|
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
|
-
#
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
215
|
-
"effort": "
|
|
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.
|
|
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
|
}
|