@nimiplatform/nimi-coding 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/CODE_OF_CONDUCT.md +28 -0
  3. package/CONTRIBUTING.md +45 -0
  4. package/README.md +371 -344
  5. package/README.zh-CN.md +307 -0
  6. package/SECURITY.md +26 -0
  7. package/adapters/oh-my-codex/README.md +8 -9
  8. package/cli/commands/audit-sweep.mjs +10 -10
  9. package/cli/commands/classify-spec-tree.mjs +5 -0
  10. package/cli/commands/closeout.mjs +3 -0
  11. package/cli/commands/generate-spec-derived-docs.mjs +20 -0
  12. package/cli/commands/generate-spec-migration-plan.mjs +30 -0
  13. package/cli/commands/start.mjs +5 -1
  14. package/cli/commands/surface-validator-command.mjs +49 -0
  15. package/cli/commands/sweep-design.mjs +295 -0
  16. package/cli/commands/sweep.mjs +22 -0
  17. package/cli/commands/sync.mjs +132 -0
  18. package/cli/commands/topic-formatters.mjs +8 -8
  19. package/cli/commands/validate-ai-governance.mjs +167 -46
  20. package/cli/commands/validate-domain-admission.mjs +5 -0
  21. package/cli/commands/validate-guidance-bodies.mjs +5 -0
  22. package/cli/commands/validate-placement.mjs +5 -0
  23. package/cli/commands/validate-projection-edges.mjs +5 -0
  24. package/cli/commands/validate-spec-audit.mjs +5 -1
  25. package/cli/commands/validate-table-family.mjs +5 -0
  26. package/cli/commands/validate-tracked-output-admission.mjs +5 -0
  27. package/cli/constants.mjs +5 -49
  28. package/cli/help.mjs +33 -11
  29. package/cli/index.mjs +20 -2
  30. package/cli/lib/audit-sweep-runtime/admissions.mjs +38 -29
  31. package/cli/lib/audit-sweep-runtime/audit-validity.mjs +8 -0
  32. package/cli/lib/audit-sweep-runtime/chunks.mjs +11 -11
  33. package/cli/lib/audit-sweep-runtime/closeout.mjs +8 -8
  34. package/cli/lib/audit-sweep-runtime/codex-auditor-evidence.mjs +3 -3
  35. package/cli/lib/audit-sweep-runtime/codex-auditor.mjs +10 -10
  36. package/cli/lib/audit-sweep-runtime/common.mjs +7 -7
  37. package/cli/lib/audit-sweep-runtime/format.mjs +3 -3
  38. package/cli/lib/audit-sweep-runtime/ingest.mjs +8 -8
  39. package/cli/lib/audit-sweep-runtime/inventory-spec-chunks.mjs +24 -27
  40. package/cli/lib/audit-sweep-runtime/inventory.mjs +58 -18
  41. package/cli/lib/audit-sweep-runtime/ledger.mjs +1 -1
  42. package/cli/lib/audit-sweep-runtime/p0p1-profile.mjs +2 -2
  43. package/cli/lib/audit-sweep-runtime/remediation.mjs +6 -6
  44. package/cli/lib/audit-sweep-runtime/rerun.mjs +6 -6
  45. package/cli/lib/audit-sweep-runtime/status.mjs +1 -1
  46. package/cli/lib/audit-sweep-runtime/validators.mjs +2 -2
  47. package/cli/lib/authority-convergence.mjs +397 -2
  48. package/cli/lib/blueprint-audit.mjs +5 -5
  49. package/cli/lib/closeout.mjs +126 -3
  50. package/cli/lib/contracts.mjs +21 -17
  51. package/cli/lib/handoff.mjs +29 -11
  52. package/cli/lib/high-risk-admission.mjs +60 -11
  53. package/cli/lib/high-risk-decision.mjs +31 -2
  54. package/cli/lib/high-risk-ingest.mjs +5 -1
  55. package/cli/lib/high-risk-review.mjs +5 -1
  56. package/cli/lib/internal/contracts-parse.mjs +195 -24
  57. package/cli/lib/internal/contracts-validators.mjs +3 -2
  58. package/cli/lib/internal/doctor-bootstrap-surface.mjs +82 -35
  59. package/cli/lib/internal/doctor-delegated-surface.mjs +1 -1
  60. package/cli/lib/internal/doctor-finalize.mjs +12 -8
  61. package/cli/lib/internal/doctor-inspectors.mjs +34 -1
  62. package/cli/lib/internal/governance/ai/ai-context-budget-core.mjs +74 -12
  63. package/cli/lib/internal/governance/ai/ai-structure-budget-core.mjs +24 -6
  64. package/cli/lib/internal/governance/ai/check-agents-freshness.mjs +18 -23
  65. package/cli/lib/internal/surface-taxonomy-validators.mjs +931 -0
  66. package/cli/lib/internal/validators-spec.mjs +229 -20
  67. package/cli/lib/sweep-design-runtime/common.mjs +246 -0
  68. package/cli/lib/sweep-design-runtime/engine.mjs +733 -0
  69. package/cli/lib/sweep-design-runtime/fix-topic.mjs +414 -0
  70. package/cli/lib/sweep-design-runtime/lifecycle.mjs +54 -0
  71. package/cli/lib/sweep-design-runtime/results.mjs +324 -0
  72. package/cli/lib/sweep-design.mjs +8 -0
  73. package/cli/lib/sync.mjs +143 -0
  74. package/cli/lib/topic-artifacts.mjs +186 -0
  75. package/cli/lib/topic-authority-coverage.mjs +73 -0
  76. package/cli/lib/topic-closeout.mjs +560 -0
  77. package/cli/lib/topic-common.mjs +404 -0
  78. package/cli/lib/topic-decisions.mjs +332 -0
  79. package/cli/lib/topic-draft-packets.mjs +126 -7
  80. package/cli/lib/topic-execution.mjs +515 -0
  81. package/cli/lib/topic-goal.mjs +112 -33
  82. package/cli/lib/topic-ledger.mjs +281 -0
  83. package/cli/lib/topic-lifecycle-artifacts.mjs +173 -0
  84. package/cli/lib/topic-root-validation.mjs +288 -0
  85. package/cli/lib/topic-runner-commands.mjs +174 -0
  86. package/cli/lib/topic-runner-deferral.mjs +532 -0
  87. package/cli/lib/topic-runner-stale-gates.mjs +114 -0
  88. package/cli/lib/topic-runner-validation.mjs +138 -0
  89. package/cli/lib/topic-runner.mjs +109 -154
  90. package/cli/lib/topic-scaffold.mjs +252 -0
  91. package/cli/lib/topic-waves.mjs +403 -0
  92. package/cli/lib/topic.mjs +81 -93
  93. package/cli/lib/value-helpers.mjs +6 -1
  94. package/cli/seeds/bootstrap.mjs +96 -20
  95. package/cli/seeds/seed-policy.yaml +67 -0
  96. package/config/bootstrap.yaml +1 -1
  97. package/config/skill-manifest.yaml +4 -2
  98. package/config/spec-generation-inputs.yaml +41 -19
  99. package/contracts/audit-remediation-map.schema.yaml +1 -0
  100. package/contracts/audit-sweep-result.yaml +4 -0
  101. package/contracts/domain-admission.schema.yaml +56 -0
  102. package/contracts/migration-inventory.schema.yaml +80 -0
  103. package/contracts/negative-fixtures.yaml +91 -0
  104. package/contracts/placement-contract.schema.yaml +163 -0
  105. package/contracts/projection-edge.schema.yaml +130 -0
  106. package/contracts/shared-enums.yaml +68 -0
  107. package/contracts/spec-generation-audit.schema.yaml +19 -4
  108. package/contracts/spec-generation-inputs.schema.yaml +130 -29
  109. package/contracts/spec-reconstruction-result.yaml +9 -5
  110. package/contracts/surface-taxonomy.schema.yaml +201 -0
  111. package/contracts/sweep-design-result.yaml +349 -0
  112. package/contracts/table-family.schema.yaml +121 -0
  113. package/contracts/topic-goal.schema.yaml +10 -1
  114. package/contracts/tracked-output-admission.schema.yaml +70 -0
  115. package/contracts/workflow-consumer.schema.yaml +112 -0
  116. package/methodology/audit-sweep-p0p1-recall.yaml +1 -1
  117. package/methodology/spec-reconstruction.yaml +53 -30
  118. package/package.json +19 -4
  119. package/spec/_meta/command-gating-matrix.yaml +33 -0
  120. package/spec/_meta/generate-drift-migration-checklist.yaml +44 -62
  121. package/spec/_meta/governance-routing-cutover-checklist.yaml +3 -3
  122. package/spec/_meta/phase2-impacted-surface-matrix.yaml +14 -14
  123. package/spec/_meta/spec-authority-cutover-readiness.yaml +3 -5
  124. package/spec/_meta/spec-tree-model.yaml +104 -36
  125. package/spec/bootstrap-state.yaml +36 -36
  126. package/spec/product-scope.yaml +13 -10
