@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
@@ -36,7 +36,7 @@ export async function loadAuditSweepProjectConfig(projectRoot) {
36
36
  } catch (error) {
37
37
  return {
38
38
  ok: false,
39
- error: `nimicoding audit-sweep refused: ${AUDIT_SWEEP_PROJECT_CONFIG_REF} must contain valid YAML (${error.message}).\n`,
39
+ error: `nimicoding sweep audit refused: ${AUDIT_SWEEP_PROJECT_CONFIG_REF} must contain valid YAML (${error.message}).\n`,
40
40
  };
41
41
  }
42
42
 
@@ -47,25 +47,25 @@ export async function loadAuditSweepProjectConfig(projectRoot) {
47
47
  if (!Array.isArray(rawExcludePatterns)) {
48
48
  return {
49
49
  ok: false,
50
- error: `nimicoding audit-sweep refused: ${AUDIT_SWEEP_PROJECT_CONFIG_REF} exclude_patterns must be an array.\n`,
50
+ error: `nimicoding sweep audit refused: ${AUDIT_SWEEP_PROJECT_CONFIG_REF} exclude_patterns must be an array.\n`,
51
51
  };
52
52
  }
53
53
  if (!Array.isArray(rawIgnorePatterns)) {
54
54
  return {
55
55
  ok: false,
56
- error: `nimicoding audit-sweep refused: ${AUDIT_SWEEP_PROJECT_CONFIG_REF} ignore_patterns must be an array.\n`,
56
+ error: `nimicoding sweep audit refused: ${AUDIT_SWEEP_PROJECT_CONFIG_REF} ignore_patterns must be an array.\n`,
57
57
  };
58
58
  }
59
59
  if (!Array.isArray(rawIgnoreOwnerDomains)) {
60
60
  return {
61
61
  ok: false,
62
- error: `nimicoding audit-sweep refused: ${AUDIT_SWEEP_PROJECT_CONFIG_REF} ignore_owner_domains must be an array.\n`,
62
+ error: `nimicoding sweep audit refused: ${AUDIT_SWEEP_PROJECT_CONFIG_REF} ignore_owner_domains must be an array.\n`,
63
63
  };
64
64
  }
65
65
  if (rawIgnoreReason !== null && (typeof rawIgnoreReason !== "string" || rawIgnoreReason.trim().length === 0)) {
66
66
  return {
67
67
  ok: false,
68
- error: `nimicoding audit-sweep refused: ${AUDIT_SWEEP_PROJECT_CONFIG_REF} ignore_reason must be a non-empty string when present.\n`,
68
+ error: `nimicoding sweep audit refused: ${AUDIT_SWEEP_PROJECT_CONFIG_REF} ignore_reason must be a non-empty string when present.\n`,
69
69
  };
70
70
  }
71
71
 
@@ -74,7 +74,7 @@ export async function loadAuditSweepProjectConfig(projectRoot) {
74
74
  if (typeof pattern !== "string" || pattern.trim().length === 0) {
75
75
  return {
76
76
  ok: false,
77
- error: `nimicoding audit-sweep refused: ${AUDIT_SWEEP_PROJECT_CONFIG_REF} exclude_patterns entries must be non-empty strings.\n`,
77
+ error: `nimicoding sweep audit refused: ${AUDIT_SWEEP_PROJECT_CONFIG_REF} exclude_patterns entries must be non-empty strings.\n`,
78
78
  };
79
79
  }
80
80
  excludePatterns.push(pattern.trim());
@@ -84,7 +84,7 @@ export async function loadAuditSweepProjectConfig(projectRoot) {
84
84
  if (typeof pattern !== "string" || pattern.trim().length === 0) {
85
85
  return {
86
86
  ok: false,
87
- error: `nimicoding audit-sweep refused: ${AUDIT_SWEEP_PROJECT_CONFIG_REF} ignore_patterns entries must be non-empty strings.\n`,
87
+ error: `nimicoding sweep audit refused: ${AUDIT_SWEEP_PROJECT_CONFIG_REF} ignore_patterns entries must be non-empty strings.\n`,
88
88
  };
89
89
  }
90
90
  ignorePatterns.push(pattern.trim());
@@ -94,7 +94,7 @@ export async function loadAuditSweepProjectConfig(projectRoot) {
94
94
  if (typeof ownerDomain !== "string" || ownerDomain.trim().length === 0) {
95
95
  return {
96
96
  ok: false,
97
- error: `nimicoding audit-sweep refused: ${AUDIT_SWEEP_PROJECT_CONFIG_REF} ignore_owner_domains entries must be non-empty strings.\n`,
97
+ error: `nimicoding sweep audit refused: ${AUDIT_SWEEP_PROJECT_CONFIG_REF} ignore_owner_domains entries must be non-empty strings.\n`,
98
98
  };
99
99
  }
100
100
  ignoreOwnerDomains.push(ownerDomain.trim());
@@ -123,7 +123,7 @@ export async function loadAppSliceAdmissions(projectRoot) {
123
123
  } catch (error) {
124
124
  return {
125
125
  ok: false,
126
- error: `nimicoding audit-sweep refused: ${APP_SLICE_ADMISSION_REF} must contain valid YAML (${error.message}).\n`,
126
+ error: `nimicoding sweep audit refused: ${APP_SLICE_ADMISSION_REF} must contain valid YAML (${error.message}).\n`,
127
127
  };
128
128
  }
129
129
 
@@ -131,7 +131,7 @@ export async function loadAppSliceAdmissions(projectRoot) {
131
131
  if (!rows) {
132
132
  return {
133
133
  ok: false,
134
- error: `nimicoding audit-sweep refused: ${APP_SLICE_ADMISSION_REF} must declare admissions as an array.\n`,
134
+ error: `nimicoding sweep audit refused: ${APP_SLICE_ADMISSION_REF} must declare admissions as an array.\n`,
135
135
  };
136
136
  }
137
137
 
@@ -146,20 +146,20 @@ export async function loadAppSliceAdmissions(projectRoot) {
146
146
  ? row.evidence_roots.map((entry) => String(entry ?? "").trim().replace(/\\/g, "/").replace(/\/$/, "")).filter(Boolean)
147
147
  : null;
148
148
  if (!appId || seenAppIds.has(appId)) {
149
- return { ok: false, error: `nimicoding audit-sweep refused: ${APP_SLICE_ADMISSION_REF} has missing or duplicate app_id.\n` };
149
+ return { ok: false, error: `nimicoding sweep audit refused: ${APP_SLICE_ADMISSION_REF} has missing or duplicate app_id.\n` };
150
150
  }
151
151
  seenAppIds.add(appId);
152
152
  if (appId === "avatar") {
153
- return { ok: false, error: `nimicoding audit-sweep refused: avatar is promoted to .nimi/spec/avatar and must not be admitted through ${APP_SLICE_ADMISSION_REF}.\n` };
153
+ return { ok: false, error: `nimicoding sweep audit refused: avatar is promoted to .nimi/spec/avatar and must not be admitted through ${APP_SLICE_ADMISSION_REF}.\n` };
154
154
  }
155
155
  if (status !== "active") {
156
156
  continue;
157
157
  }
158
158
  if (!ownerDomain || !safeProjectRef(authorityRoot) || !authorityRoot.startsWith(`apps/${appId}/spec`)) {
159
- return { ok: false, error: `nimicoding audit-sweep refused: ${APP_SLICE_ADMISSION_REF} ${appId} has invalid owner_domain or authority_root.\n` };
159
+ return { ok: false, error: `nimicoding sweep audit refused: ${APP_SLICE_ADMISSION_REF} ${appId} has invalid owner_domain or authority_root.\n` };
160
160
  }
161
161
  if (!evidenceRoots || evidenceRoots.length === 0 || !evidenceRoots.every((rootRef) => safeProjectRef(rootRef) && refInsideRoot(rootRef, `apps/${appId}`))) {
162
- return { ok: false, error: `nimicoding audit-sweep refused: ${APP_SLICE_ADMISSION_REF} ${appId} has invalid evidence_roots.\n` };
162
+ return { ok: false, error: `nimicoding sweep audit refused: ${APP_SLICE_ADMISSION_REF} ${appId} has invalid evidence_roots.\n` };
163
163
  }
164
164
  admissions.push({
165
165
  app_id: appId,
@@ -203,12 +203,12 @@ export async function loadAuditEvidenceRootAdmissions(projectRoot, listGitFiles,
203
203
  } catch (error) {
204
204
  return {
205
205
  ok: false,
206
- error: `nimicoding audit-sweep refused: ${tableRef} must contain valid YAML (${error.message}).\n`,
206
+ error: `nimicoding sweep audit refused: ${tableRef} must contain valid YAML (${error.message}).\n`,
207
207
  };
208
208
  }
209
209
  const rows = Array.isArray(parsed?.roots) ? parsed.roots : null;
210
210
  if (!rows) {
211
- return { ok: false, error: `nimicoding audit-sweep refused: ${tableRef} must declare roots as an array.\n` };
211
+ return { ok: false, error: `nimicoding sweep audit refused: ${tableRef} must declare roots as an array.\n` };
212
212
  }
213
213
  for (const row of rows) {
214
214
  const id = String(row?.id ?? "").trim();
@@ -220,13 +220,13 @@ export async function loadAuditEvidenceRootAdmissions(projectRoot, listGitFiles,
220
220
  ? row.evidence_roots.map((entry) => String(entry ?? "").trim().replace(/\\/g, "/").replace(/\/$/, "")).filter(Boolean)
221
221
  : null;
222
222
  if (!id || !ownerDomain || !authorityRefs?.length || !evidenceRoots?.length) {
223
- return { ok: false, error: `nimicoding audit-sweep refused: ${tableRef} root rows require id, owner_domain, authority_refs, and evidence_roots.\n` };
223
+ return { ok: false, error: `nimicoding sweep audit refused: ${tableRef} root rows require id, owner_domain, authority_refs, and evidence_roots.\n` };
224
224
  }
225
225
  if (!authorityRefs.every((ref) => safeProjectRef(ref) && ref.startsWith(".nimi/spec/"))) {
226
- return { ok: false, error: `nimicoding audit-sweep refused: ${tableRef} ${id} authority_refs must stay under .nimi/spec.\n` };
226
+ return { ok: false, error: `nimicoding sweep audit refused: ${tableRef} ${id} authority_refs must stay under .nimi/spec.\n` };
227
227
  }
228
228
  if (!evidenceRoots.every((ref) => safeProjectRef(ref) && !ref.startsWith(".nimi/spec/"))) {
229
- return { ok: false, error: `nimicoding audit-sweep refused: ${tableRef} ${id} evidence_roots must be project evidence roots outside .nimi/spec.\n` };
229
+ return { ok: false, error: `nimicoding sweep audit refused: ${tableRef} ${id} evidence_roots must be project evidence roots outside .nimi/spec.\n` };
230
230
  }
231
231
  admissions.push({
232
232
  id,
@@ -256,12 +256,12 @@ export async function loadPackageAuthorityAdmissions(projectRoot, listGitFiles,
256
256
  } catch (error) {
257
257
  return {
258
258
  ok: false,
259
- error: `nimicoding audit-sweep refused: ${tableRef} must contain valid YAML (${error.message}).\n`,
259
+ error: `nimicoding sweep audit refused: ${tableRef} must contain valid YAML (${error.message}).\n`,
260
260
  };
261
261
  }
262
262
  const rows = Array.isArray(parsed?.admissions) ? parsed.admissions : null;
263
263
  if (!rows) {
264
- return { ok: false, error: `nimicoding audit-sweep refused: ${tableRef} must declare admissions as an array.\n` };
264
+ return { ok: false, error: `nimicoding sweep audit refused: ${tableRef} must declare admissions as an array.\n` };
265
265
  }
266
266
  for (const row of rows) {
267
267
  const id = String(row?.id ?? "").trim();
@@ -279,28 +279,37 @@ export async function loadPackageAuthorityAdmissions(projectRoot, listGitFiles,
279
279
  : [];
280
280
  const admissionKey = `${tableRef}#${id}`;
281
281
  if (!id || seenIds.has(admissionKey)) {
282
- return { ok: false, error: `nimicoding audit-sweep refused: ${tableRef} has missing or duplicate package authority id.\n` };
282
+ return { ok: false, error: `nimicoding sweep audit refused: ${tableRef} has missing or duplicate package authority id.\n` };
283
283
  }
284
284
  seenIds.add(admissionKey);
285
285
  if (status !== "active") {
286
286
  continue;
287
287
  }
288
288
  if (!ownerDomain || !safeProjectRef(authorityRoot) || authorityRoot.startsWith(".nimi/spec/") || !authorityRoot.endsWith("/spec")) {
289
- return { ok: false, error: `nimicoding audit-sweep refused: ${tableRef} ${id} has invalid owner_domain or authority_root.\n` };
289
+ return { ok: false, error: `nimicoding sweep audit refused: ${tableRef} ${id} has invalid owner_domain or authority_root.\n` };
290
290
  }
291
291
  if (!evidenceRoots || evidenceRoots.length === 0 || !evidenceRoots.every((rootRef) => safeProjectRef(rootRef) && !rootRef.startsWith(".nimi/spec/") && refInsideRoot(authorityRoot, rootRef))) {
292
- return { ok: false, error: `nimicoding audit-sweep refused: ${tableRef} ${id} has invalid evidence_roots.\n` };
292
+ return { ok: false, error: `nimicoding sweep audit refused: ${tableRef} ${id} has invalid evidence_roots.\n` };
293
293
  }
294
294
  const seenProjectionHostRefs = new Set();
295
295
  for (const projection of hostAuthorityProjectionRefs) {
296
- if (!safeProjectRef(projection.host_ref) || !projection.host_ref.startsWith(".nimi/spec/")) {
297
- return { ok: false, error: `nimicoding audit-sweep refused: ${tableRef} ${id} host_authority_projection_refs host_ref must stay under .nimi/spec.\n` };
296
+ const hostProjectionAllowed = projection.host_ref.startsWith(".nimi/config/")
297
+ || projection.host_ref.startsWith(".nimi/contracts/")
298
+ || projection.host_ref.startsWith(".nimi/methodology/")
299
+ || projection.host_ref.startsWith(".nimi/spec/");
300
+ if (!safeProjectRef(projection.host_ref) || !hostProjectionAllowed) {
301
+ return { ok: false, error: `nimicoding sweep audit refused: ${tableRef} ${id} host_authority_projection_refs host_ref must stay under .nimi config/contracts/methodology/spec projections.\n` };
298
302
  }
299
- if (!safeProjectRef(projection.package_ref) || !refInsideRoot(projection.package_ref, authorityRoot)) {
300
- return { ok: false, error: `nimicoding audit-sweep refused: ${tableRef} ${id} host_authority_projection_refs package_ref must stay under authority_root.\n` };
303
+ const packageRoot = authorityRoot.replace(/\/spec$/, "");
304
+ const packageProjectionAllowed = projection.package_ref.startsWith(`${packageRoot}/config/`)
305
+ || projection.package_ref.startsWith(`${packageRoot}/contracts/`)
306
+ || projection.package_ref.startsWith(`${packageRoot}/methodology/`)
307
+ || projection.package_ref.startsWith(`${packageRoot}/spec/`);
308
+ if (!safeProjectRef(projection.package_ref) || !packageProjectionAllowed) {
309
+ return { ok: false, error: `nimicoding sweep audit refused: ${tableRef} ${id} host_authority_projection_refs package_ref must stay under admitted package authority roots.\n` };
301
310
  }
302
311
  if (seenProjectionHostRefs.has(projection.host_ref)) {
303
- return { ok: false, error: `nimicoding audit-sweep refused: ${tableRef} ${id} host_authority_projection_refs contains duplicate host_ref.\n` };
312
+ return { ok: false, error: `nimicoding sweep audit refused: ${tableRef} ${id} host_authority_projection_refs contains duplicate host_ref.\n` };
304
313
  }
305
314
  seenProjectionHostRefs.add(projection.host_ref);
306
315
  }
@@ -21,6 +21,7 @@ const REQUIRED_P0P1_RULE_CHECK_IDS = [
21
21
  "provider_or_model_hardcoding",
22
22
  "app_local_shadow_truth",
23
23
  ];
24
+ const REQUIRED_P0P1_RULE_CHECK_ID_SET = new Set(REQUIRED_P0P1_RULE_CHECK_IDS);
24
25
 
25
26
  function validateP0P1RuleChecks(evidence, implementationRefSet) {
26
27
  const ruleChecks = evidence?.coverage?.p0p1_rule_checks;
@@ -35,10 +36,17 @@ function validateP0P1RuleChecks(evidence, implementationRefSet) {
35
36
 
36
37
  const checkedIds = [];
37
38
  const invalid = [];
39
+ const seenIds = new Set();
38
40
  for (const [index, check] of ruleChecks.entries()) {
39
41
  const id = typeof check?.id === "string" ? check.id : "";
40
42
  if (id) {
41
43
  checkedIds.push(id);
44
+ if (!REQUIRED_P0P1_RULE_CHECK_ID_SET.has(id)) {
45
+ invalid.push({ index, id, reason: "id must exactly match an admitted P0/P1 rule check id" });
46
+ } else if (seenIds.has(id)) {
47
+ invalid.push({ index, id, reason: "duplicate P0/P1 rule check id" });
48
+ }
49
+ seenIds.add(id);
42
50
  }
43
51
  const status = check?.status;
44
52
  if (!["checked", "not_applicable"].includes(status)) {
@@ -456,7 +456,7 @@ export function buildAuditorPacket(sweepId, chunk, auditor, dispatchedAt, plan,
456
456
  finding_locations_must_belong_to_chunk_files_or_evidence_inventory: true,
457
457
  authority_only_finding_location_policy: "when no implementation surface exists, findings[].location.file must be the in-scope authority_ref that contains the defect",
458
458
  finding_contract_ref: ".nimi/contracts/audit-finding.schema.yaml",
459
- ingest_command: `nimicoding audit-sweep chunk ingest --sweep-id ${sweepId} --chunk-id ${chunk.chunk_id} --from <audit-output.json> --verified-at <ISO-8601-UTC>`,
459
+ ingest_command: `nimicoding sweep audit chunk ingest --sweep-id ${sweepId} --chunk-id ${chunk.chunk_id} --from <audit-output.json> --verified-at <ISO-8601-UTC>`,
460
460
  },
461
461
  hard_constraints: [
462
462
  "do_not_sample_out_files_from_this_chunk",
@@ -477,7 +477,7 @@ export function buildAuditorPacket(sweepId, chunk, auditor, dispatchedAt, plan,
477
477
  export async function dispatchAuditSweepChunk(projectRoot, options) {
478
478
  const sweepId = safeSweepId(options.sweepId);
479
479
  if (!sweepId || typeof options.chunkId !== "string") {
480
- return inputError("nimicoding audit-sweep refused: --sweep-id and --chunk-id are required.\n");
480
+ return inputError("nimicoding sweep audit refused: --sweep-id and --chunk-id are required.\n");
481
481
  }
482
482
 
483
483
  const timestampError = ensureIsoTimestamp(options.dispatchedAt, "--dispatched-at");
@@ -497,11 +497,11 @@ export async function dispatchAuditSweepChunk(projectRoot, options) {
497
497
  }
498
498
 
499
499
  if (chunkResult.chunk.state !== "planned") {
500
- return inputError("nimicoding audit-sweep refused: chunk dispatch requires planned state.\n");
500
+ return inputError("nimicoding sweep audit refused: chunk dispatch requires planned state.\n");
501
501
  }
502
502
  const budgetBlock = budgetBlockForChunk(planResult.plan, chunkResult.chunk);
503
503
  if (budgetBlock) {
504
- return inputError(`nimicoding audit-sweep refused: ${budgetBlock}; build or admit remediation bundles before continuing discovery.\n`);
504
+ return inputError(`nimicoding sweep audit refused: ${budgetBlock}; build or admit remediation bundles before continuing discovery.\n`);
505
505
  }
506
506
 
507
507
  const updatedChunk = {
@@ -557,7 +557,7 @@ export async function dispatchAuditSweepChunk(projectRoot, options) {
557
557
  export async function reviewAuditSweepChunk(projectRoot, options) {
558
558
  const sweepId = safeSweepId(options.sweepId);
559
559
  if (!sweepId || typeof options.chunkId !== "string") {
560
- return inputError("nimicoding audit-sweep refused: --sweep-id and --chunk-id are required.\n");
560
+ return inputError("nimicoding sweep audit refused: --sweep-id and --chunk-id are required.\n");
561
561
  }
562
562
 
563
563
  const timestampError = ensureIsoTimestamp(options.reviewedAt, "--reviewed-at");
@@ -566,7 +566,7 @@ export async function reviewAuditSweepChunk(projectRoot, options) {
566
566
  }
567
567
 
568
568
  if (!["pass", "fail"].includes(options.verdict)) {
569
- return inputError("nimicoding audit-sweep refused: --verdict must be pass or fail.\n");
569
+ return inputError("nimicoding sweep audit refused: --verdict must be pass or fail.\n");
570
570
  }
571
571
 
572
572
  return withAuditSweepMutationLock(projectRoot, sweepId, "chunk review", async () => {
@@ -581,10 +581,10 @@ export async function reviewAuditSweepChunk(projectRoot, options) {
581
581
  }
582
582
 
583
583
  if (chunkResult.chunk.state !== "ingested") {
584
- return inputError("nimicoding audit-sweep refused: chunk review requires ingested state.\n");
584
+ return inputError("nimicoding sweep audit refused: chunk review requires ingested state.\n");
585
585
  }
586
586
  if (options.verdict === "pass" && chunkResult.chunk.audit_validity?.posture === "invalid") {
587
- return inputError("nimicoding audit-sweep refused: manager review cannot freeze invalid no-finding evidence as pass.\n");
587
+ return inputError("nimicoding sweep audit refused: manager review cannot freeze invalid no-finding evidence as pass.\n");
588
588
  }
589
589
 
590
590
  const nextState = options.verdict === "pass" ? "frozen" : "failed";
@@ -636,14 +636,14 @@ export async function reviewAuditSweepChunk(projectRoot, options) {
636
636
  export async function skipAuditSweepChunk(projectRoot, options) {
637
637
  const sweepId = safeSweepId(options.sweepId);
638
638
  if (!sweepId || typeof options.chunkId !== "string") {
639
- return inputError("nimicoding audit-sweep refused: --sweep-id and --chunk-id are required.\n");
639
+ return inputError("nimicoding sweep audit refused: --sweep-id and --chunk-id are required.\n");
640
640
  }
641
641
  const timestampError = ensureIsoTimestamp(options.skippedAt, "--skipped-at");
642
642
  if (timestampError) {
643
643
  return timestampError;
644
644
  }
645
645
  if (typeof options.reason !== "string" || !options.reason.trim()) {
646
- return inputError("nimicoding audit-sweep refused: --reason is required when skipping a chunk.\n");
646
+ return inputError("nimicoding sweep audit refused: --reason is required when skipping a chunk.\n");
647
647
  }
648
648
 
649
649
  return withAuditSweepMutationLock(projectRoot, sweepId, "chunk skip", async () => {
@@ -656,7 +656,7 @@ export async function skipAuditSweepChunk(projectRoot, options) {
656
656
  return inputError(chunkResult.error);
657
657
  }
658
658
  if (chunkResult.chunk.state === "frozen") {
659
- return inputError("nimicoding audit-sweep refused: frozen chunks cannot be skipped.\n");
659
+ return inputError("nimicoding sweep audit refused: frozen chunks cannot be skipped.\n");
660
660
  }
661
661
 
662
662
  const updatedChunk = {
@@ -22,7 +22,7 @@ import { validateAuditSweepArtifacts } from "./validators.mjs";
22
22
  export async function buildAuditSweepCloseoutImport(projectRoot, options) {
23
23
  const sweepId = safeSweepId(options.sweepId);
24
24
  if (!sweepId) {
25
- return inputError("nimicoding audit-sweep refused: --sweep-id is required.\n");
25
+ return inputError("nimicoding sweep audit refused: --sweep-id is required.\n");
26
26
  }
27
27
  const timestampError = ensureIsoTimestamp(options.verifiedAt);
28
28
  if (timestampError) {
@@ -37,16 +37,16 @@ export async function buildAuditSweepCloseoutImport(projectRoot, options) {
37
37
  const preflightValidation = await validateAuditSweepArtifacts(projectRoot, { sweepId, scope: "remediation" });
38
38
  if (!preflightValidation.ok) {
39
39
  const failed = preflightValidation.checks.find((entry) => !entry.ok);
40
- return inputError(`nimicoding audit-sweep refused: audit-sweep closeout preflight failed: ${failed?.reason ?? "artifact validation failed"}.\n`);
40
+ return inputError(`nimicoding sweep audit refused: sweep audit closeout preflight failed: ${failed?.reason ?? "artifact validation failed"}.\n`);
41
41
  }
42
42
  if (ledger.status === "blocked") {
43
- return inputError("nimicoding audit-sweep refused: blocked ledger cannot produce completed closeout summary.\n");
43
+ return inputError("nimicoding sweep audit refused: blocked ledger cannot produce completed closeout summary.\n");
44
44
  }
45
45
  if (ledger.status === "blocked_evidence_incomplete" || ledger.status === "partial_authority_only") {
46
- return inputError("nimicoding audit-sweep refused: incomplete spec authority/evidence coverage cannot produce completed closeout summary.\n");
46
+ return inputError("nimicoding sweep audit refused: incomplete spec authority/evidence coverage cannot produce completed closeout summary.\n");
47
47
  }
48
48
  if (ledger.coverage.active_chunks > 0) {
49
- return inputError("nimicoding audit-sweep refused: closeout summary requires no active chunks.\n");
49
+ return inputError("nimicoding sweep audit refused: closeout summary requires no active chunks.\n");
50
50
  }
51
51
 
52
52
  const mapRef = remediationMapRef(sweepId, ledger.snapshot_id);
@@ -58,13 +58,13 @@ export async function buildAuditSweepCloseoutImport(projectRoot, options) {
58
58
  : []);
59
59
  const unmappedOpenFindings = openFindingIds.filter((findingId) => !mappedFindingIds.has(findingId));
60
60
  if (openFindingIds.length > 0 && (!remediationMap || unmappedOpenFindings.length > 0)) {
61
- return inputError("nimicoding audit-sweep refused: open findings require remediation map coverage before closeout summary.\n");
61
+ return inputError("nimicoding sweep audit refused: open findings require remediation map coverage before closeout summary.\n");
62
62
  }
63
63
  const closedWithoutResolutionEvidence = store.findings
64
64
  .filter((finding) => finding.disposition !== "open")
65
65
  .filter((finding) => !finding.resolution?.evidence_ref || !finding.resolution?.rerun);
66
66
  if (closedWithoutResolutionEvidence.length > 0) {
67
- return inputError("nimicoding audit-sweep refused: closed findings require resolution and rerun evidence before closeout summary.\n");
67
+ return inputError("nimicoding sweep audit refused: closed findings require resolution and rerun evidence before closeout summary.\n");
68
68
  }
69
69
 
70
70
  const coverageStatus = deriveCoverageStatus(ledger.status);
@@ -125,7 +125,7 @@ export async function buildAuditSweepCloseoutImport(projectRoot, options) {
125
125
  const closeoutValidation = await validateAuditSweepArtifacts(projectRoot, { sweepId, scope: "closeout" });
126
126
  if (!closeoutValidation.ok) {
127
127
  const failed = closeoutValidation.checks.find((entry) => !entry.ok);
128
- return inputError(`nimicoding audit-sweep refused: audit-sweep closeout validation failed: ${failed?.reason ?? "artifact validation failed"}.\n`);
128
+ return inputError(`nimicoding sweep audit refused: sweep audit closeout validation failed: ${failed?.reason ?? "artifact validation failed"}.\n`);
129
129
  }
130
130
 
131
131
  return {
@@ -178,8 +178,8 @@ function isNonImplementationContextRef(ref) {
178
178
  || normalized.startsWith(".nimi/spec/")
179
179
  || normalized.startsWith(".nimi/contracts/")
180
180
  || normalized.startsWith(".nimi/methodology/")
181
- || normalized.startsWith("nimi-coding/methodology/")
182
- || normalized.startsWith("nimi-coding/spec/");
181
+ || normalized.startsWith("package://@nimiplatform/nimi-coding/methodology/")
182
+ || normalized.startsWith("package://@nimiplatform/nimi-coding/spec/");
183
183
  }
184
184
 
185
185
  function stripNonImplementationContextRefs(refs, evidenceInventorySet) {
@@ -562,7 +562,7 @@ function normalizeCodexSemanticOutput(rawOutput, chunk, options) {
562
562
  auditor: {
563
563
  id: typeof rawOutput.auditor?.id === "string" && rawOutput.auditor.id.trim() ? rawOutput.auditor.id : options.auditorId,
564
564
  mode: "codex_semantic_audit",
565
- methodology_ref: "nimi-coding/methodology/audit-sweep-p0p1-recall.yaml",
565
+ methodology_ref: "package://@nimiplatform/nimi-coding/methodology/audit-sweep-p0p1-recall.yaml",
566
566
  provenance: {
567
567
  kind: "semantic_audit",
568
568
  packet_ref: options.packetRef,
@@ -42,7 +42,7 @@ function projectRefForPath(projectRoot, absolutePath) {
42
42
  }
43
43
  function codexPrompt({ packet, auditorPacketRef, rawRef, sessionRef }) {
44
44
  return [
45
- "You are the Codex semantic auditor for a nimicoding audit-sweep chunk.",
45
+ "You are the Codex semantic auditor for a nimicoding sweep audit chunk.",
46
46
  "Run in read-only, audit-only mode. Do not edit files. Do not implement product fixes.",
47
47
  `Read the auditor packet from ${auditorPacketRef} and inspect the chunk authority refs and implementation evidence semantically.`,
48
48
  "Do not rely on this prompt as the chunk inventory; the packet file is the source for files, authority_refs, selected_implementation_refs, audit_depth, retrieval_prepass, and the raw semantic output contract.",
@@ -59,7 +59,7 @@ function codexPrompt({ packet, auditorPacketRef, rawRef, sessionRef }) {
59
59
  "The JSON object must have exactly these top-level fields: chunk_id, auditor, coverage, findings.",
60
60
  `Set auditor.id to ${JSON.stringify(packet.auditor)}.`,
61
61
  `Set auditor.mode to "codex_semantic_audit".`,
62
- `Set auditor.methodology_ref to "nimi-coding/methodology/audit-sweep-p0p1-recall.yaml".`,
62
+ `Set auditor.methodology_ref to "package://@nimiplatform/nimi-coding/methodology/audit-sweep-p0p1-recall.yaml".`,
63
63
  "Put P0/P1 rule checks only at coverage.p0p1_rule_checks.",
64
64
  `Set auditor.provenance.kind to "semantic_audit".`,
65
65
  `Set auditor.provenance.packet_ref to ${JSON.stringify(packetRef(packet.sweep_id, packet.chunk_id))}.`,
@@ -173,11 +173,11 @@ async function prepareCodexAuditPacket(projectRoot, options) {
173
173
  return inputError(chunkResult.error);
174
174
  }
175
175
  if (chunkResult.chunk.state === "skipped") {
176
- return inputError("nimicoding audit-sweep refused: skipped chunks cannot be audited through Codex.\n");
176
+ return inputError("nimicoding sweep audit refused: skipped chunks cannot be audited through Codex.\n");
177
177
  }
178
178
  const budgetBlock = budgetBlockForChunk(planResult.plan, chunkResult.chunk);
179
179
  if (budgetBlock && chunkResult.chunk.state !== "frozen") {
180
- return inputError(`nimicoding audit-sweep refused: ${budgetBlock}; build or admit remediation bundles before continuing discovery.\n`);
180
+ return inputError(`nimicoding sweep audit refused: ${budgetBlock}; build or admit remediation bundles before continuing discovery.\n`);
181
181
  }
182
182
 
183
183
  const dispatch = {
@@ -311,7 +311,7 @@ async function markCodexAuditFailed(projectRoot, options) {
311
311
  export async function runCodexAuditSweepChunk(projectRoot, options) {
312
312
  const sweepId = safeSweepId(options.sweepId);
313
313
  if (!sweepId || typeof options.chunkId !== "string") {
314
- return inputError("nimicoding audit-sweep refused: --sweep-id and --chunk-id are required.\n");
314
+ return inputError("nimicoding sweep audit refused: --sweep-id and --chunk-id are required.\n");
315
315
  }
316
316
  const dispatchedAtError = ensureIsoTimestamp(options.dispatchedAt, "--dispatched-at");
317
317
  if (dispatchedAtError) {
@@ -394,7 +394,7 @@ export async function runCodexAuditSweepChunk(projectRoot, options) {
394
394
  timeout_ms: runResult.timeoutMs,
395
395
  stderr_tail: runResult.stderr.slice(-2000),
396
396
  });
397
- return inputError(`nimicoding audit-sweep refused: ${failureReason}\n`);
397
+ return inputError(`nimicoding sweep audit refused: ${failureReason}\n`);
398
398
  }
399
399
  }
400
400
 
@@ -425,7 +425,7 @@ export async function runCodexAuditSweepChunk(projectRoot, options) {
425
425
  transcript_ref: rawRef,
426
426
  reason: extracted.error,
427
427
  });
428
- return inputError(`nimicoding audit-sweep refused: Codex auditor output rejected for ${options.chunkId}: ${extracted.error}.\n`);
428
+ return inputError(`nimicoding sweep audit refused: Codex auditor output rejected for ${options.chunkId}: ${extracted.error}.\n`);
429
429
  }
430
430
 
431
431
  await appendRunEvent(projectRoot, sweepId, {
@@ -454,7 +454,7 @@ export async function runCodexAuditSweepChunk(projectRoot, options) {
454
454
  phase: "chunk_ingest",
455
455
  reason: `Codex auditor evidence ingest rejected: ${ingest.error ?? "unknown ingest failure"}.`,
456
456
  });
457
- return inputError(`nimicoding audit-sweep refused: Codex auditor evidence ingest rejected for ${options.chunkId}: ${ingest.error ?? "unknown ingest failure"}.\n`);
457
+ return inputError(`nimicoding sweep audit refused: Codex auditor evidence ingest rejected for ${options.chunkId}: ${ingest.error ?? "unknown ingest failure"}.\n`);
458
458
  }
459
459
 
460
460
  const review = await reviewAuditSweepChunk(projectRoot, {
@@ -475,7 +475,7 @@ export async function runCodexAuditSweepChunk(projectRoot, options) {
475
475
  phase: "chunk_review",
476
476
  reason: `Codex auditor evidence review rejected: ${review.error ?? "unknown review failure"}.`,
477
477
  });
478
- return inputError(`nimicoding audit-sweep refused: Codex auditor evidence review rejected for ${options.chunkId}: ${review.error ?? "unknown review failure"}.\n`);
478
+ return inputError(`nimicoding sweep audit refused: Codex auditor evidence review rejected for ${options.chunkId}: ${review.error ?? "unknown review failure"}.\n`);
479
479
  }
480
480
 
481
481
  const validation = await validateAuditSweepArtifacts(projectRoot, {
@@ -492,7 +492,7 @@ export async function runCodexAuditSweepChunk(projectRoot, options) {
492
492
  phase: "post_chunk_validation",
493
493
  reason: "Post-Codex chunk validation failed.",
494
494
  });
495
- return inputError(`nimicoding audit-sweep refused: post-Codex chunk validation failed for ${options.chunkId}.\n`);
495
+ return inputError(`nimicoding sweep audit refused: post-Codex chunk validation failed for ${options.chunkId}.\n`);
496
496
  }
497
497
 
498
498
  return {
@@ -97,7 +97,7 @@ export function resolveInsideProject(projectRoot, inputPath, label) {
97
97
  if (!isPathInside(projectRoot, absolutePath)) {
98
98
  return {
99
99
  ok: false,
100
- error: `nimicoding audit-sweep refused: ${label} must stay inside the project root.\n`,
100
+ error: `nimicoding sweep audit refused: ${label} must stay inside the project root.\n`,
101
101
  };
102
102
  }
103
103
 
@@ -168,7 +168,7 @@ export async function withAuditSweepMutationLock(projectRoot, sweepId, label, fn
168
168
  handle = await open(lockPath, "wx");
169
169
  } catch (error) {
170
170
  if (error?.code === "EEXIST") {
171
- return inputError(`nimicoding audit-sweep refused: ${label} mutation already in progress for ${sweepId}; retry after the current command finishes.\n`);
171
+ return inputError(`nimicoding sweep audit refused: ${label} mutation already in progress for ${sweepId}; retry after the current command finishes.\n`);
172
172
  }
173
173
  throw error;
174
174
  }
@@ -264,7 +264,7 @@ export async function loadPlan(projectRoot, sweepId) {
264
264
  const ref = planRef(sweepId);
265
265
  const plan = await loadYamlRef(projectRoot, ref);
266
266
  if (!isPlainObject(plan) || plan.kind !== "audit-plan" || plan.sweep_id !== sweepId) {
267
- return { ok: false, error: `nimicoding audit-sweep refused: plan not found for ${sweepId}.\n` };
267
+ return { ok: false, error: `nimicoding sweep audit refused: plan not found for ${sweepId}.\n` };
268
268
  }
269
269
  return { ok: true, plan, planRef: ref };
270
270
  }
@@ -273,7 +273,7 @@ export async function loadChunk(projectRoot, sweepId, chunkId) {
273
273
  const ref = chunkRef(sweepId, chunkId);
274
274
  const chunk = await loadYamlRef(projectRoot, ref);
275
275
  if (!isPlainObject(chunk) || chunk.kind !== "audit-chunk" || chunk.sweep_id !== sweepId || chunk.chunk_id !== chunkId) {
276
- return { ok: false, error: `nimicoding audit-sweep refused: chunk not found for ${sweepId}/${chunkId}.\n` };
276
+ return { ok: false, error: `nimicoding sweep audit refused: chunk not found for ${sweepId}/${chunkId}.\n` };
277
277
  }
278
278
  return { ok: true, chunk, chunkRef: ref };
279
279
  }
@@ -306,12 +306,12 @@ export async function loadLatestLedger(projectRoot, sweepId) {
306
306
  const latestRef = artifactRef("ledger_ref", sweepId, "latest.yaml");
307
307
  const pointer = await loadYamlRef(projectRoot, latestRef);
308
308
  if (!isPlainObject(pointer) || typeof pointer.ledger_ref !== "string") {
309
- return { ok: false, error: `nimicoding audit-sweep refused: latest ledger not found for ${sweepId}.\n` };
309
+ return { ok: false, error: `nimicoding sweep audit refused: latest ledger not found for ${sweepId}.\n` };
310
310
  }
311
311
 
312
312
  const ledger = await loadYamlRef(projectRoot, pointer.ledger_ref);
313
313
  if (!isPlainObject(ledger) || ledger.kind !== "audit-ledger" || ledger.sweep_id !== sweepId) {
314
- return { ok: false, error: `nimicoding audit-sweep refused: latest ledger is malformed for ${sweepId}.\n` };
314
+ return { ok: false, error: `nimicoding sweep audit refused: latest ledger is malformed for ${sweepId}.\n` };
315
315
  }
316
316
 
317
317
  return { ok: true, ledger, ledgerRef: pointer.ledger_ref, pointerRef: latestRef };
@@ -323,7 +323,7 @@ export function inputError(error) {
323
323
 
324
324
  export function ensureIsoTimestamp(value, label = "--verified-at") {
325
325
  if (!isIsoUtcTimestamp(value)) {
326
- return inputError(`nimicoding audit-sweep refused: ${label} must be an ISO-8601 UTC timestamp.\n`);
326
+ return inputError(`nimicoding sweep audit refused: ${label} must be an ISO-8601 UTC timestamp.\n`);
327
327
  }
328
328
  return null;
329
329
  }
@@ -5,12 +5,12 @@ export function formatAuditSweepPayload(payload) {
5
5
  }
6
6
  if (payload.checks) {
7
7
  const failed = payload.checks.filter((entry) => !entry.ok);
8
- return `audit-sweep ${payload.sweepId ?? "result"} validation failed\nchecks: ${payload.checks.length - failed.length}/${payload.checks.length}\nfailed: ${failed.map((entry) => entry.reason).join("; ")}\n`;
8
+ return `sweep audit ${payload.sweepId ?? "result"} validation failed\nchecks: ${payload.checks.length - failed.length}/${payload.checks.length}\nfailed: ${failed.map((entry) => entry.reason).join("; ")}\n`;
9
9
  }
10
- return "audit-sweep failed\n";
10
+ return "sweep audit failed\n";
11
11
  }
12
12
 
13
- const lines = [`audit-sweep ${payload.sweepId ?? payload.auditCloseout?.sweep_id ?? "result"}`];
13
+ const lines = [`sweep audit ${payload.sweepId ?? payload.auditCloseout?.sweep_id ?? "result"}`];
14
14
  for (const [label, value] of [
15
15
  ["plan", payload.planRef],
16
16
  ["chunk", payload.chunkRef],
@@ -297,7 +297,7 @@ function recordClusteredSymptom(store, cluster, finding, fingerprint, classifica
297
297
  export async function ingestAuditSweepChunk(projectRoot, options) {
298
298
  const sweepId = safeSweepId(options.sweepId);
299
299
  if (!sweepId || typeof options.chunkId !== "string") {
300
- return inputError("nimicoding audit-sweep refused: --sweep-id and --chunk-id are required.\n");
300
+ return inputError("nimicoding sweep audit refused: --sweep-id and --chunk-id are required.\n");
301
301
  }
302
302
 
303
303
  const timestampError = ensureIsoTimestamp(options.verifiedAt);
@@ -311,7 +311,7 @@ export async function ingestAuditSweepChunk(projectRoot, options) {
311
311
  }
312
312
  const sourceInfo = await pathExists(source.absolutePath);
313
313
  if (!sourceInfo || !sourceInfo.isFile()) {
314
- return inputError("nimicoding audit-sweep refused: --from must point to an existing JSON file.\n");
314
+ return inputError("nimicoding sweep audit refused: --from must point to an existing JSON file.\n");
315
315
  }
316
316
 
317
317
  return withAuditSweepMutationLock(projectRoot, sweepId, "chunk ingest", async () => {
@@ -324,20 +324,20 @@ export async function ingestAuditSweepChunk(projectRoot, options) {
324
324
  return inputError(chunkResult.error);
325
325
  }
326
326
  if (chunkResult.chunk.state !== "dispatched") {
327
- return inputError("nimicoding audit-sweep refused: chunk ingest requires dispatched state.\n");
327
+ return inputError("nimicoding sweep audit refused: chunk ingest requires dispatched state.\n");
328
328
  }
329
329
 
330
330
  const evidenceJson = await loadJsonFile(source.absolutePath);
331
331
  if (!evidenceJson.ok) {
332
- return inputError("nimicoding audit-sweep refused: --from must contain valid JSON.\n");
332
+ return inputError("nimicoding sweep audit refused: --from must contain valid JSON.\n");
333
333
  }
334
334
  const envelope = validateEvidenceEnvelope(evidenceJson.value, chunkResult.chunk);
335
335
  if (!envelope.ok) {
336
- return inputError(`nimicoding audit-sweep refused: ${envelope.error}.\n`);
336
+ return inputError(`nimicoding sweep audit refused: ${envelope.error}.\n`);
337
337
  }
338
338
  const auditValidity = buildAuditValidityForEvidence(chunkResult.chunk, evidenceJson.value);
339
339
  if (auditValidity.posture === "invalid") {
340
- return inputError(`nimicoding audit-sweep refused: audit evidence is invalid no-finding evidence (${auditValidity.blockers.map((blocker) => blocker.id).join(", ")}).\n`);
340
+ return inputError(`nimicoding sweep audit refused: audit evidence is invalid no-finding evidence (${auditValidity.blockers.map((blocker) => blocker.id).join(", ")}).\n`);
341
341
  }
342
342
 
343
343
  const evidenceRef = artifactRef("evidence_refs", sweepId, `${options.chunkId}.audit-evidence.json`);
@@ -355,11 +355,11 @@ export async function ingestAuditSweepChunk(projectRoot, options) {
355
355
  for (const [index, rawFinding] of evidenceJson.value.findings.entries()) {
356
356
  const normalized = normalizeFinding(rawFinding, index, chunkResult.chunk, sweepId, evidenceRef, options.verifiedAt);
357
357
  if (!normalized.ok) {
358
- return inputError(`nimicoding audit-sweep refused: ${normalized.error}.\n`);
358
+ return inputError(`nimicoding sweep audit refused: ${normalized.error}.\n`);
359
359
  }
360
360
  const clusterResult = deriveFindingCluster(rawFinding, normalized.finding, chunkResult.chunk, planResult.plan);
361
361
  if (!clusterResult.ok) {
362
- return inputError(`nimicoding audit-sweep refused: finding ${index + 1} ${clusterResult.error}.\n`);
362
+ return inputError(`nimicoding sweep audit refused: finding ${index + 1} ${clusterResult.error}.\n`);
363
363
  }
364
364
  if (seen.has(normalized.fingerprint)) {
365
365
  duplicateCount += 1;