@nimiplatform/nimi-coding 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -20
- package/adapters/oh-my-codex/README.md +8 -9
- package/cli/commands/audit-sweep.mjs +10 -10
- package/cli/commands/classify-spec-tree.mjs +5 -0
- package/cli/commands/closeout.mjs +3 -0
- package/cli/commands/generate-spec-derived-docs.mjs +20 -0
- package/cli/commands/generate-spec-migration-plan.mjs +30 -0
- package/cli/commands/start.mjs +5 -1
- package/cli/commands/surface-validator-command.mjs +49 -0
- package/cli/commands/sweep-design.mjs +295 -0
- package/cli/commands/sweep.mjs +22 -0
- package/cli/commands/sync.mjs +132 -0
- package/cli/commands/topic-formatters.mjs +8 -8
- package/cli/commands/validate-ai-governance.mjs +167 -46
- package/cli/commands/validate-domain-admission.mjs +5 -0
- package/cli/commands/validate-guidance-bodies.mjs +5 -0
- package/cli/commands/validate-placement.mjs +5 -0
- package/cli/commands/validate-projection-edges.mjs +5 -0
- package/cli/commands/validate-spec-audit.mjs +5 -1
- package/cli/commands/validate-table-family.mjs +5 -0
- package/cli/commands/validate-tracked-output-admission.mjs +5 -0
- package/cli/constants.mjs +5 -49
- package/cli/help.mjs +33 -11
- package/cli/index.mjs +20 -2
- package/cli/lib/audit-sweep-runtime/admissions.mjs +38 -29
- package/cli/lib/audit-sweep-runtime/audit-validity.mjs +8 -0
- package/cli/lib/audit-sweep-runtime/chunks.mjs +11 -11
- package/cli/lib/audit-sweep-runtime/closeout.mjs +8 -8
- package/cli/lib/audit-sweep-runtime/codex-auditor-evidence.mjs +3 -3
- package/cli/lib/audit-sweep-runtime/codex-auditor.mjs +10 -10
- package/cli/lib/audit-sweep-runtime/common.mjs +7 -7
- package/cli/lib/audit-sweep-runtime/format.mjs +3 -3
- package/cli/lib/audit-sweep-runtime/ingest.mjs +8 -8
- package/cli/lib/audit-sweep-runtime/inventory-spec-chunks.mjs +24 -27
- package/cli/lib/audit-sweep-runtime/inventory.mjs +58 -18
- package/cli/lib/audit-sweep-runtime/ledger.mjs +1 -1
- package/cli/lib/audit-sweep-runtime/p0p1-profile.mjs +2 -2
- package/cli/lib/audit-sweep-runtime/remediation.mjs +6 -6
- package/cli/lib/audit-sweep-runtime/rerun.mjs +6 -6
- package/cli/lib/audit-sweep-runtime/status.mjs +1 -1
- package/cli/lib/audit-sweep-runtime/validators.mjs +2 -2
- package/cli/lib/authority-convergence.mjs +397 -2
- package/cli/lib/blueprint-audit.mjs +5 -5
- package/cli/lib/closeout.mjs +126 -3
- package/cli/lib/contracts.mjs +21 -17
- package/cli/lib/handoff.mjs +29 -11
- package/cli/lib/high-risk-admission.mjs +60 -11
- package/cli/lib/high-risk-decision.mjs +31 -2
- package/cli/lib/high-risk-ingest.mjs +5 -1
- package/cli/lib/high-risk-review.mjs +5 -1
- package/cli/lib/internal/contracts-parse.mjs +195 -24
- package/cli/lib/internal/contracts-validators.mjs +3 -2
- package/cli/lib/internal/doctor-bootstrap-surface.mjs +82 -35
- package/cli/lib/internal/doctor-delegated-surface.mjs +1 -1
- package/cli/lib/internal/doctor-finalize.mjs +12 -8
- package/cli/lib/internal/doctor-inspectors.mjs +34 -1
- package/cli/lib/internal/governance/ai/ai-context-budget-core.mjs +74 -12
- package/cli/lib/internal/governance/ai/ai-structure-budget-core.mjs +24 -6
- package/cli/lib/internal/governance/ai/check-agents-freshness.mjs +18 -23
- package/cli/lib/internal/surface-taxonomy-validators.mjs +931 -0
- package/cli/lib/internal/validators-spec.mjs +229 -20
- package/cli/lib/sweep-design-runtime/common.mjs +246 -0
- package/cli/lib/sweep-design-runtime/engine.mjs +733 -0
- package/cli/lib/sweep-design-runtime/fix-topic.mjs +414 -0
- package/cli/lib/sweep-design-runtime/lifecycle.mjs +54 -0
- package/cli/lib/sweep-design-runtime/results.mjs +324 -0
- package/cli/lib/sweep-design.mjs +8 -0
- package/cli/lib/sync.mjs +143 -0
- package/cli/lib/topic-artifacts.mjs +186 -0
- package/cli/lib/topic-authority-coverage.mjs +73 -0
- package/cli/lib/topic-closeout.mjs +560 -0
- package/cli/lib/topic-common.mjs +404 -0
- package/cli/lib/topic-decisions.mjs +332 -0
- package/cli/lib/topic-draft-packets.mjs +126 -7
- package/cli/lib/topic-execution.mjs +515 -0
- package/cli/lib/topic-goal.mjs +112 -33
- package/cli/lib/topic-ledger.mjs +281 -0
- package/cli/lib/topic-lifecycle-artifacts.mjs +173 -0
- package/cli/lib/topic-root-validation.mjs +288 -0
- package/cli/lib/topic-runner-commands.mjs +174 -0
- package/cli/lib/topic-runner-deferral.mjs +532 -0
- package/cli/lib/topic-runner-stale-gates.mjs +114 -0
- package/cli/lib/topic-runner-validation.mjs +138 -0
- package/cli/lib/topic-runner.mjs +109 -154
- package/cli/lib/topic-scaffold.mjs +252 -0
- package/cli/lib/topic-waves.mjs +403 -0
- package/cli/lib/topic.mjs +81 -93
- package/cli/lib/value-helpers.mjs +6 -1
- package/cli/seeds/bootstrap.mjs +96 -20
- package/cli/seeds/seed-policy.yaml +67 -0
- package/config/bootstrap.yaml +1 -1
- package/config/skill-manifest.yaml +4 -2
- package/config/spec-generation-inputs.yaml +41 -19
- package/contracts/audit-remediation-map.schema.yaml +1 -0
- package/contracts/audit-sweep-result.yaml +4 -0
- package/contracts/domain-admission.schema.yaml +56 -0
- package/contracts/migration-inventory.schema.yaml +80 -0
- package/contracts/negative-fixtures.yaml +91 -0
- package/contracts/placement-contract.schema.yaml +163 -0
- package/contracts/projection-edge.schema.yaml +130 -0
- package/contracts/shared-enums.yaml +68 -0
- package/contracts/spec-generation-audit.schema.yaml +19 -4
- package/contracts/spec-generation-inputs.schema.yaml +130 -29
- package/contracts/spec-reconstruction-result.yaml +9 -5
- package/contracts/surface-taxonomy.schema.yaml +201 -0
- package/contracts/sweep-design-result.yaml +349 -0
- package/contracts/table-family.schema.yaml +114 -0
- package/contracts/topic-goal.schema.yaml +10 -1
- package/contracts/tracked-output-admission.schema.yaml +70 -0
- package/contracts/workflow-consumer.schema.yaml +112 -0
- package/methodology/audit-sweep-p0p1-recall.yaml +1 -1
- package/methodology/spec-reconstruction.yaml +53 -30
- package/package.json +5 -4
- package/spec/_meta/command-gating-matrix.yaml +33 -0
- package/spec/_meta/generate-drift-migration-checklist.yaml +44 -62
- package/spec/_meta/governance-routing-cutover-checklist.yaml +3 -3
- package/spec/_meta/phase2-impacted-surface-matrix.yaml +14 -14
- package/spec/_meta/spec-authority-cutover-readiness.yaml +3 -5
- package/spec/_meta/spec-tree-model.yaml +104 -36
- package/spec/bootstrap-state.yaml +36 -36
- package/spec/product-scope.yaml +13 -10
package/README.md
CHANGED
|
@@ -19,14 +19,14 @@ The primary `nimicoding` path is for an ordinary project with mixed inputs:
|
|
|
19
19
|
6. close out reconstruction
|
|
20
20
|
7. hand off `doc_spec_audit` and close it out locally
|
|
21
21
|
|
|
22
|
-
`blueprint-audit
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
`blueprint-audit` and benchmark parity remain available, but they are
|
|
23
|
+
support-only package fixtures. They do not define default reconstruction
|
|
24
|
+
completion for a host project.
|
|
25
25
|
|
|
26
|
-
In
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
In a host project, `/.nimi/spec/**` becomes product authority only after that
|
|
27
|
+
project admits or reconstructs it. `nimicoding` provides the CLI, injected
|
|
28
|
+
`.nimi/{config,contracts,methodology}/**` contracts, and validators; it does
|
|
29
|
+
not make a host read package source paths directly.
|
|
30
30
|
|
|
31
31
|
## Current Status
|
|
32
32
|
|
|
@@ -37,7 +37,7 @@ Its completed standalone scope is:
|
|
|
37
37
|
- package identity
|
|
38
38
|
- repository foundation
|
|
39
39
|
- initial AI-native methodology seed
|
|
40
|
-
- package-owned
|
|
40
|
+
- package-owned support profile source for future governance slices
|
|
41
41
|
- machine-readable reconstruction, doc-spec-audit, and high-risk execution result contracts
|
|
42
42
|
- package-owned canonical high-risk admission schema contract
|
|
43
43
|
- seed-only high-risk execution schemas for packet, orchestration-state, prompt, worker-output, and acceptance
|
|
@@ -73,8 +73,8 @@ At the current stage it provides:
|
|
|
73
73
|
- a primary `nimicoding start` entrypoint for bootstrap, resume, and next-stage AI task prep
|
|
74
74
|
- a conservative `nimicoding clear` entrypoint for removing package-managed setup without deleting project-owned truth
|
|
75
75
|
- a bounded `nimicoding doctor`
|
|
76
|
-
- an explicit `nimicoding blueprint-audit` equivalence check for comparing a
|
|
77
|
-
-
|
|
76
|
+
- an explicit `nimicoding blueprint-audit` equivalence check for comparing a fixture or host blueprint root with the candidate canonical tree under `.nimi/spec`
|
|
77
|
+
- surface validators for placement, table-family, projection-edge, guidance-body, domain-admission, and tracked-output admission boundaries
|
|
78
78
|
- an explicit `nimicoding handoff` export
|
|
79
79
|
- an explicit `nimicoding admit-high-risk-decision` semantic admission surface
|
|
80
80
|
- a local-only `nimicoding closeout` projection
|
|
@@ -91,7 +91,7 @@ Current `nimicoding start` behavior is intentionally narrow:
|
|
|
91
91
|
- detect the current project state and continue from the right stage
|
|
92
92
|
- create or resume the `.nimi/**` seed by projecting package-owned source into host paths
|
|
93
93
|
- seed AI-native spec-reconstruction guidance inside `.nimi/**`
|
|
94
|
-
- keep
|
|
94
|
+
- keep support-only methodology assets package-owned unless a host explicitly opts into them
|
|
95
95
|
- seed package-owned machine contracts inside `.nimi/contracts/**`
|
|
96
96
|
- seed package-owned execution schemas for future high-risk methodology artifacts without admitting runtime ownership
|
|
97
97
|
- seed canonical skill-manifest, host-profile, installer, delegated runtime contract, installer result contract, installer operational evidence home, and external handoff truth inside `.nimi/**`
|
|
@@ -198,21 +198,20 @@ cross-report navigation harder. Stable machine report artifacts that are meant
|
|
|
198
198
|
to behave like a current snapshot, such as `blueprint-equivalence-audit.json`,
|
|
199
199
|
should keep their fixed names.
|
|
200
200
|
|
|
201
|
-
## Canonical Spec
|
|
201
|
+
## Canonical Spec Surface Model
|
|
202
202
|
|
|
203
|
-
The package
|
|
204
|
-
|
|
205
|
-
|
|
203
|
+
The package seeds the host-local contracts needed to reconstruct and validate a
|
|
204
|
+
canonical spec tree without putting package methodology or lifecycle state under
|
|
205
|
+
the host product-authority root.
|
|
206
206
|
|
|
207
207
|
At this stage:
|
|
208
208
|
|
|
209
|
-
-
|
|
210
|
-
-
|
|
211
|
-
- `start`, `doctor`, `handoff`, `closeout`, and high-risk gating
|
|
209
|
+
- `config/**`, `contracts/**`, `methodology/**`, and `spec/**` are package source for the npm package
|
|
210
|
+
- generated host projects receive injected `.nimi/{config,contracts,methodology}/**` projections and own their `.nimi/spec/**` product authority
|
|
211
|
+
- `start`, `doctor`, `handoff`, `closeout`, and high-risk gating read host-local `.nimi/**` projections instead of requiring access to package source paths
|
|
212
212
|
- `nimicoding blueprint-audit` remains the explicit audit surface for benchmark-vs-canonical equivalence checks; it does not perform routing changes on its own
|
|
213
|
-
- `pnpm check:spec-authority-cutover-readiness` remains a pre-cutover readiness aggregator; after cutover it is historical/preflight-only rather than the active authority source
|
|
214
213
|
- canonical spec generation now reads mixed inputs from `.nimi/config/spec-generation-inputs.yaml` and treats any blueprint root as an optional benchmark rather than a universal host assumption
|
|
215
|
-
- completed canonical reconstruction now requires
|
|
214
|
+
- completed canonical reconstruction now requires structural validity and may carry file-level auditability under `.nimi/local/state/spec-generation/spec-generation-audit.yaml`
|
|
216
215
|
- `nimicoding validate-spec-tree` checks canonical tree structure, while `nimicoding validate-spec-audit` checks per-file grounding, inference, and unresolved-gap tracking
|
|
217
216
|
|
|
218
217
|
Current `nimicoding doctor` behavior is intentionally narrow:
|
|
@@ -97,8 +97,8 @@ nimicoding handoff --skill spec_reconstruction --json
|
|
|
97
97
|
Use the JSON payload as OMX's machine contract. `--prompt` may still be used
|
|
98
98
|
as a host briefing, but it is not the authoritative surface. OMX should
|
|
99
99
|
return only the declared canonical tree outputs and must not invent new semantic
|
|
100
|
-
owners. In
|
|
101
|
-
|
|
100
|
+
owners. In a host project, `.nimi/spec/**` is current authority only when the
|
|
101
|
+
host has admitted or reconstructed it; OMX still must not redefine that
|
|
102
102
|
authority or promote its own runtime state into semantic truth.
|
|
103
103
|
|
|
104
104
|
Then project the closeout locally:
|
|
@@ -152,13 +152,12 @@ For now, treat OMX output as execution candidate material:
|
|
|
152
152
|
|
|
153
153
|
In practice, this means the first real user can use OMX as the execution host
|
|
154
154
|
today, while standalone `nimicoding` remains the host-agnostic semantic and
|
|
155
|
-
interop boundary package. The
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
`nimicoding
|
|
160
|
-
|
|
161
|
-
the referenced packet/prompt/output candidates while
|
|
155
|
+
interop boundary package. The standalone package intentionally does not own
|
|
156
|
+
packet-bound runtime, provider-backed execution, scheduler, notification, or
|
|
157
|
+
automation surfaces yet, even though `nimicoding closeout` can import a
|
|
158
|
+
fail-closed local-only execution summary and
|
|
159
|
+
`nimicoding ingest-high-risk-execution` can mechanically validate the
|
|
160
|
+
referenced packet/prompt/output candidates while
|
|
162
161
|
`nimicoding review-high-risk-execution` can project a manager-ready local
|
|
163
162
|
attachment bundle, `nimicoding decide-high-risk-execution` can record a
|
|
164
163
|
manager-owned local disposition, and `nimicoding admit-high-risk-decision`
|
|
@@ -22,8 +22,8 @@ function readRequiredValue(args, index, optionName, commandName) {
|
|
|
22
22
|
return {
|
|
23
23
|
ok: false,
|
|
24
24
|
error: `${localize(
|
|
25
|
-
`nimicoding
|
|
26
|
-
`nimicoding
|
|
25
|
+
`nimicoding sweep audit ${commandName} refused: ${optionName} requires a value.`,
|
|
26
|
+
`nimicoding sweep audit ${commandName} 已拒绝:${optionName} 需要一个值。`,
|
|
27
27
|
)}\n`,
|
|
28
28
|
};
|
|
29
29
|
}
|
|
@@ -34,8 +34,8 @@ function unknownOption(commandName, arg) {
|
|
|
34
34
|
return {
|
|
35
35
|
ok: false,
|
|
36
36
|
error: `${localize(
|
|
37
|
-
`nimicoding
|
|
38
|
-
`nimicoding
|
|
37
|
+
`nimicoding sweep audit ${commandName} refused: unknown option ${arg}.`,
|
|
38
|
+
`nimicoding sweep audit ${commandName} 已拒绝:未知选项 ${arg}。`,
|
|
39
39
|
)}\n`,
|
|
40
40
|
};
|
|
41
41
|
}
|
|
@@ -65,8 +65,8 @@ function parseOptions(args, commandName, spec) {
|
|
|
65
65
|
return {
|
|
66
66
|
ok: false,
|
|
67
67
|
error: `${localize(
|
|
68
|
-
`nimicoding
|
|
69
|
-
`nimicoding
|
|
68
|
+
`nimicoding sweep audit ${commandName} refused: ${arg} must be a positive integer.`,
|
|
69
|
+
`nimicoding sweep audit ${commandName} 已拒绝:${arg} 必须是正整数。`,
|
|
70
70
|
)}\n`,
|
|
71
71
|
};
|
|
72
72
|
}
|
|
@@ -85,8 +85,8 @@ function parseOptions(args, commandName, spec) {
|
|
|
85
85
|
return {
|
|
86
86
|
ok: false,
|
|
87
87
|
error: `${localize(
|
|
88
|
-
`nimicoding
|
|
89
|
-
`nimicoding
|
|
88
|
+
`nimicoding sweep audit ${commandName} refused: missing required options: ${missing.join(", ")}.`,
|
|
89
|
+
`nimicoding sweep audit ${commandName} 已拒绝:缺少必填选项:${missing.join(", ")}。`,
|
|
90
90
|
)}\n`,
|
|
91
91
|
};
|
|
92
92
|
}
|
|
@@ -269,8 +269,8 @@ function parseAuditSweepOptions(args) {
|
|
|
269
269
|
return {
|
|
270
270
|
ok: false,
|
|
271
271
|
error: `${localize(
|
|
272
|
-
"nimicoding
|
|
273
|
-
"nimicoding
|
|
272
|
+
"nimicoding sweep audit refused: expected one of `plan`, `chunk dispatch`, `chunk audit-codex`, `chunk ingest`, `chunk review`, `chunk skip`, `ledger build`, `remediation-map build`, `remediation-map admit`, `finding resolve`, `closeout summary`, `status`, or `validate`.",
|
|
273
|
+
"nimicoding sweep audit 已拒绝:需要使用 `plan`、`chunk dispatch`、`chunk ingest`、`chunk review`、`chunk skip`、`ledger build`、`remediation-map build`、`remediation-map admit`、`finding resolve`、`closeout summary`、`status` 或 `validate`。",
|
|
274
274
|
)}\n`,
|
|
275
275
|
};
|
|
276
276
|
}
|
|
@@ -163,6 +163,9 @@ export async function runCloseout(args) {
|
|
|
163
163
|
const payload = await buildCloseoutPayload(process.cwd(), effectiveOptions);
|
|
164
164
|
if (payload.inputError) {
|
|
165
165
|
process.stderr.write(payload.error);
|
|
166
|
+
if (parsed.options.json) {
|
|
167
|
+
process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
|
|
168
|
+
}
|
|
166
169
|
return payload.exitCode;
|
|
167
170
|
}
|
|
168
171
|
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
|
|
1
5
|
import { localize } from "../lib/ui.mjs";
|
|
2
6
|
import { loadGovernanceConfig, requireProfile } from "../lib/internal/governance/config.mjs";
|
|
3
7
|
import { runCommand } from "../lib/internal/governance/runner.mjs";
|
|
8
|
+
import { parseSpecGenerationInputsConfig } from "../lib/internal/contracts-parse.mjs";
|
|
9
|
+
|
|
10
|
+
const PACKAGE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
|
|
4
11
|
|
|
5
12
|
function parseOptions(args) {
|
|
6
13
|
const options = {
|
|
@@ -100,6 +107,19 @@ export async function runGenerateSpecDerivedDocs(args) {
|
|
|
100
107
|
return 2;
|
|
101
108
|
}
|
|
102
109
|
|
|
110
|
+
const packageInputsText = await readFile(
|
|
111
|
+
path.join(PACKAGE_ROOT, "config", "spec-generation-inputs.yaml"),
|
|
112
|
+
"utf8",
|
|
113
|
+
);
|
|
114
|
+
const packageInputs = parseSpecGenerationInputsConfig(packageInputsText);
|
|
115
|
+
if (!packageInputs.ok || !packageInputs.generationOrder.includes("validate_placement")) {
|
|
116
|
+
process.stderr.write(localize(
|
|
117
|
+
"nimicoding generate-spec-derived-docs refused: package spec generation inputs must be class-filtered and include placement validation.\n",
|
|
118
|
+
"nimicoding generate-spec-derived-docs 已拒绝:package spec generation inputs 必须按 surface class 过滤并包含 placement validation。\n",
|
|
119
|
+
));
|
|
120
|
+
return 2;
|
|
121
|
+
}
|
|
122
|
+
|
|
103
123
|
let failed = false;
|
|
104
124
|
for (const scope of scopeResolution.scopes) {
|
|
105
125
|
const commands = governance.config.specGovernance.generateCommands[scope] || [];
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import {
|
|
2
|
+
generateSpecMigrationPlan,
|
|
3
|
+
parseSurfaceValidatorOptions,
|
|
4
|
+
writeMigrationPlanIfRequested,
|
|
5
|
+
} from "../lib/internal/surface-taxonomy-validators.mjs";
|
|
6
|
+
import { localize } from "../lib/ui.mjs";
|
|
7
|
+
|
|
8
|
+
export async function runGenerateSpecMigrationPlan(args) {
|
|
9
|
+
const parsed = parseSurfaceValidatorOptions(args);
|
|
10
|
+
if (!parsed.ok) {
|
|
11
|
+
process.stderr.write(localize(
|
|
12
|
+
`nimicoding generate-spec-migration-plan refused: ${parsed.error}\n`,
|
|
13
|
+
`nimicoding generate-spec-migration-plan 已拒绝:${parsed.error}\n`,
|
|
14
|
+
));
|
|
15
|
+
return 2;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
const report = await generateSpecMigrationPlan(process.cwd(), parsed.options);
|
|
20
|
+
await writeMigrationPlanIfRequested(report, parsed.options.emit, process.cwd());
|
|
21
|
+
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
22
|
+
return report.ok ? 0 : 1;
|
|
23
|
+
} catch (error) {
|
|
24
|
+
process.stderr.write(localize(
|
|
25
|
+
`nimicoding generate-spec-migration-plan refused: ${error.message}\n`,
|
|
26
|
+
`nimicoding generate-spec-migration-plan 已拒绝:${error.message}\n`,
|
|
27
|
+
));
|
|
28
|
+
return 2;
|
|
29
|
+
}
|
|
30
|
+
}
|
package/cli/commands/start.mjs
CHANGED
|
@@ -343,8 +343,12 @@ function buildTaskStageLines(mode) {
|
|
|
343
343
|
}
|
|
344
344
|
|
|
345
345
|
function canonicalTreeReady(doctorResult) {
|
|
346
|
-
|
|
346
|
+
const v2Ready = doctorResult.specGenerationInputs?.mode === "class_filtered"
|
|
347
|
+
&& doctorResult.canonicalTree?.requiredFilesValid === true
|
|
348
|
+
&& doctorResult.specGenerationAudit?.ok === true;
|
|
349
|
+
const legacyReady = doctorResult.lifecycleState?.treeState === "canonical_tree_ready"
|
|
347
350
|
&& doctorResult.canonicalTree?.requiredFilesValid === true;
|
|
351
|
+
return v2Ready || legacyReady;
|
|
348
352
|
}
|
|
349
353
|
|
|
350
354
|
function determineWizardStage(doctorResult) {
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import {
|
|
2
|
+
classifySpecSurface,
|
|
3
|
+
parseSurfaceValidatorOptions,
|
|
4
|
+
validateDomainAdmission,
|
|
5
|
+
validateGuidanceBodies,
|
|
6
|
+
validatePlacement,
|
|
7
|
+
validateProjectionEdges,
|
|
8
|
+
validateTableFamily,
|
|
9
|
+
validateTrackedOutputAdmission,
|
|
10
|
+
writeInventoryIfRequested,
|
|
11
|
+
} from "../lib/internal/surface-taxonomy-validators.mjs";
|
|
12
|
+
import { localize } from "../lib/ui.mjs";
|
|
13
|
+
|
|
14
|
+
const VALIDATORS = {
|
|
15
|
+
"classify-spec-tree": classifySpecSurface,
|
|
16
|
+
"validate-placement": validatePlacement,
|
|
17
|
+
"validate-table-family": validateTableFamily,
|
|
18
|
+
"validate-projection-edges": validateProjectionEdges,
|
|
19
|
+
"validate-guidance-bodies": validateGuidanceBodies,
|
|
20
|
+
"validate-domain-admission": validateDomainAdmission,
|
|
21
|
+
"validate-tracked-output-admission": validateTrackedOutputAdmission,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export async function runSurfaceValidatorCommand(args, validatorName) {
|
|
25
|
+
const parsed = parseSurfaceValidatorOptions(args);
|
|
26
|
+
if (!parsed.ok) {
|
|
27
|
+
process.stderr.write(localize(
|
|
28
|
+
`nimicoding ${validatorName} refused: ${parsed.error}\n`,
|
|
29
|
+
`nimicoding ${validatorName} 已拒绝:${parsed.error}\n`,
|
|
30
|
+
));
|
|
31
|
+
return 2;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const validator = VALIDATORS[validatorName];
|
|
35
|
+
if (!validator) {
|
|
36
|
+
process.stderr.write(localize(
|
|
37
|
+
`nimicoding ${validatorName} refused: unknown surface validator.\n`,
|
|
38
|
+
`nimicoding ${validatorName} 已拒绝:未知 surface validator。\n`,
|
|
39
|
+
));
|
|
40
|
+
return 2;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const report = await validator(process.cwd(), parsed.options);
|
|
44
|
+
if (validatorName === "classify-spec-tree") {
|
|
45
|
+
await writeInventoryIfRequested(report, parsed.options.emit, process.cwd());
|
|
46
|
+
}
|
|
47
|
+
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
48
|
+
return report.ok ? 0 : 1;
|
|
49
|
+
}
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import {
|
|
2
|
+
runAuditorPrompt,
|
|
3
|
+
runFinalize,
|
|
4
|
+
runFixTopic,
|
|
5
|
+
runIntake,
|
|
6
|
+
runLedgerValidate,
|
|
7
|
+
runPacketBuild,
|
|
8
|
+
runPacketBuildBatch,
|
|
9
|
+
runResultIngest,
|
|
10
|
+
runWavePlan,
|
|
11
|
+
} from "../lib/sweep-design.mjs";
|
|
12
|
+
import { localize } from "../lib/ui.mjs";
|
|
13
|
+
|
|
14
|
+
function readRequiredValue(args, index, optionName, commandName) {
|
|
15
|
+
const next = args[index + 1];
|
|
16
|
+
if (!next || next.startsWith("--")) {
|
|
17
|
+
return {
|
|
18
|
+
ok: false,
|
|
19
|
+
error: `${localize(
|
|
20
|
+
`nimicoding sweep design ${commandName} refused: ${optionName} requires a value.`,
|
|
21
|
+
`nimicoding sweep design ${commandName} 已拒绝:${optionName} 需要一个值。`,
|
|
22
|
+
)}\n`,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
return { ok: true, value: next };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function unknownOption(commandName, arg) {
|
|
29
|
+
return {
|
|
30
|
+
ok: false,
|
|
31
|
+
error: `${localize(
|
|
32
|
+
`nimicoding sweep design ${commandName} refused: unknown option ${arg}.`,
|
|
33
|
+
`nimicoding sweep design ${commandName} 已拒绝:未知选项 ${arg}。`,
|
|
34
|
+
)}\n`,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function parseOptions(args, commandName, spec) {
|
|
39
|
+
const options = Object.fromEntries(Object.entries(spec).map(([name, config]) => [name, config.default ?? null]));
|
|
40
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
41
|
+
const arg = args[index];
|
|
42
|
+
if (arg === "--json") {
|
|
43
|
+
options.json = true;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
const entry = Object.entries(spec).find(([, config]) => config.flag === arg);
|
|
47
|
+
if (!entry) {
|
|
48
|
+
return unknownOption(commandName, arg);
|
|
49
|
+
}
|
|
50
|
+
const [name] = entry;
|
|
51
|
+
if (entry[1].type === "boolean") {
|
|
52
|
+
options[name] = true;
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
const value = readRequiredValue(args, index, arg, commandName);
|
|
56
|
+
if (!value.ok) return value;
|
|
57
|
+
options[name] = value.value;
|
|
58
|
+
index += 1;
|
|
59
|
+
}
|
|
60
|
+
const missing = Object.entries(spec)
|
|
61
|
+
.filter(([, config]) => config.required)
|
|
62
|
+
.filter(([name]) => !options[name])
|
|
63
|
+
.map(([, config]) => config.flag);
|
|
64
|
+
if (missing.length > 0) {
|
|
65
|
+
return {
|
|
66
|
+
ok: false,
|
|
67
|
+
error: `${localize(
|
|
68
|
+
`nimicoding sweep design ${commandName} refused: missing required options: ${missing.join(", ")}.`,
|
|
69
|
+
`nimicoding sweep design ${commandName} 已拒绝:缺少必填选项:${missing.join(", ")}。`,
|
|
70
|
+
)}\n`,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
return { ok: true, options };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function parseSweepDesignOptions(args) {
|
|
77
|
+
const [phase] = args;
|
|
78
|
+
if (phase === "intake") {
|
|
79
|
+
return {
|
|
80
|
+
ok: true,
|
|
81
|
+
action: "intake",
|
|
82
|
+
parsed: parseOptions(args.slice(1), "intake", {
|
|
83
|
+
sweepId: { flag: "--sweep-id", required: true },
|
|
84
|
+
runId: { flag: "--run-id" },
|
|
85
|
+
verifiedAt: { flag: "--verified-at" },
|
|
86
|
+
json: { default: false },
|
|
87
|
+
}),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
if (phase === "packet-build") {
|
|
91
|
+
return {
|
|
92
|
+
ok: true,
|
|
93
|
+
action: "packet-build",
|
|
94
|
+
parsed: parseOptions(args.slice(1), "packet-build", {
|
|
95
|
+
runId: { flag: "--run-id", required: true },
|
|
96
|
+
packetId: { flag: "--packet-id", required: true },
|
|
97
|
+
findingId: { flag: "--finding-id" },
|
|
98
|
+
findingIds: { flag: "--finding-ids" },
|
|
99
|
+
explicitQuestion: { flag: "--explicit-question" },
|
|
100
|
+
explicitQuestions: { flag: "--explicit-questions" },
|
|
101
|
+
priorDesignStateRefs: { flag: "--prior-design-state-refs" },
|
|
102
|
+
priorDesignStateMarker: { flag: "--prior-design-state-marker" },
|
|
103
|
+
currentClusterRefs: { flag: "--current-cluster-refs" },
|
|
104
|
+
currentWaveRefs: { flag: "--current-wave-refs" },
|
|
105
|
+
authorityOnly: { flag: "--authority-only", type: "boolean", default: false },
|
|
106
|
+
verifiedAt: { flag: "--verified-at" },
|
|
107
|
+
json: { default: false },
|
|
108
|
+
}),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
if (phase === "packet-build-batch") {
|
|
112
|
+
return {
|
|
113
|
+
ok: true,
|
|
114
|
+
action: "packet-build-batch",
|
|
115
|
+
parsed: parseOptions(args.slice(1), "packet-build-batch", {
|
|
116
|
+
runId: { flag: "--run-id", required: true },
|
|
117
|
+
batchSize: { flag: "--batch-size", required: true },
|
|
118
|
+
findingIds: { flag: "--finding-ids" },
|
|
119
|
+
packetPrefix: { flag: "--packet-prefix" },
|
|
120
|
+
manifestId: { flag: "--manifest-id" },
|
|
121
|
+
explicitQuestion: { flag: "--explicit-question" },
|
|
122
|
+
explicitQuestions: { flag: "--explicit-questions" },
|
|
123
|
+
priorDesignStateRefs: { flag: "--prior-design-state-refs" },
|
|
124
|
+
priorDesignStateMarker: { flag: "--prior-design-state-marker" },
|
|
125
|
+
currentClusterRefs: { flag: "--current-cluster-refs" },
|
|
126
|
+
currentWaveRefs: { flag: "--current-wave-refs" },
|
|
127
|
+
authorityOnly: { flag: "--authority-only", type: "boolean", default: false },
|
|
128
|
+
verifiedAt: { flag: "--verified-at" },
|
|
129
|
+
json: { default: false },
|
|
130
|
+
}),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
if (phase === "result-ingest") {
|
|
134
|
+
return {
|
|
135
|
+
ok: true,
|
|
136
|
+
action: "result-ingest",
|
|
137
|
+
parsed: parseOptions(args.slice(1), "result-ingest", {
|
|
138
|
+
runId: { flag: "--run-id", required: true },
|
|
139
|
+
from: { flag: "--from", required: true },
|
|
140
|
+
mode: { flag: "--mode", default: "focused" },
|
|
141
|
+
allowSyntheticTrial: { flag: "--allow-synthetic-trial", type: "boolean", default: false },
|
|
142
|
+
verifiedAt: { flag: "--verified-at" },
|
|
143
|
+
json: { default: false },
|
|
144
|
+
}),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
if (phase === "auditor-prompt") {
|
|
148
|
+
return {
|
|
149
|
+
ok: true,
|
|
150
|
+
action: "auditor-prompt",
|
|
151
|
+
parsed: parseOptions(args.slice(1), "auditor-prompt", {
|
|
152
|
+
runId: { flag: "--run-id", required: true },
|
|
153
|
+
packetId: { flag: "--packet-id", required: true },
|
|
154
|
+
verifiedAt: { flag: "--verified-at" },
|
|
155
|
+
json: { default: false },
|
|
156
|
+
}),
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
if (phase === "finalize") {
|
|
160
|
+
return {
|
|
161
|
+
ok: true,
|
|
162
|
+
action: "finalize",
|
|
163
|
+
parsed: parseOptions(args.slice(1), "finalize", {
|
|
164
|
+
runId: { flag: "--run-id", required: true },
|
|
165
|
+
allowSyntheticCloseout: { flag: "--allow-synthetic-closeout", type: "boolean", default: false },
|
|
166
|
+
verifiedAt: { flag: "--verified-at" },
|
|
167
|
+
json: { default: false },
|
|
168
|
+
}),
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
if (phase === "ledger-validate") {
|
|
172
|
+
return {
|
|
173
|
+
ok: true,
|
|
174
|
+
action: "ledger-validate",
|
|
175
|
+
parsed: parseOptions(args.slice(1), "ledger-validate", {
|
|
176
|
+
runId: { flag: "--run-id", required: true },
|
|
177
|
+
verifiedAt: { flag: "--verified-at" },
|
|
178
|
+
json: { default: false },
|
|
179
|
+
}),
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
if (phase === "wave-plan") {
|
|
183
|
+
return {
|
|
184
|
+
ok: true,
|
|
185
|
+
action: "wave-plan",
|
|
186
|
+
parsed: parseOptions(args.slice(1), "wave-plan", {
|
|
187
|
+
runId: { flag: "--run-id", required: true },
|
|
188
|
+
topicId: { flag: "--topic-id", required: true },
|
|
189
|
+
allowSyntheticTrial: { flag: "--allow-synthetic-trial", type: "boolean", default: false },
|
|
190
|
+
verifiedAt: { flag: "--verified-at" },
|
|
191
|
+
json: { default: false },
|
|
192
|
+
}),
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
if (phase === "fix-topic") {
|
|
196
|
+
return {
|
|
197
|
+
ok: true,
|
|
198
|
+
action: "fix-topic",
|
|
199
|
+
parsed: parseOptions(args.slice(1), "fix-topic", {
|
|
200
|
+
runId: { flag: "--run-id", required: true },
|
|
201
|
+
slug: { flag: "--slug" },
|
|
202
|
+
title: { flag: "--title" },
|
|
203
|
+
admitFirstWave: { flag: "--admit-first-wave", type: "boolean", default: false },
|
|
204
|
+
admitWaveId: { flag: "--admit-wave-id" },
|
|
205
|
+
verifiedAt: { flag: "--verified-at" },
|
|
206
|
+
json: { default: false },
|
|
207
|
+
}),
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
return {
|
|
211
|
+
ok: false,
|
|
212
|
+
error: `${localize(
|
|
213
|
+
"nimicoding sweep design refused: expected intake, packet-build, packet-build-batch, auditor-prompt, result-ingest, ledger-validate, finalize, wave-plan, or fix-topic.",
|
|
214
|
+
"nimicoding sweep design 已拒绝:需要 intake、packet-build、packet-build-batch、auditor-prompt、result-ingest、ledger-validate、finalize、wave-plan 或 fix-topic。",
|
|
215
|
+
)}\n`,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function emitResult(result, json) {
|
|
220
|
+
if (result.inputError) {
|
|
221
|
+
process.stderr.write(result.error);
|
|
222
|
+
return result.exitCode ?? 2;
|
|
223
|
+
}
|
|
224
|
+
if (!result.ok) {
|
|
225
|
+
process.stderr.write(result.error ?? "nimicoding sweep design failed.\n");
|
|
226
|
+
return result.exitCode ?? 1;
|
|
227
|
+
}
|
|
228
|
+
if (json) {
|
|
229
|
+
process.stdout.write(`${JSON.stringify({ command: "sweep.design", ...result }, null, 2)}\n`);
|
|
230
|
+
} else {
|
|
231
|
+
const lines = ["sweep design result"];
|
|
232
|
+
for (const [label, value] of [
|
|
233
|
+
["run", result.runId],
|
|
234
|
+
["inventory", result.inventoryRef],
|
|
235
|
+
["ledger", result.ledgerRef],
|
|
236
|
+
["packet", result.packetRef],
|
|
237
|
+
["auditor prompt", result.promptRef],
|
|
238
|
+
["auditor result", result.resultRef],
|
|
239
|
+
["decision queue", result.decisionQueueRef],
|
|
240
|
+
["final state report", result.finalStateReportRef],
|
|
241
|
+
["wave plan", result.wavePlanRef],
|
|
242
|
+
["topic", result.topicRef],
|
|
243
|
+
["sweep fix source", result.sourceRef],
|
|
244
|
+
["wave catalog", result.waveCatalogRef],
|
|
245
|
+
]) {
|
|
246
|
+
if (value !== undefined && value !== null) {
|
|
247
|
+
lines.push(`${label}: ${value}`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
for (const [label, value] of [
|
|
251
|
+
["findings", result.findingCount],
|
|
252
|
+
["finding outcomes", result.findingOutcomeCount],
|
|
253
|
+
["revision entries", result.revisionEntryCount],
|
|
254
|
+
["total findings", result.totalFindingCount],
|
|
255
|
+
["final findings", result.finalFindingCount],
|
|
256
|
+
["transient findings", result.transientFindingCount],
|
|
257
|
+
["waves", result.waveCount],
|
|
258
|
+
["admitted wave", result.admittedWaveId],
|
|
259
|
+
["stop class", result.stopClass],
|
|
260
|
+
["stop reason", result.stopReason],
|
|
261
|
+
]) {
|
|
262
|
+
if (value !== undefined && value !== null) {
|
|
263
|
+
lines.push(`${label}: ${value}`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
process.stdout.write(`${lines.join("\n")}\n`);
|
|
267
|
+
}
|
|
268
|
+
return result.exitCode ?? 0;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export async function runSweepDesign(args) {
|
|
272
|
+
const parsedAction = parseSweepDesignOptions(args);
|
|
273
|
+
if (!parsedAction.ok) {
|
|
274
|
+
process.stderr.write(parsedAction.error);
|
|
275
|
+
return 2;
|
|
276
|
+
}
|
|
277
|
+
if (!parsedAction.parsed.ok) {
|
|
278
|
+
process.stderr.write(parsedAction.parsed.error);
|
|
279
|
+
return 2;
|
|
280
|
+
}
|
|
281
|
+
const options = parsedAction.parsed.options;
|
|
282
|
+
const projectRoot = process.cwd();
|
|
283
|
+
const actions = {
|
|
284
|
+
intake: runIntake,
|
|
285
|
+
"packet-build": runPacketBuild,
|
|
286
|
+
"packet-build-batch": runPacketBuildBatch,
|
|
287
|
+
"auditor-prompt": runAuditorPrompt,
|
|
288
|
+
"result-ingest": runResultIngest,
|
|
289
|
+
"ledger-validate": runLedgerValidate,
|
|
290
|
+
finalize: runFinalize,
|
|
291
|
+
"wave-plan": runWavePlan,
|
|
292
|
+
"fix-topic": runFixTopic,
|
|
293
|
+
};
|
|
294
|
+
return emitResult(await actions[parsedAction.action](projectRoot, options), options.json);
|
|
295
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { runAuditSweep } from "./audit-sweep.mjs";
|
|
2
|
+
import { runSweepDesign } from "./sweep-design.mjs";
|
|
3
|
+
import { localize } from "../lib/ui.mjs";
|
|
4
|
+
|
|
5
|
+
export async function runSweep(args) {
|
|
6
|
+
const [command] = args;
|
|
7
|
+
const rest = args.slice(1);
|
|
8
|
+
|
|
9
|
+
if (command === "audit") {
|
|
10
|
+
return runAuditSweep(rest);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (command === "design") {
|
|
14
|
+
return runSweepDesign(rest);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
process.stderr.write(localize(
|
|
18
|
+
"nimicoding sweep refused: expected `audit` or `design`.\n",
|
|
19
|
+
"nimicoding sweep 已拒绝:需要使用 `audit` 或 `design`。\n",
|
|
20
|
+
));
|
|
21
|
+
return 2;
|
|
22
|
+
}
|