@nimiplatform/nimi-coding 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/cli/commands/audit-sweep.mjs +25 -2
- package/cli/constants.mjs +1 -1
- package/cli/help.mjs +1 -0
- package/cli/lib/audit-sweep-runtime/audit-validity.mjs +18 -3
- package/cli/lib/audit-sweep-runtime/claude-auditor.mjs +647 -0
- package/cli/lib/audit-sweep-runtime/codex-auditor-evidence.mjs +21 -6
- package/cli/lib/audit-sweep-runtime/codex-auditor.mjs +3 -2
- package/cli/lib/audit-sweep-runtime/common.mjs +12 -0
- package/cli/lib/audit-sweep-runtime/inventory-spec-chunks.mjs +106 -8
- package/cli/lib/audit-sweep-runtime/inventory.mjs +2 -4
- package/cli/lib/audit-sweep-runtime/validators.mjs +6 -1
- package/cli/lib/audit-sweep.mjs +1 -0
- package/cli/lib/handoff.mjs +12 -3
- package/cli/lib/internal/doctor-finalize.mjs +32 -11
- package/cli/lib/internal/doctor-format.mjs +3 -2
- package/config/bootstrap.yaml +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,30 @@ All notable changes to `@nimiplatform/nimi-coding` are tracked here.
|
|
|
4
4
|
|
|
5
5
|
This project follows semantic versioning for published npm releases.
|
|
6
6
|
|
|
7
|
+
## 0.2.3
|
|
8
|
+
|
|
9
|
+
- Added `nimicoding sweep audit chunk audit-claude` for Claude-backed sweep
|
|
10
|
+
chunk audits with structured JSON output, evidence ingestion, review, freeze,
|
|
11
|
+
post-chunk validation, and run-ledger events.
|
|
12
|
+
- Hardened Claude auditor output handling by normalizing Claude CLI JSON result
|
|
13
|
+
wrappers, including `structured_output` and replayed raw output files.
|
|
14
|
+
- Tightened audit evidence normalization so AGENTS, README, spec, contract, and
|
|
15
|
+
methodology refs are treated as context rather than implementation evidence.
|
|
16
|
+
- Improved P0/P1 validity and spec-authority evidence mapping so context-only
|
|
17
|
+
chunks can be marked not applicable while declared implementation refs,
|
|
18
|
+
including `.prisma` surfaces, map to the correct owner roots.
|
|
19
|
+
- Updated default audit-sweep exclusions for common tool state and archive
|
|
20
|
+
directories while keeping host-specific `nimi/**` exclusions out of the
|
|
21
|
+
package defaults.
|
|
22
|
+
|
|
23
|
+
## 0.2.2
|
|
24
|
+
|
|
25
|
+
- Fixed v2 doctor lifecycle/readiness derivation so host projects using the
|
|
26
|
+
class-filtered surface model no longer depend on legacy `.nimi/spec/_meta`
|
|
27
|
+
carriers or `.nimi/spec/bootstrap-state.yaml`.
|
|
28
|
+
- Fixed v2 handoff readiness for `doc_spec_audit` so it can run when the
|
|
29
|
+
canonical tree is present but the local generation audit still needs repair.
|
|
30
|
+
|
|
7
31
|
## 0.2.1
|
|
8
32
|
|
|
9
33
|
- Added the `gate_registry` table family for product-owned release gate
|
package/README.md
CHANGED
|
@@ -314,7 +314,7 @@ repository itself keeps the package-owned source directly under
|
|
|
314
314
|
|
|
315
315
|
```bash
|
|
316
316
|
pnpm install
|
|
317
|
-
pnpm test # runs the node:test suite (
|
|
317
|
+
pnpm test # runs the node:test suite (337 tests at 0.2.3)
|
|
318
318
|
pnpm check:pack # npm pack --dry-run
|
|
319
319
|
pnpm check:ci # test + pack + CLI help/version smoke
|
|
320
320
|
```
|
package/README.zh-CN.md
CHANGED
|
@@ -256,7 +256,7 @@ Nimi Coding 坐在你已经用的 AI host *底下*。它是让 AI 做完的工
|
|
|
256
256
|
|
|
257
257
|
```bash
|
|
258
258
|
pnpm install
|
|
259
|
-
pnpm test # 跑 node:test 套件(0.2.
|
|
259
|
+
pnpm test # 跑 node:test 套件(0.2.3 共 337 用例)
|
|
260
260
|
pnpm check:pack # npm pack --dry-run
|
|
261
261
|
pnpm check:ci # test + pack + CLI help/version smoke
|
|
262
262
|
```
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
ingestAuditSweepChunk,
|
|
11
11
|
resolveAuditSweepFinding,
|
|
12
12
|
reviewAuditSweepChunk,
|
|
13
|
+
runClaudeAuditSweepChunk,
|
|
13
14
|
runCodexAuditSweepChunk,
|
|
14
15
|
skipAuditSweepChunk,
|
|
15
16
|
validateAuditSweepArtifacts,
|
|
@@ -150,6 +151,23 @@ function parseChunkAuditCodexOptions(args) {
|
|
|
150
151
|
});
|
|
151
152
|
}
|
|
152
153
|
|
|
154
|
+
function parseChunkAuditClaudeOptions(args) {
|
|
155
|
+
return parseOptions(args, "chunk audit-claude", {
|
|
156
|
+
sweepId: { flag: "--sweep-id", required: true },
|
|
157
|
+
chunkId: { flag: "--chunk-id", required: true },
|
|
158
|
+
dispatchedAt: { flag: "--dispatched-at", required: true },
|
|
159
|
+
verifiedAt: { flag: "--verified-at", required: true },
|
|
160
|
+
reviewedAt: { flag: "--reviewed-at", required: true },
|
|
161
|
+
auditor: { flag: "--auditor" },
|
|
162
|
+
reviewer: { flag: "--reviewer" },
|
|
163
|
+
summary: { flag: "--summary" },
|
|
164
|
+
claudeBin: { flag: "--claude-bin" },
|
|
165
|
+
fromRawOutput: { flag: "--from-raw-output" },
|
|
166
|
+
timeoutMs: { flag: "--timeout-ms", type: "positive-int" },
|
|
167
|
+
json: { default: false },
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
153
171
|
function parseChunkReviewOptions(args) {
|
|
154
172
|
return parseOptions(args, "chunk review", {
|
|
155
173
|
sweepId: { flag: "--sweep-id", required: true },
|
|
@@ -238,6 +256,9 @@ function parseAuditSweepOptions(args) {
|
|
|
238
256
|
if (command === "chunk" && subcommand === "audit-codex") {
|
|
239
257
|
return { ok: true, action: "chunk-audit-codex", parsed: parseChunkAuditCodexOptions(args.slice(2)) };
|
|
240
258
|
}
|
|
259
|
+
if (command === "chunk" && subcommand === "audit-claude") {
|
|
260
|
+
return { ok: true, action: "chunk-audit-claude", parsed: parseChunkAuditClaudeOptions(args.slice(2)) };
|
|
261
|
+
}
|
|
241
262
|
if (command === "chunk" && subcommand === "review") {
|
|
242
263
|
return { ok: true, action: "chunk-review", parsed: parseChunkReviewOptions(args.slice(2)) };
|
|
243
264
|
}
|
|
@@ -269,8 +290,8 @@ function parseAuditSweepOptions(args) {
|
|
|
269
290
|
return {
|
|
270
291
|
ok: false,
|
|
271
292
|
error: `${localize(
|
|
272
|
-
"nimicoding sweep audit refused: expected one of `plan`, `chunk dispatch`, `chunk audit-codex`, `chunk ingest`, `chunk review`, `chunk skip`, `ledger build`, `remediation-map build`, `remediation-map admit`, `finding resolve`, `closeout summary`, `status`, or `validate`.",
|
|
273
|
-
"nimicoding sweep audit 已拒绝:需要使用 `plan`、`chunk dispatch`、`chunk ingest`、`chunk review`、`chunk skip`、`ledger build`、`remediation-map build`、`remediation-map admit`、`finding resolve`、`closeout summary`、`status` 或 `validate`。",
|
|
293
|
+
"nimicoding sweep audit refused: expected one of `plan`, `chunk dispatch`, `chunk audit-codex`, `chunk audit-claude`, `chunk ingest`, `chunk review`, `chunk skip`, `ledger build`, `remediation-map build`, `remediation-map admit`, `finding resolve`, `closeout summary`, `status`, or `validate`.",
|
|
294
|
+
"nimicoding sweep audit 已拒绝:需要使用 `plan`、`chunk dispatch`、`chunk audit-codex`、`chunk audit-claude`、`chunk ingest`、`chunk review`、`chunk skip`、`ledger build`、`remediation-map build`、`remediation-map admit`、`finding resolve`、`closeout summary`、`status` 或 `validate`。",
|
|
274
295
|
)}\n`,
|
|
275
296
|
};
|
|
276
297
|
}
|
|
@@ -303,6 +324,7 @@ export async function runAuditSweep(args) {
|
|
|
303
324
|
"chunk-dispatch": dispatchAuditSweepChunk,
|
|
304
325
|
"chunk-ingest": ingestAuditSweepChunk,
|
|
305
326
|
"chunk-audit-codex": runCodexAuditSweepChunk,
|
|
327
|
+
"chunk-audit-claude": runClaudeAuditSweepChunk,
|
|
306
328
|
"chunk-review": reviewAuditSweepChunk,
|
|
307
329
|
"chunk-skip": skipAuditSweepChunk,
|
|
308
330
|
"ledger-build": buildAuditSweepLedger,
|
|
@@ -328,6 +350,7 @@ export async function runAuditSweep(args) {
|
|
|
328
350
|
|
|
329
351
|
export {
|
|
330
352
|
parseAuditSweepOptions,
|
|
353
|
+
parseChunkAuditClaudeOptions,
|
|
331
354
|
parseChunkAuditCodexOptions,
|
|
332
355
|
parseChunkDispatchOptions,
|
|
333
356
|
parseChunkIngestOptions,
|
package/cli/constants.mjs
CHANGED
package/cli/help.mjs
CHANGED
|
@@ -53,6 +53,7 @@ export function helpText() {
|
|
|
53
53
|
` ${styleCommand("nimicoding sweep audit plan --root <dir> [--criteria <csv>] [--exclude <csv>] [--max-files <n>] [--sweep-id <id>] [--json]")}`,
|
|
54
54
|
` ${styleCommand("nimicoding sweep audit chunk dispatch --sweep-id <id> --chunk-id <chunk-id> --dispatched-at <iso8601> [--auditor <id>] [--json]")}`,
|
|
55
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 audit-claude --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
57
|
` ${styleCommand("nimicoding sweep audit chunk ingest --sweep-id <id> --chunk-id <chunk-id> --from <json> --verified-at <iso8601> [--json]")}`,
|
|
57
58
|
` ${styleCommand("nimicoding sweep audit chunk review --sweep-id <id> --chunk-id <chunk-id> --verdict <pass|fail> --reviewed-at <iso8601> [--summary <text>] [--json]")}`,
|
|
58
59
|
` ${styleCommand("nimicoding sweep audit chunk skip --sweep-id <id> --chunk-id <chunk-id> --reason <text> --skipped-at <iso8601> [--json]")}`,
|
|
@@ -12,6 +12,20 @@ function normalizeFileRef(value) {
|
|
|
12
12
|
return typeof value === "string" ? value.replace(/\\/g, "/") : null;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
function isNonImplementationContextRef(ref) {
|
|
16
|
+
if (typeof ref !== "string") {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
const normalized = ref.replace(/\\/g, "/");
|
|
20
|
+
return /(^|\/)AGENTS\.md$/u.test(normalized)
|
|
21
|
+
|| /(^|\/)README\.md$/u.test(normalized)
|
|
22
|
+
|| normalized.startsWith(".nimi/spec/")
|
|
23
|
+
|| normalized.startsWith(".nimi/contracts/")
|
|
24
|
+
|| normalized.startsWith(".nimi/methodology/")
|
|
25
|
+
|| normalized.startsWith("package://@nimiplatform/nimi-coding/methodology/")
|
|
26
|
+
|| normalized.startsWith("package://@nimiplatform/nimi-coding/spec/");
|
|
27
|
+
}
|
|
28
|
+
|
|
15
29
|
const REQUIRED_P0P1_RULE_CHECK_IDS = [
|
|
16
30
|
"fail_open_or_pseudo_success",
|
|
17
31
|
"partial_coverage_misrepresented_as_complete",
|
|
@@ -111,7 +125,7 @@ function looksSyntheticNoFindingEvidence(evidence) {
|
|
|
111
125
|
|
|
112
126
|
export function p0p1ImplementationRefsForChunk(chunk) {
|
|
113
127
|
if (chunk?.planning_basis === "spec_authority") {
|
|
114
|
-
return normalizeRefs(chunk?.evidence_inventory);
|
|
128
|
+
return normalizeRefs(chunk?.evidence_inventory).filter((ref) => !isNonImplementationContextRef(ref));
|
|
115
129
|
}
|
|
116
130
|
return normalizeRefs(chunk?.files);
|
|
117
131
|
}
|
|
@@ -155,6 +169,7 @@ export function buildAuditValidityForEvidence(chunk, evidence) {
|
|
|
155
169
|
const evidenceInventorySet = new Set(evidenceInventory);
|
|
156
170
|
const p0p1ImplementationRefSet = new Set(p0p1ImplementationRefs);
|
|
157
171
|
const hasImplementationInventory = evidenceInventory.length > 0;
|
|
172
|
+
const hasP0P1ImplementationInventory = p0p1ImplementationRefs.length > 0;
|
|
158
173
|
const findingsEmpty = findings.length === 0;
|
|
159
174
|
const p0p1RecallRequired = criteriaEnableP0P1Recall(chunk?.criteria);
|
|
160
175
|
const hasP0P1Finding = findings.some((finding) => ["critical", "high"].includes(finding?.severity));
|
|
@@ -218,7 +233,7 @@ export function buildAuditValidityForEvidence(chunk, evidence) {
|
|
|
218
233
|
const p0p1NegativeReasoning = typeof evidence?.coverage?.p0p1_negative_reasoning === "string"
|
|
219
234
|
&& evidence.coverage.p0p1_negative_reasoning.trim().length > 0;
|
|
220
235
|
const p0p1EvidenceRefs = normalizeRefs(evidence?.coverage?.p0p1_evidence_refs);
|
|
221
|
-
const p0p1ImplementationNotApplicable = !
|
|
236
|
+
const p0p1ImplementationNotApplicable = !hasP0P1ImplementationInventory
|
|
222
237
|
&& typeof evidence?.coverage?.p0p1_implementation_not_applicable_reason === "string"
|
|
223
238
|
&& evidence.coverage.p0p1_implementation_not_applicable_reason.trim().length > 0;
|
|
224
239
|
const invalidP0P1EvidenceRefs = p0p1EvidenceRefs.filter((ref) => !p0p1ImplementationRefSet.has(ref));
|
|
@@ -248,7 +263,7 @@ export function buildAuditValidityForEvidence(chunk, evidence) {
|
|
|
248
263
|
"P0/P1 no-finding evidence appears to be generated by a script or bulk template rather than a semantic audit.",
|
|
249
264
|
));
|
|
250
265
|
}
|
|
251
|
-
if (
|
|
266
|
+
if (hasP0P1ImplementationInventory) {
|
|
252
267
|
if (!hasSemanticAuditorProvenance(evidence)) {
|
|
253
268
|
blockers.push(diagnostic(
|
|
254
269
|
"auditor_provenance_missing",
|