@@ -3,7 +3,10 @@ import { loadGovernanceConfig, requireProfile } from "../lib/internal/governance
3
3
  import { evaluateAiContextBudget, formatBytes } from "../lib/internal/governance/ai/ai-context-budget-core.mjs";
4
4
  import { evaluateAiStructureBudget } from "../lib/internal/governance/ai/ai-structure-budget-core.mjs";
5
5
  import { evaluateHighRiskDocMetadata } from "../lib/internal/governance/ai/check-high-risk-doc-metadata-core.mjs";
6
- import { runAgentsFreshnessCheck } from "../lib/internal/governance/ai/check-agents-freshness.mjs";
6
+ import {
7
+ evaluateAgentsFreshnessCheck,
8
+ runAgentsFreshnessCheck,
9
+ } from "../lib/internal/governance/ai/check-agents-freshness.mjs";
7
10
 
8
11
  const SCOPES = new Set([
9
12
  "agents-freshness",
@@ -16,6 +19,7 @@ function parseOptions(args) {
16
19
  const options = {
17
20
  profile: null,
18
21
  scope: "all",
22
+ json: false,
19
23
  };
20
24
 
21
25
  for (let index = 0; index < args.length; index += 1) {
@@ -41,6 +45,11 @@ function parseOptions(args) {
41
45
  continue;
42
46
  }
43
47
 
48
+ if (arg === "--json") {
49
+ options.json = true;
50
+ continue;
51
+ }
52
+
44
53
  return {
45
54
  ok: false,
46
55
  error: `nimicoding validate-ai-governance refused: unknown option ${arg}.\n`,
@@ -57,6 +66,63 @@ function parseOptions(args) {
57
66
  return { ok: true, options };
58
67
  }
59
68
 
69
+ function writeJson(payload) {
70
+ process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
71
+ }
72
+
73
+ function buildContextBudgetReport(governanceConfig) {
74
+ const report = evaluateAiContextBudget({
75
+ cwd: process.cwd(),
76
+ config: governanceConfig.aiGovernance.contextBudget,
77
+ configPathLabel: ".nimi/config/governance.yaml#ai_governance.context_budget",
78
+ });
79
+ const exitCode = report.invalidWaivers.length > 0 || report.expiredWaivers.length > 0 || report.errors.length > 0
80
+ ? 1
81
+ : 0;
82
+ return { exitCode, report };
83
+ }
84
+
85
+ function buildStructureBudgetReport(governanceConfig) {
86
+ const report = evaluateAiStructureBudget({
87
+ cwd: process.cwd(),
88
+ config: governanceConfig.aiGovernance.structureBudget,
89
+ configPathLabel: ".nimi/config/governance.yaml#ai_governance.structure_budget",
90
+ });
91
+ const exitCode = report.errors.length > 0 || report.expiredWaivers.length > 0 ? 1 : 0;
92
+ return { exitCode, report };
93
+ }
94
+
95
+ function buildHighRiskDocMetadataReport(governanceConfig) {
96
+ const config = governanceConfig.aiGovernance.highRiskDocMetadata;
97
+ const report = evaluateHighRiskDocMetadata({
98
+ repoRoot: process.cwd(),
99
+ docRoots: Array.isArray(config.doc_roots) ? config.doc_roots : [".local"],
100
+ exemptPaths: Array.isArray(config.exempt_paths) ? config.exempt_paths : [],
101
+ namePatterns: Array.isArray(config.name_patterns) ? config.name_patterns : [],
102
+ requiredMetadataKeys: Array.isArray(config.required_metadata_keys)
103
+ ? config.required_metadata_keys
104
+ : [],
105
+ });
106
+ return {
107
+ exitCode: report.failures.length > 0 ? 1 : 0,
108
+ report: {
109
+ ...report,
110
+ exemptPaths: [...report.exemptPaths],
111
+ },
112
+ };
113
+ }
114
+
115
+ function buildAgentsFreshnessReport(governanceConfig) {
116
+ const report = evaluateAgentsFreshnessCheck({
117
+ projectRoot: process.cwd(),
118
+ config: governanceConfig.aiGovernance.agentsFreshness,
119
+ });
120
+ return {
121
+ exitCode: report.failures.length > 0 ? 1 : 0,
122
+ report,
123
+ };
124
+ }
125
+
60
126
  function formatStructureRow(row) {
61
127
  if (row.check === "depth") {
62
128
  return `${row.file} [rule=${row.ruleId}] depth=${row.depth} base=${row.depthBase} subject=${row.depthSubject} (threshold warn>=${row.warningDepth} error>=${row.errorDepth})`;
@@ -64,42 +130,37 @@ function formatStructureRow(row) {
64
130
  return `${row.file} [rule=${row.ruleId}] basename=${row.basename} (forwarding shell outside allowed basename set)`;
65
131
  }
66
132
 
133
+ function formatContextBudgetRow(row, thresholdPrefix) {
134
+ return `${row.file} [${row.profile}] lines=${row.lines} bytes=${formatBytes(row.bytes)} max-line=${formatBytes(row.maxLineBytes)} avg-line=${formatBytes(Math.round(row.averageLineBytes))} `
135
+ + `(${thresholdPrefix} lines>=${row[`${thresholdPrefix}Lines`] ?? "-"} bytes>=${row[`${thresholdPrefix}Bytes`] ?? "-"} max-line>=${row[`${thresholdPrefix}MaxLineBytes`] ?? "-"} avg-line>=${row[`${thresholdPrefix}AverageLineBytes`] ?? "-"})`;
136
+ }
137
+
67
138
  async function runContextBudget(governanceConfig) {
68
- const report = evaluateAiContextBudget({
69
- cwd: process.cwd(),
70
- config: governanceConfig.aiGovernance.contextBudget,
71
- configPathLabel: ".nimi/config/governance.yaml#ai_governance.context_budget",
72
- });
139
+ const { exitCode, report } = buildContextBudgetReport(governanceConfig);
73
140
 
74
141
  process.stdout.write(`ai-context-budget: config=${report.configPath}\n`);
75
142
  process.stdout.write(`ai-context-budget: tracked=${report.totalTrackedFiles}, analyzed=${report.analyzedFiles}\n`);
76
143
 
77
144
  for (const row of report.warnings) {
78
- process.stderr.write(
79
- `WARN: ${row.file} [${row.profile}] lines=${row.lines} bytes=${formatBytes(row.bytes)} (threshold warn lines>=${row.warningLines ?? "-"} bytes>=${row.warningBytes ?? "-"})\n`,
80
- );
145
+ process.stderr.write(`WARN: ${formatContextBudgetRow(row, "warning")}\n`);
81
146
  }
82
147
  for (const row of report.waivedErrors) {
83
148
  const until = row.waiver?.until ? row.waiver.until.toISOString().slice(0, 10) : "n/a";
84
149
  const reason = row.waiver?.reason || "no reason";
85
- process.stderr.write(
86
- `WARN: WAIVED error for ${row.file} [${row.profile}] lines=${row.lines} bytes=${formatBytes(row.bytes)} until=${until} reason=${reason}\n`,
87
- );
150
+ process.stderr.write(`WARN: WAIVED error for ${formatContextBudgetRow(row, "error")} until=${until} reason=${reason}\n`);
88
151
  }
89
152
  for (const row of report.expiredWaivers) {
90
- process.stderr.write(`ERROR: waiver expired for ${row.file} [${row.profile}] (lines=${row.lines} bytes=${formatBytes(row.bytes)})\n`);
153
+ process.stderr.write(`ERROR: waiver expired for ${formatContextBudgetRow(row, "error")}\n`);
91
154
  }
92
155
  for (const row of report.invalidWaivers) {
93
156
  process.stderr.write(`ERROR: invalid waiver for ${row.file}: ${row.detail}\n`);
94
157
  }
95
158
  for (const row of report.errors) {
96
- process.stderr.write(
97
- `ERROR: ${row.file} [${row.profile}] lines=${row.lines} bytes=${formatBytes(row.bytes)} (threshold error lines>=${row.errorLines ?? "-"} bytes>=${row.errorBytes ?? "-"})\n`,
98
- );
159
+ process.stderr.write(`ERROR: ${formatContextBudgetRow(row, "error")}\n`);
99
160
  }
100
161
 
101
- if (report.invalidWaivers.length > 0 || report.expiredWaivers.length > 0 || report.errors.length > 0) {
102
- return 1;
162
+ if (exitCode !== 0) {
163
+ return exitCode;
103
164
  }
104
165
 
105
166
  process.stdout.write("ai-context-budget: OK\n");
@@ -107,11 +168,7 @@ async function runContextBudget(governanceConfig) {
107
168
  }
108
169
 
109
170
  async function runStructureBudget(governanceConfig) {
110
- const report = evaluateAiStructureBudget({
111
- cwd: process.cwd(),
112
- config: governanceConfig.aiGovernance.structureBudget,
113
- configPathLabel: ".nimi/config/governance.yaml#ai_governance.structure_budget",
114
- });
171
+ const { exitCode, report } = buildStructureBudgetReport(governanceConfig);
115
172
 
116
173
  process.stdout.write(`ai-structure-budget: config=${report.configPath}\n`);
117
174
  process.stdout.write(`ai-structure-budget: tracked=${report.totalTrackedFiles}, analyzed=${report.analyzedFiles}\n`);
@@ -129,8 +186,8 @@ async function runStructureBudget(governanceConfig) {
129
186
  for (const row of report.errors) {
130
187
  process.stderr.write(`ERROR: ${formatStructureRow(row)}\n`);
131
188
  }
132
- if (report.errors.length > 0 || report.expiredWaivers.length > 0) {
133
- return 1;
189
+ if (exitCode !== 0) {
190
+ return exitCode;
134
191
  }
135
192
 
136
193
  process.stdout.write("ai-structure-budget: OK\n");
@@ -138,51 +195,90 @@ async function runStructureBudget(governanceConfig) {
138
195
  }
139
196
 
140
197
  async function runHighRiskDocMetadata(governanceConfig) {
141
- const config = governanceConfig.aiGovernance.highRiskDocMetadata;
142
- const report = evaluateHighRiskDocMetadata({
143
- repoRoot: process.cwd(),
144
- docRoots: Array.isArray(config.doc_roots) ? config.doc_roots : [".local"],
145
- exemptPaths: Array.isArray(config.exempt_paths) ? config.exempt_paths : [],
146
- namePatterns: Array.isArray(config.name_patterns) ? config.name_patterns : [],
147
- requiredMetadataKeys: Array.isArray(config.required_metadata_keys)
148
- ? config.required_metadata_keys
149
- : [],
150
- });
198
+ const { exitCode, report } = buildHighRiskDocMetadataReport(governanceConfig);
151
199
 
152
- if (report.failures.length > 0) {
200
+ if (exitCode !== 0) {
153
201
  process.stderr.write("high-risk doc metadata check failed:\n");
154
202
  for (const failure of report.failures) {
155
203
  process.stderr.write(`- ${failure}\n`);
156
204
  }
157
- return 1;
205
+ return exitCode;
158
206
  }
159
207
 
160
208
  process.stdout.write(`high-risk doc metadata check passed (${report.scanned.length} file(s) scanned)\n`);
161
209
  return 0;
162
210
  }
163
211
 
212
+ function runJsonScope(governanceConfig, scope) {
213
+ if (scope === "agents-freshness") {
214
+ return buildAgentsFreshnessReport(governanceConfig);
215
+ }
216
+ if (scope === "context-budget") {
217
+ return buildContextBudgetReport(governanceConfig);
218
+ }
219
+ if (scope === "structure-budget") {
220
+ return buildStructureBudgetReport(governanceConfig);
221
+ }
222
+ if (scope === "high-risk-doc-metadata") {
223
+ return buildHighRiskDocMetadataReport(governanceConfig);
224
+ }
225
+ return {
226
+ exitCode: 2,
227
+ report: { error: `unsupported scope: ${scope}` },
228
+ };
229
+ }
230
+
164
231
  export async function runValidateAiGovernance(args) {
232
+ const wantsJson = args.includes("--json");
165
233
  const parsed = parseOptions(args);
166
234
  if (!parsed.ok) {
167
- process.stderr.write(localize(parsed.error, parsed.error));
235
+ if (wantsJson) {
236
+ writeJson({
237
+ ok: false,
238
+ command: "validate-ai-governance",
239
+ error: parsed.error.trim(),
240
+ });
241
+ } else {
242
+ process.stderr.write(localize(parsed.error, parsed.error));
243
+ }
168
244
  return 2;
169
245
  }
170
246
 
171
247
  const governance = await loadGovernanceConfig(process.cwd());
172
248
  if (!governance.ok) {
173
- process.stderr.write(localize(
174
- `nimicoding validate-ai-governance refused: ${governance.reason} at ${governance.path}.\n`,
175
- `nimicoding validate-ai-governance 已拒绝:${governance.path} 的治理配置不可用。\n`,
176
- ));
249
+ const error = `nimicoding validate-ai-governance refused: ${governance.reason} at ${governance.path}.`;
250
+ if (parsed.options.json) {
251
+ writeJson({
252
+ ok: false,
253
+ command: "validate-ai-governance",
254
+ error,
255
+ governancePath: governance.path,
256
+ });
257
+ } else {
258
+ process.stderr.write(localize(
259
+ `${error}\n`,
260
+ `nimicoding validate-ai-governance 已拒绝:${governance.path} 的治理配置不可用。\n`,
261
+ ));
262
+ }
177
263
  return 2;
178
264
  }
179
265
 
180
266
  const profileCheck = requireProfile(governance.config, parsed.options.profile);
181
267
  if (!profileCheck.ok) {
182
- process.stderr.write(localize(
183
- `nimicoding validate-ai-governance refused: ${profileCheck.error}.\n`,
184
- `nimicoding validate-ai-governance 已拒绝:${profileCheck.error}。\n`,
185
- ));
268
+ const error = `nimicoding validate-ai-governance refused: ${profileCheck.error}.`;
269
+ if (parsed.options.json) {
270
+ writeJson({
271
+ ok: false,
272
+ command: "validate-ai-governance",
273
+ error,
274
+ profile: profileCheck.profile,
275
+ });
276
+ } else {
277
+ process.stderr.write(localize(
278
+ `${error}\n`,
279
+ `nimicoding validate-ai-governance 已拒绝:${profileCheck.error}。\n`,
280
+ ));
281
+ }
186
282
  return 2;
187
283
  }
188
284
 
@@ -190,6 +286,31 @@ export async function runValidateAiGovernance(args) {
190
286
  ? ["agents-freshness", "context-budget", "structure-budget", "high-risk-doc-metadata"]
191
287
  : [parsed.options.scope];
192
288
 
289
+ if (parsed.options.json) {
290
+ const results = [];
291
+ let exitCode = 0;
292
+ for (const scope of scopes) {
293
+ const result = runJsonScope(governance.config, scope);
294
+ if (exitCode === 0 && result.exitCode !== 0) {
295
+ exitCode = result.exitCode;
296
+ }
297
+ results.push({
298
+ scope,
299
+ ok: result.exitCode === 0,
300
+ exitCode: result.exitCode,
301
+ report: result.report,
302
+ });
303
+ }
304
+ writeJson({
305
+ ok: exitCode === 0,
306
+ command: "validate-ai-governance",
307
+ profile: profileCheck.profile,
308
+ scope: parsed.options.scope,
309
+ scopes: results,
310
+ });
311
+ return exitCode;
312
+ }
313
+
193
314
  for (const scope of scopes) {
194
315
  let exitCode = 0;
195
316
  if (scope === "agents-freshness") {
@@ -0,0 +1,5 @@
1
+ import { runSurfaceValidatorCommand } from "./surface-validator-command.mjs";
2
+
3
+ export function runValidateDomainAdmission(args) {
4
+ return runSurfaceValidatorCommand(args, "validate-domain-admission");
5
+ }
@@ -0,0 +1,5 @@
1
+ import { runSurfaceValidatorCommand } from "./surface-validator-command.mjs";
2
+
3
+ export function runValidateGuidanceBodies(args) {
4
+ return runSurfaceValidatorCommand(args, "validate-guidance-bodies");
5
+ }
@@ -0,0 +1,5 @@
1
+ import { runSurfaceValidatorCommand } from "./surface-validator-command.mjs";
2
+
3
+ export function runValidatePlacement(args) {
4
+ return runSurfaceValidatorCommand(args, "validate-placement");
5
+ }
@@ -0,0 +1,5 @@
1
+ import { runSurfaceValidatorCommand } from "./surface-validator-command.mjs";
2
+
3
+ export function runValidateProjectionEdges(args) {
4
+ return runSurfaceValidatorCommand(args, "validate-projection-edges");
5
+ }
@@ -1,11 +1,15 @@
1
1
  import path from "node:path";
2
2
 
3
3
  import { validateSpecAudit, buildValidatorCliReport } from "../lib/validators.mjs";
4
+ import { loadSpecGenerationInputsConfig } from "../lib/contracts.mjs";
4
5
  import { localize } from "../lib/ui.mjs";
5
6
 
6
7
  export async function runValidateSpecAudit(args) {
7
8
  const normalized = args[0] === "--" ? args.slice(1) : args;
8
- let targetPath = ".nimi/spec/_meta/spec-generation-audit.yaml";
9
+ const generationInputs = await loadSpecGenerationInputsConfig(process.cwd());
10
+ let targetPath = generationInputs.ok && generationInputs.mode === "class_filtered"
11
+ ? ".nimi/local/state/spec-generation/spec-generation-audit.yaml"
12
+ : ".nimi/spec/_meta/spec-generation-audit.yaml";
9
13
 
10
14
  if (normalized.length > 1) {
11
15
  process.stderr.write(localize(
@@ -0,0 +1,5 @@
1
+ import { runSurfaceValidatorCommand } from "./surface-validator-command.mjs";
2
+
3
+ export function runValidateTableFamily(args) {
4
+ return runSurfaceValidatorCommand(args, "validate-table-family");
5
+ }
@@ -0,0 +1,5 @@
1
+ import { runSurfaceValidatorCommand } from "./surface-validator-command.mjs";
2
+
3
+ export function runValidateTrackedOutputAdmission(args) {
4
+ return runSurfaceValidatorCommand(args, "validate-tracked-output-admission");
5
+ }
package/cli/constants.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export const VERSION = "0.1.0";
1
+ export const VERSION = "0.2.1";
2
2
  export const PACKAGE_NAME = "@nimiplatform/nimi-coding";
3
3
  export const BOOTSTRAP_CONTRACT_ID = "nimicoding.bootstrap";
4
4
  export const BOOTSTRAP_CONTRACT_VERSION = 1;
@@ -18,6 +18,8 @@ export const STANDALONE_COMPLETED_SURFACES = [
18
18
  "bootstrap",
19
19
  "doctor",
20
20
  "handoff",
21
+ "sweep_audit",
22
+ "sweep_design",
21
23
  "validators",
22
24
  "topic_lifecycle_report_methodology",
23
25
  "closeout",
@@ -51,6 +53,7 @@ export const CLAUDE_END = "<!-- nimicoding:managed:claude:end -->";
51
53
  export const SPEC_RECONSTRUCTION_RESULT_CONTRACT_REF = ".nimi/contracts/spec-reconstruction-result.yaml";
52
54
  export const DOC_SPEC_AUDIT_RESULT_CONTRACT_REF = ".nimi/contracts/doc-spec-audit-result.yaml";
53
55
  export const AUDIT_SWEEP_RESULT_CONTRACT_REF = ".nimi/contracts/audit-sweep-result.yaml";
56
+ export const SWEEP_DESIGN_RESULT_CONTRACT_REF = ".nimi/contracts/sweep-design-result.yaml";
54
57
  export const AUDIT_PLAN_SCHEMA_REF = ".nimi/contracts/audit-plan.schema.yaml";
55
58
  export const AUDIT_CHUNK_SCHEMA_REF = ".nimi/contracts/audit-chunk.schema.yaml";
56
59
  export const AUDIT_FINDING_SCHEMA_REF = ".nimi/contracts/audit-finding.schema.yaml";
@@ -260,7 +263,7 @@ export const DOC_SPEC_AUDIT_DEFAULT_COMPARED_PATHS = [
260
263
  ];
261
264
 
262
265
  export const SPEC_TREE_MODEL_REF = ".nimi/spec/_meta/spec-tree-model.yaml";
263
- export const BLUEPRINT_REFERENCE_REF = ".nimi/spec/_meta/blueprint-reference.yaml";
266
+ export const BLUEPRINT_REFERENCE_REF = ".nimi/local/state/spec-generation/blueprint-reference.yaml";
264
267
  export const COMMAND_GATING_MATRIX_REF = ".nimi/spec/_meta/command-gating-matrix.yaml";
265
268
  export const GENERATE_DRIFT_MIGRATION_CHECKLIST_REF = ".nimi/spec/_meta/generate-drift-migration-checklist.yaml";
266
269
  export const GOVERNANCE_ROUTING_CUTOVER_CHECKLIST_REF = ".nimi/spec/_meta/governance-routing-cutover-checklist.yaml";
@@ -277,53 +280,6 @@ export const SKILL_RESULT_CONTRACT_REFS = {
277
280
  high_risk_execution: HIGH_RISK_EXECUTION_RESULT_CONTRACT_REF,
278
281
  };
279
282
 
280
- export const REQUIRED_BOOTSTRAP_FILES = [
281
- ".nimi/methodology/core.yaml",
282
- ".nimi/methodology/spec-reconstruction.yaml",
283
- ".nimi/methodology/skill-runtime.yaml",
284
- ".nimi/methodology/skill-installer-result.yaml",
285
- ".nimi/methodology/skill-installer-summary-projection.yaml",
286
- ".nimi/methodology/skill-exchange-projection.yaml",
287
- ".nimi/methodology/skill-handoff.yaml",
288
- SPEC_TREE_MODEL_REF,
289
- COMMAND_GATING_MATRIX_REF,
290
- GENERATE_DRIFT_MIGRATION_CHECKLIST_REF,
291
- GOVERNANCE_ROUTING_CUTOVER_CHECKLIST_REF,
292
- PHASE2_IMPACTED_SURFACE_MATRIX_REF,
293
- ".nimi/spec/product-scope.yaml",
294
- ".nimi/spec/bootstrap-state.yaml",
295
- ".nimi/config/bootstrap.yaml",
296
- ".nimi/config/skills.yaml",
297
- ".nimi/config/skill-manifest.yaml",
298
- SPEC_GENERATION_INPUTS_REF,
299
- ".nimi/config/host-profile.yaml",
300
- HOST_ADAPTER_CONFIG_REF,
301
- EXTERNAL_EXECUTION_ARTIFACTS_CONFIG_REF,
302
- AUDIT_EXECUTION_ARTIFACTS_CONFIG_REF,
303
- ".nimi/config/skill-installer.yaml",
304
- ".nimi/config/installer-evidence.yaml",
305
- SPEC_RECONSTRUCTION_RESULT_CONTRACT_REF,
306
- DOC_SPEC_AUDIT_RESULT_CONTRACT_REF,
307
- AUDIT_SWEEP_RESULT_CONTRACT_REF,
308
- AUDIT_PLAN_SCHEMA_REF,
309
- AUDIT_CHUNK_SCHEMA_REF,
310
- AUDIT_FINDING_SCHEMA_REF,
311
- AUDIT_LEDGER_SCHEMA_REF,
312
- AUDIT_REMEDIATION_MAP_SCHEMA_REF,
313
- AUDIT_RERUN_SCHEMA_REF,
314
- AUDIT_CLOSEOUT_SCHEMA_REF,
315
- HIGH_RISK_EXECUTION_RESULT_CONTRACT_REF,
316
- HIGH_RISK_ADMISSION_CONTRACT_REF,
317
- SPEC_GENERATION_INPUTS_CONTRACT_REF,
318
- SPEC_GENERATION_AUDIT_CONTRACT_REF,
319
- EXTERNAL_HOST_COMPATIBILITY_CONTRACT_REF,
320
- EXECUTION_PACKET_SCHEMA_REF,
321
- ORCHESTRATION_STATE_SCHEMA_REF,
322
- PROMPT_SCHEMA_REF,
323
- WORKER_OUTPUT_SCHEMA_REF,
324
- ACCEPTANCE_SCHEMA_REF,
325
- ];
326
-
327
283
  export const REQUIRED_LOCAL_DIRS = [".nimi/local", ".nimi/cache"];
328
284
 
329
285
  export const REQUIRED_BOOTSTRAP_DIRS = [
package/cli/help.mjs CHANGED
@@ -18,6 +18,7 @@ export function helpText() {
18
18
  ` ${styleCommand("nimicoding start --host <generic|codex|claude|oh-my-codex>")}`,
19
19
  ` ${styleCommand("nimicoding clear")}`,
20
20
  ` ${styleCommand("nimicoding clear --yes")}`,
21
+ ` ${styleCommand("nimicoding sync [--apply|--check|--dry-run] [--json]")}`,
21
22
  ` ${styleCommand("nimicoding topic create <slug> --justification <text> [--title <text>] [--json]")}`,
22
23
  ` ${styleCommand("nimicoding topic status [<topic-id>|<topic-path>] [--json]")}`,
23
24
  ` ${styleCommand("nimicoding topic run-next-step <topic-id> [--json]")}`,
@@ -49,17 +50,26 @@ export function helpText() {
49
50
  ` ${styleCommand("nimicoding handoff --skill <skill-id>")}`,
50
51
  ` ${styleCommand("nimicoding handoff --skill <skill-id> --json")}`,
51
52
  ` ${styleCommand("nimicoding handoff --skill <skill-id> --prompt")}`,
52
- ` ${styleCommand("nimicoding audit-sweep plan --root <dir> [--criteria <csv>] [--exclude <csv>] [--max-files <n>] [--sweep-id <id>] [--json]")}`,
53
- ` ${styleCommand("nimicoding audit-sweep chunk dispatch --sweep-id <id> --chunk-id <chunk-id> --dispatched-at <iso8601> [--auditor <id>] [--json]")}`,
54
- ` ${styleCommand("nimicoding audit-sweep chunk audit-codex --sweep-id <id> --chunk-id <chunk-id> --dispatched-at <iso8601> --verified-at <iso8601> --reviewed-at <iso8601> [--from-raw-output <ref>] [--timeout-ms <ms>] [--json]")}`,
55
- ` ${styleCommand("nimicoding audit-sweep chunk ingest --sweep-id <id> --chunk-id <chunk-id> --from <json> --verified-at <iso8601> [--json]")}`,
56
- ` ${styleCommand("nimicoding audit-sweep chunk review --sweep-id <id> --chunk-id <chunk-id> --verdict <pass|fail> --reviewed-at <iso8601> [--summary <text>] [--json]")}`,
57
- ` ${styleCommand("nimicoding audit-sweep chunk skip --sweep-id <id> --chunk-id <chunk-id> --reason <text> --skipped-at <iso8601> [--json]")}`,
58
- ` ${styleCommand("nimicoding audit-sweep ledger build --sweep-id <id> [--verified-at <iso8601>] [--json]")}`,
59
- ` ${styleCommand("nimicoding audit-sweep remediation-map build --sweep-id <id> [--max-findings <n>] [--verified-at <iso8601>] [--json]")}`,
60
- ` ${styleCommand("nimicoding audit-sweep finding resolve --sweep-id <id> --finding-id <id> --disposition <remediated|accepted-risk|false-positive|deferred-backlog> --from <json> --verified-at <iso8601> [--json]")}`,
61
- ` ${styleCommand("nimicoding audit-sweep closeout summary --sweep-id <id> --verified-at <iso8601> [--json]")}`,
62
- ` ${styleCommand("nimicoding audit-sweep status --sweep-id <id> [--json]")}`,
53
+ ` ${styleCommand("nimicoding sweep audit plan --root <dir> [--criteria <csv>] [--exclude <csv>] [--max-files <n>] [--sweep-id <id>] [--json]")}`,
54
+ ` ${styleCommand("nimicoding sweep audit chunk dispatch --sweep-id <id> --chunk-id <chunk-id> --dispatched-at <iso8601> [--auditor <id>] [--json]")}`,
55
+ ` ${styleCommand("nimicoding sweep audit chunk audit-codex --sweep-id <id> --chunk-id <chunk-id> --dispatched-at <iso8601> --verified-at <iso8601> --reviewed-at <iso8601> [--from-raw-output <ref>] [--timeout-ms <ms>] [--json]")}`,
56
+ ` ${styleCommand("nimicoding sweep audit chunk ingest --sweep-id <id> --chunk-id <chunk-id> --from <json> --verified-at <iso8601> [--json]")}`,
57
+ ` ${styleCommand("nimicoding sweep audit chunk review --sweep-id <id> --chunk-id <chunk-id> --verdict <pass|fail> --reviewed-at <iso8601> [--summary <text>] [--json]")}`,
58
+ ` ${styleCommand("nimicoding sweep audit chunk skip --sweep-id <id> --chunk-id <chunk-id> --reason <text> --skipped-at <iso8601> [--json]")}`,
59
+ ` ${styleCommand("nimicoding sweep audit ledger build --sweep-id <id> [--verified-at <iso8601>] [--json]")}`,
60
+ ` ${styleCommand("nimicoding sweep audit remediation-map build --sweep-id <id> [--max-findings <n>] [--verified-at <iso8601>] [--json]")}`,
61
+ ` ${styleCommand("nimicoding sweep audit finding resolve --sweep-id <id> --finding-id <id> --disposition <remediated|accepted-risk|false-positive|deferred-backlog> --from <json> --verified-at <iso8601> [--json]")}`,
62
+ ` ${styleCommand("nimicoding sweep audit closeout summary --sweep-id <id> --verified-at <iso8601> [--json]")}`,
63
+ ` ${styleCommand("nimicoding sweep audit status --sweep-id <id> [--json]")}`,
64
+ ` ${styleCommand("nimicoding sweep design intake --sweep-id <id> [--run-id <id>] [--json]")}`,
65
+ ` ${styleCommand("nimicoding sweep design packet-build --run-id <id> --packet-id <id> (--finding-id <id>|--finding-ids <csv>) [--explicit-question <text>] [--prior-design-state-refs <csv>] [--prior-design-state-marker <state>] [--current-cluster-refs <csv>] [--current-wave-refs <csv>] [--authority-only] [--json]")}`,
66
+ ` ${styleCommand("nimicoding sweep design packet-build-batch --run-id <id> --batch-size <n> [--finding-ids <csv>] [--packet-prefix <id>] [--manifest-id <id>] [--explicit-question <text>] [--json]")}`,
67
+ ` ${styleCommand("nimicoding sweep design auditor-prompt --run-id <id> --packet-id <id> [--json]")}`,
68
+ ` ${styleCommand("nimicoding sweep design result-ingest --run-id <id> --from <yaml> [--mode <focused|all>] [--json]")}`,
69
+ ` ${styleCommand("nimicoding sweep design ledger-validate --run-id <id> [--json]")}`,
70
+ ` ${styleCommand("nimicoding sweep design finalize --run-id <id> [--json]")}`,
71
+ ` ${styleCommand("nimicoding sweep design wave-plan --run-id <id> --topic-id <id> [--json]")}`,
72
+ ` ${styleCommand("nimicoding sweep design fix-topic --run-id <id> [--slug <slug>] [--title <title>] [--admit-first-wave|--admit-wave-id <id>] [--json]")}`,
63
73
  ` ${styleCommand("nimicoding admit-high-risk-decision --from <json> --admitted-at <iso8601> [--json] [--write-spec]")}`,
64
74
  ` ${styleCommand("nimicoding closeout --skill <skill-id> --outcome <completed|blocked|failed> --verified-at <iso8601>")}`,
65
75
  ` ${styleCommand("nimicoding closeout --skill <skill-id> --outcome <completed|blocked|failed> --verified-at <iso8601> --json")}`,
@@ -73,6 +83,14 @@ export function helpText() {
73
83
  ` ${styleCommand("nimicoding validate-spec-governance --profile <profile-id> --scope <all|host-defined-scope>")}`,
74
84
  ` ${styleCommand("nimicoding validate-spec-audit [.nimi/spec/_meta/spec-generation-audit.yaml]")}`,
75
85
  ` ${styleCommand("nimicoding validate-spec-tree [.nimi/spec]")}`,
86
+ ` ${styleCommand("nimicoding classify-spec-tree --profile <profile-id> --root .nimi/spec [--emit <path>] [--json]")}`,
87
+ ` ${styleCommand("nimicoding generate-spec-migration-plan --profile <profile-id> --root .nimi/spec --emit .nimi/local/state/spec-surface/migration-plan.json [--json]")}`,
88
+ ` ${styleCommand("nimicoding validate-placement --profile <profile-id> --root .nimi/spec [--json]")}`,
89
+ ` ${styleCommand("nimicoding validate-table-family --profile <profile-id> --root .nimi/spec [--json]")}`,
90
+ ` ${styleCommand("nimicoding validate-projection-edges --profile <profile-id> --root .nimi/spec [--json]")}`,
91
+ ` ${styleCommand("nimicoding validate-guidance-bodies --profile <profile-id> --root .nimi/spec [--json]")}`,
92
+ ` ${styleCommand("nimicoding validate-domain-admission --profile <profile-id> --root .nimi/spec [--json]")}`,
93
+ ` ${styleCommand("nimicoding validate-tracked-output-admission --profile <profile-id> --root .nimi/spec [--json]")}`,
76
94
  ` ${styleCommand("nimicoding generate-spec-derived-docs --profile <profile-id> --scope <all|host-defined-scope> [--check]")}`,
77
95
  ` ${styleCommand("nimicoding validate-ai-governance --profile <profile-id> --scope <all|agents-freshness|context-budget|structure-budget|high-risk-doc-metadata>")}`,
78
96
  ` ${styleCommand("nimicoding validate-prompt <path>")}`,
@@ -108,6 +126,10 @@ export function helpText() {
108
126
  " - `nimicoding clear` does not remove .nimi/spec, .nimi/local, or .nimi/cache for you",
109
127
  " - `nimicoding clear` 不会替你移除 .nimi/spec、.nimi/local 或 .nimi/cache",
110
128
  )),
129
+ styleMuted(localize(
130
+ " - `nimicoding sync` is the package-owned seed projection contract: --apply rewrites drifted package_canonical files and seeds missing entries; --check exits non-zero on package_canonical drift or any missing seed; host-owned seed entries are seeded once and never overwritten",
131
+ " - `nimicoding sync` 是 package 拥有的 seed 投影契约:--apply 会刷新 drifted package_canonical 文件并补齐缺失 seed;--check 在 package_canonical drift 或 seed 缺失时退出非零;host-owned seed 条目仅初始化一次,之后永不覆盖",
132
+ )),
111
133
  styleMuted(localize(
112
134
  " - `nimicoding doctor` shows the user-facing summary; add `--verbose` for internal contract detail",
113
135
  " - `nimicoding doctor` 默认显示用户视图;加 `--verbose` 可查看内部契约细节",
package/cli/index.mjs CHANGED
@@ -2,23 +2,32 @@ import { runBlueprintAudit } from "./commands/blueprint-audit.mjs";
2
2
  import { runClear } from "./commands/clear.mjs";
3
3
  import { runCloseout } from "./commands/closeout.mjs";
4
4
  import { runAdmitHighRiskDecision } from "./commands/admit-high-risk-decision.mjs";
5
- import { runAuditSweep } from "./commands/audit-sweep.mjs";
5
+ import { runSweep } from "./commands/sweep.mjs";
6
6
  import { runDecideHighRiskExecution } from "./commands/decide-high-risk-execution.mjs";
7
7
  import { runDoctor } from "./commands/doctor.mjs";
8
8
  import { runHandoff } from "./commands/handoff.mjs";
9
9
  import { runIngestHighRiskExecution } from "./commands/ingest-high-risk-execution.mjs";
10
10
  import { runReviewHighRiskExecution } from "./commands/review-high-risk-execution.mjs";
11
11
  import { runStart } from "./commands/start.mjs";
12
+ import { runSync } from "./commands/sync.mjs";
12
13
  import { runTopic } from "./commands/topic.mjs";
13
14
  import { runTopicRunnerCommand } from "./commands/topic-runner.mjs";
14
15
  import { runValidateAcceptance } from "./commands/validate-acceptance.mjs";
15
16
  import { runGenerateSpecDerivedDocs } from "./commands/generate-spec-derived-docs.mjs";
17
+ import { runGenerateSpecMigrationPlan } from "./commands/generate-spec-migration-plan.mjs";
18
+ import { runClassifySpecTree } from "./commands/classify-spec-tree.mjs";
16
19
  import { runValidateAiGovernance } from "./commands/validate-ai-governance.mjs";
20
+ import { runValidateDomainAdmission } from "./commands/validate-domain-admission.mjs";
17
21
  import { runValidateExecutionPacket } from "./commands/validate-execution-packet.mjs";
22
+ import { runValidateGuidanceBodies } from "./commands/validate-guidance-bodies.mjs";
18
23
  import { runValidateOrchestrationState } from "./commands/validate-orchestration-state.mjs";
24
+ import { runValidatePlacement } from "./commands/validate-placement.mjs";
25
+ import { runValidateProjectionEdges } from "./commands/validate-projection-edges.mjs";
19
26
  import { runValidateSpecGovernance } from "./commands/validate-spec-governance.mjs";
20
27
  import { runValidateSpecAudit } from "./commands/validate-spec-audit.mjs";
21
28
  import { runValidateSpecTree } from "./commands/validate-spec-tree.mjs";
29
+ import { runValidateTableFamily } from "./commands/validate-table-family.mjs";
30
+ import { runValidateTrackedOutputAdmission } from "./commands/validate-tracked-output-admission.mjs";
22
31
  import { runValidatePrompt } from "./commands/validate-prompt.mjs";
23
32
  import { runValidateWorkerOutput } from "./commands/validate-worker-output.mjs";
24
33
  import { helpText } from "./help.mjs";
@@ -27,6 +36,7 @@ import { VERSION } from "./constants.mjs";
27
36
 
28
37
  const COMMANDS = {
29
38
  start: runStart,
39
+ sync: runSync,
30
40
  topic: runTopic,
31
41
  "topic-runner": runTopicRunnerCommand,
32
42
  clear: runClear,
@@ -34,7 +44,7 @@ const COMMANDS = {
34
44
  "blueprint-audit": runBlueprintAudit,
35
45
  handoff: runHandoff,
36
46
  closeout: runCloseout,
37
- "audit-sweep": runAuditSweep,
47
+ sweep: runSweep,
38
48
  "admit-high-risk-decision": runAdmitHighRiskDecision,
39
49
  "decide-high-risk-execution": runDecideHighRiskExecution,
40
50
  "ingest-high-risk-execution": runIngestHighRiskExecution,
@@ -44,7 +54,15 @@ const COMMANDS = {
44
54
  "validate-spec-governance": runValidateSpecGovernance,
45
55
  "validate-spec-audit": runValidateSpecAudit,
46
56
  "validate-spec-tree": runValidateSpecTree,
57
+ "classify-spec-tree": runClassifySpecTree,
58
+ "validate-placement": runValidatePlacement,
59
+ "validate-table-family": runValidateTableFamily,
60
+ "validate-projection-edges": runValidateProjectionEdges,
61
+ "validate-guidance-bodies": runValidateGuidanceBodies,
62
+ "validate-domain-admission": runValidateDomainAdmission,
63
+ "validate-tracked-output-admission": runValidateTrackedOutputAdmission,
47
64
  "generate-spec-derived-docs": runGenerateSpecDerivedDocs,
65
+ "generate-spec-migration-plan": runGenerateSpecMigrationPlan,
48
66
  "validate-ai-governance": runValidateAiGovernance,
49
67
  "validate-prompt": runValidatePrompt,
50
68
  "validate-worker-output": runValidateWorkerOutput,