@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
@@ -6,33 +6,25 @@ function evidenceRootsForSpecOwner(ownerDomain, targetRootRef) {
6
6
  if (targetRootRef !== ".") {
7
7
  return [targetRootRef];
8
8
  }
9
- const repoWideEvidenceRoots = [
10
- ".github",
11
- "apps",
12
- "config",
13
- "kit",
14
- "nimi-coding",
15
- "nimi-cognition",
16
- "proto",
17
- "runtime",
9
+ const owner = String(ownerDomain ?? "").trim().replace(/\\/g, "/").replace(/^\/+|\/+$/g, "");
10
+ const repoWideEvidenceRoots = [".", ".github", "config", "scripts", "src", "lib", "packages", "apps", "tools", "services"];
11
+ if (!owner || owner === "spec-meta" || owner === "spec-root") {
12
+ return repoWideEvidenceRoots;
13
+ }
14
+ if (owner === "project") {
15
+ return ["src", "lib", "packages", "apps", "tools", "services", "scripts", "config"];
16
+ }
17
+ return [
18
+ owner,
19
+ `src/${owner}`,
20
+ `lib/${owner}`,
21
+ `packages/${owner}`,
22
+ `apps/${owner}`,
23
+ `tools/${owner}`,
24
+ `services/${owner}`,
18
25
  "scripts",
19
- "sdk",
20
- ".nimi/spec",
21
- ".nimi/contracts",
22
- ".nimi/methodology",
26
+ "config",
23
27
  ];
24
- const roots = {
25
- "spec-meta": repoWideEvidenceRoots,
26
- "spec-root": repoWideEvidenceRoots,
27
- cognition: ["nimi-cognition", ".nimi/spec/cognition"],
28
- desktop: ["apps/desktop", "kit", ".nimi/spec/desktop"],
29
- future: [".nimi/spec/future", ".nimi/topics"],
30
- platform: ["kit", "scripts", ".nimi/spec/platform"],
31
- realm: ["sdk/src/realm", "runtime/internal/protocol", ".nimi/spec/realm"],
32
- runtime: ["runtime", "proto/runtime/v1", "scripts", "config", ".nimi/spec/runtime"],
33
- sdk: ["sdk/src", "sdk/test", "scripts", ".nimi/spec/sdk"],
34
- };
35
- return roots[ownerDomain] ?? [ownerDomain, `.nimi/spec/${ownerDomain}`];
36
28
  }
37
29
 
38
30
  function slugPart(value) {
@@ -74,7 +66,13 @@ function candidateEvidenceRefsForModuleMapPath(modulePath, evidenceRoots) {
74
66
  if (!normalized || normalized.startsWith("http:") || normalized.startsWith("https:")) {
75
67
  return [];
76
68
  }
77
- const directRoot = /^(?:\.nimi|apps|config|kit|nimi-[^/]+|proto|runtime|scripts|sdk)\//.test(normalized);
69
+ const firstSegment = normalized.split("/")[0];
70
+ const genericDirectRoots = new Set([".github", ".nimi", "apps", "config", "lib", "packages", "scripts", "services", "src", "tools"]);
71
+ const directRoot = genericDirectRoots.has(firstSegment)
72
+ || (evidenceRoots ?? []).some((rootRef) => {
73
+ const root = String(rootRef ?? "").replace(/\\/g, "/").replace(/\/$/, "");
74
+ return root !== "." && (normalized === root || normalized.startsWith(`${root}/`));
75
+ });
78
76
  const candidates = [];
79
77
  if (directRoot) {
80
78
  candidates.push(normalized);
@@ -195,4 +193,3 @@ export function buildSpecChunks(includedInventory, options) {
195
193
  }
196
194
  return chunks;
197
195
  }
198
-
@@ -38,6 +38,10 @@ import { assignEvidenceInventory } from "./evidence-assignment.mjs";
38
38
  import { buildSpecChunks } from "./inventory-spec-chunks.mjs";
39
39
  import { buildRiskBudgetPolicy } from "./risk-budget.mjs";
40
40
  import { pathExists } from "../fs-helpers.mjs";
41
+ import {
42
+ buildSpecSurfaceInventory,
43
+ isProductAuthoritySurfaceClass,
44
+ } from "../internal/surface-taxonomy-validators.mjs";
41
45
 
42
46
  const execFile = promisify(execFileCallback);
43
47
  async function listGitFiles(projectRoot, targetRootRef) {
@@ -140,7 +144,7 @@ async function hasSpecAuthorityRoot(projectRoot) {
140
144
  function resolveChunkBasis(targetRootRef, requested, specRootPresent) {
141
145
  const normalized = requested ? String(requested).trim() : "auto";
142
146
  if (!["auto", "files", "spec"].includes(normalized)) {
143
- return { ok: false, error: "nimicoding audit-sweep refused: --chunk-basis must be auto, files, or spec.\n" };
147
+ return { ok: false, error: "nimicoding sweep audit refused: --chunk-basis must be auto, files, or spec.\n" };
144
148
  }
145
149
  if (normalized === "files") {
146
150
  return { ok: true, basis: "files" };
@@ -148,7 +152,7 @@ function resolveChunkBasis(targetRootRef, requested, specRootPresent) {
148
152
  if (normalized === "spec") {
149
153
  return specRootPresent
150
154
  ? { ok: true, basis: "spec" }
151
- : { ok: false, error: "nimicoding audit-sweep refused: --chunk-basis spec requires .nimi/spec.\n" };
155
+ : { ok: false, error: "nimicoding sweep audit refused: --chunk-basis spec requires .nimi/spec.\n" };
152
156
  }
153
157
  return { ok: true, basis: (targetRootRef === "." || isSpecAuthorityRoot(targetRootRef)) && specRootPresent ? "spec" : "files" };
154
158
  }
@@ -169,6 +173,7 @@ async function buildInventoryEntry(projectRoot, fileRef, targetRootRef, excludeP
169
173
  extension: extension || "none",
170
174
  owner_domain: options.ownerDomain ?? ownerDomainForFile(fileRef, targetRootRef),
171
175
  classification: classifyFile(fileRef),
176
+ surface_class: options.surfaceClass ?? null,
172
177
  included,
173
178
  exclusion_reason: included
174
179
  ? null
@@ -176,6 +181,25 @@ async function buildInventoryEntry(projectRoot, fileRef, targetRootRef, excludeP
176
181
  };
177
182
  }
178
183
 
184
+ function applySpecSurfaceAuthorityFilter(inventory, surfaceEntriesByRef) {
185
+ return inventory.map((entry) => {
186
+ const surfaceEntry = surfaceEntriesByRef.get(entry.file_ref);
187
+ if (!surfaceEntry) {
188
+ return entry;
189
+ }
190
+ const surfaceClass = surfaceEntry.current_inferred_class;
191
+ if (isProductAuthoritySurfaceClass(surfaceClass)) {
192
+ return { ...entry, surface_class: surfaceClass };
193
+ }
194
+ return {
195
+ ...entry,
196
+ surface_class: surfaceClass,
197
+ included: false,
198
+ exclusion_reason: `non_product_surface:${surfaceClass}`,
199
+ };
200
+ });
201
+ }
202
+
179
203
  function buildFileChunks(includedInventory, options) {
180
204
  const byOwner = new Map();
181
205
  for (const entry of includedInventory) {
@@ -222,7 +246,7 @@ function buildAuditIgnorePolicy(projectConfig, options) {
222
246
  if (!reason) {
223
247
  return {
224
248
  ok: false,
225
- error: "nimicoding audit-sweep refused: --ignore or --ignore-owner requires --ignore-reason, or .nimi/config/audit-sweep.yaml audit_sweep.ignore_reason.\n",
249
+ error: "nimicoding sweep audit refused: --ignore or --ignore-owner requires --ignore-reason, or .nimi/config/audit-sweep.yaml audit_sweep.ignore_reason.\n",
226
250
  };
227
251
  }
228
252
  return {
@@ -297,7 +321,7 @@ async function listAdmittedPackageAuthorityEntries(projectRoot, packageAuthority
297
321
  if (!rootInfo?.isDirectory()) {
298
322
  return {
299
323
  ok: false,
300
- error: `nimicoding audit-sweep refused: package authority admission ${admission.id} authority_root is missing: ${admission.authority_root}.\n`,
324
+ error: `nimicoding sweep audit refused: package authority admission ${admission.id} authority_root is missing: ${admission.authority_root}.\n`,
301
325
  };
302
326
  }
303
327
  const gitFiles = await listGitFiles(projectRoot, admission.authority_root);
@@ -326,7 +350,7 @@ async function listAdmittedAppAuthorityEntries(projectRoot, appSliceAdmissions,
326
350
  if (!rootInfo?.isDirectory()) {
327
351
  return {
328
352
  ok: false,
329
- error: `nimicoding audit-sweep refused: app-slice admission ${admission.app_id} authority_root is missing: ${admission.authority_root}.\n`,
353
+ error: `nimicoding sweep audit refused: app-slice admission ${admission.app_id} authority_root is missing: ${admission.authority_root}.\n`,
330
354
  };
331
355
  }
332
356
  const gitFiles = await listGitFiles(projectRoot, admission.authority_root);
@@ -381,12 +405,12 @@ export async function createAuditSweepPlan(projectRoot, options) {
381
405
 
382
406
  const targetInfo = await pathExists(targetRoot.absolutePath);
383
407
  if (!targetInfo || !targetInfo.isDirectory()) {
384
- return inputError("nimicoding audit-sweep refused: --root must point to an existing directory.\n");
408
+ return inputError("nimicoding sweep audit refused: --root must point to an existing directory.\n");
385
409
  }
386
410
 
387
411
  const sweepId = options.sweepId ? safeSweepId(options.sweepId) : deriveSweepId(targetRootRef);
388
412
  if (!sweepId) {
389
- return inputError("nimicoding audit-sweep refused: --sweep-id must be a safe id.\n");
413
+ return inputError("nimicoding sweep audit refused: --sweep-id must be a safe id.\n");
390
414
  }
391
415
 
392
416
  const specRootPresent = await hasSpecAuthorityRoot(projectRoot);
@@ -446,15 +470,22 @@ export async function createAuditSweepPlan(projectRoot, options) {
446
470
  for (const fileRef of allFileRefs) {
447
471
  inventory.push(await buildInventoryEntry(projectRoot, fileRef, inventoryRootRef, excludePatterns, { forceAuthority: true }));
448
472
  }
473
+ let specSurfaceReport = null;
474
+ let authorityInventory = inventory;
475
+ if (chunkBasis.basis === "spec") {
476
+ specSurfaceReport = await buildSpecSurfaceInventory(projectRoot, { rootRef: inventoryRootRef });
477
+ const surfaceEntriesByRef = new Map(specSurfaceReport.entries.map((entry) => [entry.source_path, entry]));
478
+ authorityInventory = applySpecSurfaceAuthorityFilter(inventory, surfaceEntriesByRef);
479
+ }
449
480
  if (chunkBasis.basis === "spec" && appSliceAdmissions.length > 0) {
450
481
  const appAuthorityEntries = await listAdmittedAppAuthorityEntries(projectRoot, appSliceAdmissions, excludePatterns);
451
482
  if (!appAuthorityEntries.ok) {
452
483
  return inputError(appAuthorityEntries.error);
453
484
  }
454
- const seenAuthorityRefs = new Set(inventory.map((entry) => entry.file_ref));
485
+ const seenAuthorityRefs = new Set(authorityInventory.map((entry) => entry.file_ref));
455
486
  for (const entry of appAuthorityEntries.entries) {
456
487
  if (!seenAuthorityRefs.has(entry.file_ref)) {
457
- inventory.push(entry);
488
+ authorityInventory.push(entry);
458
489
  seenAuthorityRefs.add(entry.file_ref);
459
490
  }
460
491
  }
@@ -464,16 +495,16 @@ export async function createAuditSweepPlan(projectRoot, options) {
464
495
  if (!packageAuthorityEntries.ok) {
465
496
  return inputError(packageAuthorityEntries.error);
466
497
  }
467
- const seenAuthorityRefs = new Set(inventory.map((entry) => entry.file_ref));
498
+ const seenAuthorityRefs = new Set(authorityInventory.map((entry) => entry.file_ref));
468
499
  for (const entry of packageAuthorityEntries.entries) {
469
500
  if (!seenAuthorityRefs.has(entry.file_ref)) {
470
- inventory.push(entry);
501
+ authorityInventory.push(entry);
471
502
  seenAuthorityRefs.add(entry.file_ref);
472
503
  }
473
504
  }
474
505
  }
475
506
 
476
- const includedInventory = inventory.filter((entry) => entry.included);
507
+ const includedInventory = authorityInventory.filter((entry) => entry.included);
477
508
  const authorityFileRefs = new Set(includedInventory.map((entry) => entry.file_ref));
478
509
  const authorityTextByRef = new Map();
479
510
  if (chunkBasis.basis === "spec") {
@@ -516,7 +547,7 @@ export async function createAuditSweepPlan(projectRoot, options) {
516
547
  const createdAt = options.createdAt ?? new Date().toISOString();
517
548
  const ignoreResult = applyAuditIgnorePolicy(chunks, auditIgnorePolicy, createdAt);
518
549
  chunks = ignoreResult.chunks;
519
- const inventoryHash = sha256Object(inventory.map((entry) => ({
550
+ const inventoryHash = sha256Object(authorityInventory.map((entry) => ({
520
551
  file_ref: entry.file_ref,
521
552
  sha256: entry.sha256,
522
553
  included: entry.included,
@@ -574,8 +605,15 @@ export async function createAuditSweepPlan(projectRoot, options) {
574
605
  } : {}),
575
606
  exclude_patterns: excludePatterns,
576
607
  inventory_hash: inventoryHash,
608
+ ...(specSurfaceReport ? {
609
+ surface_classification: {
610
+ contract: specSurfaceReport.contract,
611
+ summary: specSurfaceReport.summary,
612
+ errors: specSurfaceReport.errors,
613
+ },
614
+ } : {}),
577
615
  ...(evidenceInventoryHash ? { evidence_inventory_hash: evidenceInventoryHash } : {}),
578
- inventory,
616
+ inventory: authorityInventory,
579
617
  ...(chunkBasis.basis === "spec" ? {
580
618
  evidence_inventory: evidenceInventory.map((entry) => ({
581
619
  file_ref: entry.file_ref,
@@ -591,9 +629,9 @@ export async function createAuditSweepPlan(projectRoot, options) {
591
629
  } : {}),
592
630
  chunks,
593
631
  coverage: {
594
- total_files: inventory.length,
632
+ total_files: authorityInventory.length,
595
633
  included_files: includedInventory.length,
596
- excluded_files: inventory.length - includedInventory.length,
634
+ excluded_files: authorityInventory.length - includedInventory.length,
597
635
  ...(chunkBasis.basis === "spec" ? {
598
636
  authority_files: includedInventory.length,
599
637
  evidence_files: evidenceInventory.length,
@@ -694,11 +732,12 @@ export async function createAuditSweepPlan(projectRoot, options) {
694
732
  sweepId,
695
733
  planRef: planRef(sweepId),
696
734
  chunkRefs: chunks.map((chunk) => chunkRef(sweepId, chunk.chunk_id)),
735
+ chunkIds: chunks.map((chunk) => chunk.chunk_id),
697
736
  runLedgerRef: runRef,
698
737
  chunkCount: chunks.length,
699
- totalFiles: inventory.length,
738
+ totalFiles: authorityInventory.length,
700
739
  includedFiles: includedInventory.length,
701
- excludedFiles: inventory.length - includedInventory.length,
740
+ excludedFiles: authorityInventory.length - includedInventory.length,
702
741
  ...(chunkBasis.basis === "spec" ? {
703
742
  evidenceFiles: evidenceInventory.length,
704
743
  unmappedEvidenceFiles: unmappedEvidenceFiles.length,
@@ -724,5 +763,6 @@ export async function getPlannedChunkRefs(projectRoot, sweepId) {
724
763
  return {
725
764
  ok: true,
726
765
  chunkRefs: loaded.plan.chunks.map((chunk) => chunkRef(sweepId, chunk.chunk_id)),
766
+ chunkIds: loaded.plan.chunks.map((chunk) => chunk.chunk_id),
727
767
  };
728
768
  }
@@ -206,7 +206,7 @@ function formatReport({ sweepId, ledger, findings }) {
206
206
  export async function buildAuditSweepLedger(projectRoot, options) {
207
207
  const sweepId = safeSweepId(options.sweepId);
208
208
  if (!sweepId) {
209
- return inputError("nimicoding audit-sweep refused: --sweep-id is required.\n");
209
+ return inputError("nimicoding sweep audit refused: --sweep-id is required.\n");
210
210
  }
211
211
 
212
212
  const timestampError = options.verifiedAt ? ensureIsoTimestamp(options.verifiedAt) : null;
@@ -15,8 +15,8 @@ const HIGH_RISK_OWNER_DOMAINS = new Set([
15
15
  "provider",
16
16
  "desktop",
17
17
  "web",
18
- "nimi-coding",
19
- "nimi-coding/audit-sweep",
18
+ "nimicoding",
19
+ "nimicoding/audit-sweep",
20
20
  ]);
21
21
 
22
22
  export function criteriaEnableP0P1Recall(criteria) {
@@ -135,7 +135,7 @@ function groupOpenFindings(findings, clusters, maxFindingsPerWave) {
135
135
  export async function buildAuditSweepRemediationMap(projectRoot, options) {
136
136
  const sweepId = safeSweepId(options.sweepId);
137
137
  if (!sweepId) {
138
- return inputError("nimicoding audit-sweep refused: --sweep-id is required.\n");
138
+ return inputError("nimicoding sweep audit refused: --sweep-id is required.\n");
139
139
  }
140
140
  const timestampError = options.verifiedAt ? ensureIsoTimestamp(options.verifiedAt) : null;
141
141
  if (timestampError) {
@@ -243,7 +243,7 @@ function topicWaveFromRemediationWave(wave, ledgerRef, remediationMapRefValue) {
243
243
  export async function admitAuditSweepRemediationMap(projectRoot, options) {
244
244
  const sweepId = safeSweepId(options.sweepId);
245
245
  if (!sweepId || typeof options.topicId !== "string" || !options.topicId.trim()) {
246
- return inputError("nimicoding audit-sweep refused: --sweep-id and --topic-id are required.\n");
246
+ return inputError("nimicoding sweep audit refused: --sweep-id and --topic-id are required.\n");
247
247
  }
248
248
 
249
249
  const ledgerResult = await loadLatestLedger(projectRoot, sweepId);
@@ -253,7 +253,7 @@ export async function admitAuditSweepRemediationMap(projectRoot, options) {
253
253
  const mapRef = remediationMapRef(sweepId, ledgerResult.ledger.snapshot_id);
254
254
  const remediationMap = await loadYamlRef(projectRoot, mapRef);
255
255
  if (!remediationMap || remediationMap.kind !== "audit-remediation-map" || remediationMap.source_ledger_ref !== ledgerResult.ledgerRef || !Array.isArray(remediationMap.waves)) {
256
- return inputError("nimicoding audit-sweep refused: latest remediation map is missing or malformed.\n");
256
+ return inputError("nimicoding sweep audit refused: latest remediation map is missing or malformed.\n");
257
257
  }
258
258
  const planResult = await loadPlan(projectRoot, sweepId);
259
259
  if (!planResult.ok) {
@@ -273,7 +273,7 @@ export async function admitAuditSweepRemediationMap(projectRoot, options) {
273
273
  ok: false,
274
274
  inputError: true,
275
275
  exitCode: 1,
276
- error: `nimicoding audit-sweep refused: remediation wave admission failed: ${addResult.error}\n`,
276
+ error: `nimicoding sweep audit refused: remediation wave admission failed: ${addResult.error}\n`,
277
277
  };
278
278
  }
279
279
  materialized.push(topicWave.wave_id);
@@ -289,7 +289,7 @@ export async function admitAuditSweepRemediationMap(projectRoot, options) {
289
289
  ok: false,
290
290
  inputError: true,
291
291
  exitCode: 1,
292
- error: `nimicoding audit-sweep refused: remediation wave selection failed: ${selectResult.error}\n`,
292
+ error: `nimicoding sweep audit refused: remediation wave selection failed: ${selectResult.error}\n`,
293
293
  };
294
294
  }
295
295
  const admitResult = await admitWaveInTopic(projectRoot, options.topicId, topicWave.wave_id);
@@ -298,7 +298,7 @@ export async function admitAuditSweepRemediationMap(projectRoot, options) {
298
298
  ok: false,
299
299
  inputError: true,
300
300
  exitCode: 1,
301
- error: `nimicoding audit-sweep refused: remediation wave admission failed: ${admitResult.error}\n`,
301
+ error: `nimicoding sweep audit refused: remediation wave admission failed: ${admitResult.error}\n`,
302
302
  };
303
303
  }
304
304
  admitted.push(topicWave.wave_id);
@@ -59,10 +59,10 @@ function validateRerunEvidence(evidence, finding, disposition) {
59
59
  export async function resolveAuditSweepFinding(projectRoot, options) {
60
60
  const sweepId = safeSweepId(options.sweepId);
61
61
  if (!sweepId || typeof options.findingId !== "string") {
62
- return inputError("nimicoding audit-sweep refused: --sweep-id and --finding-id are required.\n");
62
+ return inputError("nimicoding sweep audit refused: --sweep-id and --finding-id are required.\n");
63
63
  }
64
64
  if (!FINDING_DISPOSITION.has(options.disposition) || options.disposition === "open") {
65
- return inputError("nimicoding audit-sweep refused: --disposition must be one of remediated, accepted-risk, false-positive, deferred-backlog.\n");
65
+ return inputError("nimicoding sweep audit refused: --disposition must be one of remediated, accepted-risk, false-positive, deferred-backlog.\n");
66
66
  }
67
67
  const timestampError = ensureIsoTimestamp(options.verifiedAt);
68
68
  if (timestampError) {
@@ -74,22 +74,22 @@ export async function resolveAuditSweepFinding(projectRoot, options) {
74
74
  }
75
75
  const sourceInfo = await pathExists(source.absolutePath);
76
76
  if (!sourceInfo || !sourceInfo.isFile()) {
77
- return inputError("nimicoding audit-sweep refused: --from must point to an existing JSON evidence file.\n");
77
+ return inputError("nimicoding sweep audit refused: --from must point to an existing JSON evidence file.\n");
78
78
  }
79
79
 
80
80
  const { findingsRef: aggregateFindingsRef, store } = await loadFindings(projectRoot, sweepId);
81
81
  const findingIndex = store.findings.findIndex((finding) => finding.id === options.findingId);
82
82
  if (findingIndex === -1) {
83
- return inputError(`nimicoding audit-sweep refused: finding not found for ${options.findingId}.\n`);
83
+ return inputError(`nimicoding sweep audit refused: finding not found for ${options.findingId}.\n`);
84
84
  }
85
85
  const finding = store.findings[findingIndex];
86
86
  const evidenceJson = await loadJsonFile(source.absolutePath);
87
87
  if (!evidenceJson.ok) {
88
- return inputError("nimicoding audit-sweep refused: --from must contain valid JSON.\n");
88
+ return inputError("nimicoding sweep audit refused: --from must contain valid JSON.\n");
89
89
  }
90
90
  const validation = validateRerunEvidence(evidenceJson.value, finding, options.disposition);
91
91
  if (!validation.ok) {
92
- return inputError(`nimicoding audit-sweep refused: ${validation.error}.\n`);
92
+ return inputError(`nimicoding sweep audit refused: ${validation.error}.\n`);
93
93
  }
94
94
 
95
95
  const evidenceRef = artifactRef("evidence_refs", sweepId, `resolution-${options.findingId}.json`);
@@ -12,7 +12,7 @@ import { ensureClusterStore } from "./risk-budget.mjs";
12
12
  export async function getAuditSweepStatus(projectRoot, options) {
13
13
  const sweepId = safeSweepId(options.sweepId);
14
14
  if (!sweepId) {
15
- return inputError("nimicoding audit-sweep refused: --sweep-id is required.\n");
15
+ return inputError("nimicoding sweep audit refused: --sweep-id is required.\n");
16
16
  }
17
17
 
18
18
  const planResult = await loadPlan(projectRoot, sweepId);
@@ -688,11 +688,11 @@ async function validateCloseoutArtifact(projectRoot, sweepId, ledgerInfo, remedi
688
688
  export async function validateAuditSweepArtifacts(projectRoot, options) {
689
689
  const sweepId = safeSweepId(options.sweepId);
690
690
  if (!sweepId) {
691
- return inputError("nimicoding audit-sweep refused: --sweep-id is required.\n");
691
+ return inputError("nimicoding sweep audit refused: --sweep-id is required.\n");
692
692
  }
693
693
  const scope = options.scope ?? "all";
694
694
  if (!VALIDATION_SCOPES.has(scope)) {
695
- return inputError("nimicoding audit-sweep refused: --scope must be one of all, plan, chunks, findings, ledger, remediation, rerun, closeout.\n");
695
+ return inputError("nimicoding sweep audit refused: --scope must be one of all, plan, chunks, findings, ledger, remediation, rerun, closeout.\n");
696
696
  }
697
697
 
698
698
  const checks = [];