@nimiplatform/nimi-coding 0.2.5 → 0.2.7
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 +23 -0
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/adapters/oh-my-codex/README.md +1 -1
- package/cli/commands/admit-high-risk-decision.mjs +4 -4
- package/cli/constants.mjs +1 -1
- package/cli/help.mjs +1 -1
- package/cli/lib/audit-sweep-runtime/admissions.mjs +118 -0
- package/cli/lib/audit-sweep-runtime/evidence-assignment.mjs +3 -0
- package/cli/lib/audit-sweep-runtime/inventory-spec-chunks.mjs +134 -2
- package/cli/lib/audit-sweep-runtime/inventory.mjs +33 -1
- package/cli/lib/audit-sweep-runtime/validators.mjs +34 -0
- package/cli/lib/closeout.mjs +0 -14
- package/cli/lib/entrypoints.mjs +1 -1
- package/cli/lib/high-risk-admission.mjs +68 -47
- package/cli/lib/internal/contracts-parse-high-risk.mjs +1 -1
- package/cli/lib/internal/doctor-finalize.mjs +1 -28
- package/cli/lib/internal/doctor-format.mjs +0 -1
- package/cli/lib/internal/surface-taxonomy-validators.mjs +0 -34
- package/cli/lib/internal/validators-spec-helpers.mjs +0 -1
- package/config/bootstrap.yaml +1 -1
- package/config/spec-generation-inputs.yaml +1 -1
- package/contracts/audit-chunk.schema.yaml +13 -0
- package/contracts/audit-plan.schema.yaml +15 -0
- package/contracts/high-risk-admission.schema.yaml +4 -4
- package/contracts/migration-inventory.schema.yaml +0 -2
- package/contracts/placement-contract.schema.yaml +1 -8
- package/contracts/shared-enums.yaml +0 -1
- package/contracts/spec-generation-inputs.schema.yaml +2 -2
- package/contracts/surface-taxonomy.schema.yaml +0 -11
- package/contracts/workflow-consumer.schema.yaml +0 -2
- package/methodology/spec-target-truth-profile.yaml +0 -7
- package/package.json +1 -1
- package/spec/_meta/command-gating-matrix.yaml +2 -2
- package/spec/product-scope.yaml +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { realpath, writeFile } from "node:fs/promises";
|
|
1
|
+
import { mkdir, realpath, writeFile } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
|
|
4
4
|
import YAML from "yaml";
|
|
@@ -24,7 +24,23 @@ import { validateExecutionPacket } from "./validators.mjs";
|
|
|
24
24
|
import { isIsoUtcTimestamp, isPlainObject } from "./value-helpers.mjs";
|
|
25
25
|
import { parseYamlText } from "./yaml-helpers.mjs";
|
|
26
26
|
|
|
27
|
-
const
|
|
27
|
+
const ADMISSIONS_EVIDENCE_REF = ".nimi/local/high-risk-admissions.yaml";
|
|
28
|
+
|
|
29
|
+
function emptyAdmissionsEvidence() {
|
|
30
|
+
return {
|
|
31
|
+
admissions: [],
|
|
32
|
+
admission_rules: [
|
|
33
|
+
"explicit_manager_owned_decision_required_before_high_risk_local_evidence",
|
|
34
|
+
"mechanically_valid_admission_identity_required_before_high_risk_local_evidence",
|
|
35
|
+
"product_authority_change_requires_explicit_domain_spec_update",
|
|
36
|
+
],
|
|
37
|
+
semantic_constraints: [
|
|
38
|
+
"local_admission_records_must_not_promote_operational_runtime_state",
|
|
39
|
+
"local_admission_records_must_not_be_used_as_product_authority",
|
|
40
|
+
"local_admission_records_must_use_iso_8601_utc_admitted_at",
|
|
41
|
+
],
|
|
42
|
+
};
|
|
43
|
+
}
|
|
28
44
|
|
|
29
45
|
async function resolveProjectContainedPath(projectRoot, inputPath, artifactLabel) {
|
|
30
46
|
const absolutePath = path.resolve(projectRoot, inputPath);
|
|
@@ -66,8 +82,8 @@ function translateAdmissionReason(reason) {
|
|
|
66
82
|
["attached packet_ref failed mechanical validation", "附加的 packet_ref 未通过机械校验"],
|
|
67
83
|
["attached packet_ref is missing packet_id or topic_id", "附加的 packet_ref 缺少 packet_id 或 topic_id"],
|
|
68
84
|
["Bootstrap or handoff validation is failing; repair doctor errors before semantic admission", "bootstrap 或 handoff 校验失败;请先修复 doctor 报错,再进行语义准入"],
|
|
69
|
-
["
|
|
70
|
-
["Manager-owned local decision is ready for explicit
|
|
85
|
+
["Local admission evidence requires the canonical tree under `.nimi/spec`", "local admission evidence 需要 `.nimi/spec` 下的 canonical tree"],
|
|
86
|
+
["Manager-owned local decision is ready for explicit local admission evidence", "manager 拥有的本地 decision 已准备好写入显式 local admission evidence"],
|
|
71
87
|
]);
|
|
72
88
|
return translations.get(reason) ?? reason;
|
|
73
89
|
}
|
|
@@ -206,15 +222,19 @@ function validateImportedDecisionPayload(payload) {
|
|
|
206
222
|
return { ok: true };
|
|
207
223
|
}
|
|
208
224
|
|
|
209
|
-
async function
|
|
210
|
-
const absolutePath = path.join(projectRoot,
|
|
225
|
+
async function loadAdmissionsEvidence(projectRoot, contract) {
|
|
226
|
+
const absolutePath = path.join(projectRoot, ADMISSIONS_EVIDENCE_REF);
|
|
211
227
|
const text = await readTextIfFile(absolutePath);
|
|
212
228
|
|
|
213
229
|
if (text === null) {
|
|
230
|
+
const parsed = emptyAdmissionsEvidence();
|
|
231
|
+
const validation = validateHighRiskAdmissionsSpec(parsed, contract);
|
|
214
232
|
return {
|
|
215
|
-
ok:
|
|
233
|
+
ok: validation.ok,
|
|
216
234
|
path: absolutePath,
|
|
217
|
-
|
|
235
|
+
parsed,
|
|
236
|
+
reason: validation.ok ? null : validation.reason,
|
|
237
|
+
initialized: true,
|
|
218
238
|
};
|
|
219
239
|
}
|
|
220
240
|
|
|
@@ -226,6 +246,7 @@ async function loadAdmissionsSpec(projectRoot, contract) {
|
|
|
226
246
|
path: absolutePath,
|
|
227
247
|
parsed,
|
|
228
248
|
reason: validation.ok ? null : validation.reason,
|
|
249
|
+
initialized: false,
|
|
229
250
|
};
|
|
230
251
|
}
|
|
231
252
|
|
|
@@ -279,7 +300,7 @@ function upsertAdmissionRecord(existingAdmissions, record) {
|
|
|
279
300
|
};
|
|
280
301
|
}
|
|
281
302
|
|
|
282
|
-
function evaluateAdmissionReadiness(doctorResult,
|
|
303
|
+
function evaluateAdmissionReadiness(doctorResult, admissionsEvidence, packetIdentity) {
|
|
283
304
|
if (!doctorResult.ok || !doctorResult.handoffReadiness.ok) {
|
|
284
305
|
return {
|
|
285
306
|
ok: false,
|
|
@@ -294,14 +315,14 @@ function evaluateAdmissionReadiness(doctorResult, admissionsSpec, packetIdentity
|
|
|
294
315
|
if (!v2Ready && !legacyReady) {
|
|
295
316
|
return {
|
|
296
317
|
ok: false,
|
|
297
|
-
reason: "
|
|
318
|
+
reason: "Local admission evidence requires canonical_tree_ready with declared canonical files present",
|
|
298
319
|
};
|
|
299
320
|
}
|
|
300
321
|
|
|
301
|
-
if (!
|
|
322
|
+
if (!admissionsEvidence.ok) {
|
|
302
323
|
return {
|
|
303
324
|
ok: false,
|
|
304
|
-
reason:
|
|
325
|
+
reason: admissionsEvidence.reason,
|
|
305
326
|
};
|
|
306
327
|
}
|
|
307
328
|
|
|
@@ -314,7 +335,7 @@ function evaluateAdmissionReadiness(doctorResult, admissionsSpec, packetIdentity
|
|
|
314
335
|
|
|
315
336
|
return {
|
|
316
337
|
ok: true,
|
|
317
|
-
reason: "Manager-owned local decision is ready for explicit
|
|
338
|
+
reason: "Manager-owned local decision is ready for explicit local admission evidence",
|
|
318
339
|
};
|
|
319
340
|
}
|
|
320
341
|
|
|
@@ -362,12 +383,12 @@ export async function buildHighRiskAdmissionPayload(projectRoot, options) {
|
|
|
362
383
|
exitCode: 1,
|
|
363
384
|
projectRoot,
|
|
364
385
|
sourceDecisionRef: imported.path,
|
|
365
|
-
semanticTargetRef:
|
|
366
|
-
artifactPath: path.join(projectRoot,
|
|
386
|
+
semanticTargetRef: ADMISSIONS_EVIDENCE_REF,
|
|
387
|
+
artifactPath: path.join(projectRoot, ADMISSIONS_EVIDENCE_REF),
|
|
367
388
|
skill: {
|
|
368
389
|
id: "high_risk_execution",
|
|
369
390
|
},
|
|
370
|
-
localOnly:
|
|
391
|
+
localOnly: true,
|
|
371
392
|
admittedAt: options.admittedAt,
|
|
372
393
|
admissionAction: "blocked",
|
|
373
394
|
admissionRecord: null,
|
|
@@ -380,15 +401,15 @@ export async function buildHighRiskAdmissionPayload(projectRoot, options) {
|
|
|
380
401
|
handoffReadiness: { ok: false },
|
|
381
402
|
delegatedContracts: {},
|
|
382
403
|
},
|
|
383
|
-
|
|
384
|
-
nextAction: `${HIGH_RISK_ADMISSION_CONTRACT_REF} must satisfy the package-owned
|
|
404
|
+
nextEvidenceYaml: null,
|
|
405
|
+
nextAction: `${HIGH_RISK_ADMISSION_CONTRACT_REF} must satisfy the package-owned local admission evidence contract.`,
|
|
385
406
|
};
|
|
386
407
|
}
|
|
387
408
|
|
|
388
409
|
const doctorResult = await inspectDoctorState(projectRoot);
|
|
389
|
-
const
|
|
410
|
+
const admissionsEvidence = await loadAdmissionsEvidence(projectRoot, admissionsContract);
|
|
390
411
|
const packetIdentity = await loadPacketIdentity(projectRoot, imported.payload.attachmentRefs.packet_ref);
|
|
391
|
-
const readiness = evaluateAdmissionReadiness(doctorResult,
|
|
412
|
+
const readiness = evaluateAdmissionReadiness(doctorResult, admissionsEvidence, packetIdentity);
|
|
392
413
|
|
|
393
414
|
const admissionRecord = packetIdentity.ok ? {
|
|
394
415
|
topic_id: packetIdentity.topicId,
|
|
@@ -403,35 +424,35 @@ export async function buildHighRiskAdmissionPayload(projectRoot, options) {
|
|
|
403
424
|
} : null;
|
|
404
425
|
|
|
405
426
|
const nextAdmissions = readiness.ok
|
|
406
|
-
? upsertAdmissionRecord(
|
|
407
|
-
: { admissions:
|
|
427
|
+
? upsertAdmissionRecord(admissionsEvidence.parsed.admissions, admissionRecord)
|
|
428
|
+
: { admissions: admissionsEvidence.parsed?.admissions ?? [], action: "blocked" };
|
|
408
429
|
|
|
409
|
-
const
|
|
430
|
+
const nextEvidenceObject = admissionsEvidence.ok ? {
|
|
410
431
|
admissions: nextAdmissions.admissions,
|
|
411
|
-
admission_rules:
|
|
412
|
-
semantic_constraints:
|
|
432
|
+
admission_rules: admissionsEvidence.parsed.admission_rules,
|
|
433
|
+
semantic_constraints: admissionsEvidence.parsed.semantic_constraints,
|
|
413
434
|
} : null;
|
|
414
|
-
const
|
|
435
|
+
const nextEvidenceValidation = nextEvidenceObject ? validateHighRiskAdmissionsSpec(nextEvidenceObject, admissionsContract) : { ok: false };
|
|
415
436
|
|
|
416
437
|
return {
|
|
417
438
|
contractVersion: HIGH_RISK_ADMISSION_PAYLOAD_CONTRACT_VERSION,
|
|
418
|
-
ok: readiness.ok &&
|
|
419
|
-
exitCode: readiness.ok &&
|
|
439
|
+
ok: readiness.ok && nextEvidenceValidation.ok,
|
|
440
|
+
exitCode: readiness.ok && nextEvidenceValidation.ok ? 0 : 1,
|
|
420
441
|
projectRoot,
|
|
421
442
|
sourceDecisionRef: imported.path,
|
|
422
|
-
semanticTargetRef:
|
|
423
|
-
artifactPath: path.join(projectRoot,
|
|
443
|
+
semanticTargetRef: ADMISSIONS_EVIDENCE_REF,
|
|
444
|
+
artifactPath: path.join(projectRoot, ADMISSIONS_EVIDENCE_REF),
|
|
424
445
|
skill: {
|
|
425
446
|
id: "high_risk_execution",
|
|
426
447
|
},
|
|
427
|
-
localOnly:
|
|
448
|
+
localOnly: true,
|
|
428
449
|
admittedAt: options.admittedAt,
|
|
429
450
|
admissionAction: nextAdmissions.action,
|
|
430
451
|
admissionRecord,
|
|
431
|
-
readiness: readiness.ok && !
|
|
452
|
+
readiness: readiness.ok && !nextEvidenceValidation.ok
|
|
432
453
|
? {
|
|
433
454
|
ok: false,
|
|
434
|
-
reason:
|
|
455
|
+
reason: nextEvidenceValidation.reason,
|
|
435
456
|
}
|
|
436
457
|
: readiness,
|
|
437
458
|
doctor: {
|
|
@@ -439,37 +460,37 @@ export async function buildHighRiskAdmissionPayload(projectRoot, options) {
|
|
|
439
460
|
handoffReadiness: doctorResult.handoffReadiness,
|
|
440
461
|
delegatedContracts: doctorResult.delegatedContracts,
|
|
441
462
|
},
|
|
442
|
-
|
|
443
|
-
nextAction: readiness.ok &&
|
|
444
|
-
? options.
|
|
445
|
-
? `Write
|
|
446
|
-
: `Review the
|
|
447
|
-
: readiness.ok && !
|
|
448
|
-
?
|
|
463
|
+
nextEvidenceYaml: nextEvidenceObject ? YAML.stringify(nextEvidenceObject) : null,
|
|
464
|
+
nextAction: readiness.ok && nextEvidenceValidation.ok
|
|
465
|
+
? options.writeLocal
|
|
466
|
+
? `Write local admission evidence to ${ADMISSIONS_EVIDENCE_REF}.`
|
|
467
|
+
: `Review the local admission evidence preview or write it with --write-local.`
|
|
468
|
+
: readiness.ok && !nextEvidenceValidation.ok
|
|
469
|
+
? nextEvidenceValidation.reason
|
|
449
470
|
: readiness.reason,
|
|
450
471
|
};
|
|
451
472
|
}
|
|
452
473
|
|
|
453
474
|
export async function writeHighRiskAdmission(projectRoot, payload) {
|
|
454
|
-
if (!payload.ok || typeof payload.
|
|
475
|
+
if (!payload.ok || typeof payload.nextEvidenceYaml !== "string") {
|
|
455
476
|
return;
|
|
456
477
|
}
|
|
457
478
|
|
|
458
|
-
await
|
|
479
|
+
await mkdir(path.dirname(path.join(projectRoot, ADMISSIONS_EVIDENCE_REF)), { recursive: true });
|
|
480
|
+
await writeFile(path.join(projectRoot, ADMISSIONS_EVIDENCE_REF), payload.nextEvidenceYaml, "utf8");
|
|
459
481
|
}
|
|
460
482
|
|
|
461
483
|
export function formatHighRiskAdmissionPayload(payload) {
|
|
462
484
|
const nextAction = payload.ok
|
|
463
|
-
? payload.nextAction.startsWith("Write
|
|
464
|
-
? localize(payload.nextAction, `将
|
|
485
|
+
? payload.nextAction.startsWith("Write local admission evidence to ")
|
|
486
|
+
? localize(payload.nextAction, `将 local admission evidence 写入 ${payload.semanticTargetRef}。`)
|
|
465
487
|
: localize(
|
|
466
488
|
payload.nextAction,
|
|
467
|
-
`检查
|
|
489
|
+
`检查 local admission evidence 预览,或使用 ${styleCommand("--write-local")} 将其写入。`,
|
|
468
490
|
)
|
|
469
491
|
: localize(payload.nextAction, translateAdmissionReason(payload.nextAction)
|
|
470
492
|
.replace(`${HIGH_RISK_ADMISSION_CONTRACT_REF} is missing or malformed`, `${HIGH_RISK_ADMISSION_CONTRACT_REF} 缺失或格式错误`)
|
|
471
|
-
.replace(`${HIGH_RISK_ADMISSION_CONTRACT_REF} must satisfy the package-owned
|
|
472
|
-
.replace("cannot read .nimi/spec/high-risk-admissions.yaml", "无法读取 .nimi/spec/high-risk-admissions.yaml"));
|
|
493
|
+
.replace(`${HIGH_RISK_ADMISSION_CONTRACT_REF} must satisfy the package-owned local admission evidence contract.`, `${HIGH_RISK_ADMISSION_CONTRACT_REF} 必须满足包内 local admission evidence 契约。`));
|
|
473
494
|
const lines = [
|
|
474
495
|
styleHeading(`nimicoding admit-high-risk-decision: ${payload.projectRoot}`),
|
|
475
496
|
"",
|
|
@@ -67,7 +67,7 @@ export function parseHighRiskAdmissionContract(text) {
|
|
|
67
67
|
const dispositionEnum = toStringArray(parsed?.disposition_enum);
|
|
68
68
|
|
|
69
69
|
return {
|
|
70
|
-
ok: String(parsed?.truth_contract?.id ?? "") === "
|
|
70
|
+
ok: String(parsed?.truth_contract?.id ?? "") === "local_high_risk_admission_evidence"
|
|
71
71
|
&& arraysEqual(topLevelRequiredKeys, HIGH_RISK_ADMISSION_REQUIRED_TOP_LEVEL_KEYS)
|
|
72
72
|
&& arraysEqual(admissionRequiredFields, HIGH_RISK_ADMISSION_RECORD_REQUIRED_FIELDS)
|
|
73
73
|
&& arraysEqual(dispositionEnum, HIGH_RISK_ADMISSION_DISPOSITION_ENUM),
|
|
@@ -22,12 +22,10 @@ import {
|
|
|
22
22
|
loadHighRiskExecutionContract,
|
|
23
23
|
loadHighRiskSchemaContracts,
|
|
24
24
|
loadSpecReconstructionContract,
|
|
25
|
-
validateHighRiskAdmissionsSpec,
|
|
26
25
|
} from "../contracts.mjs";
|
|
27
26
|
import { loadAuditExecutionArtifactsConfig } from "../audit-execution.mjs";
|
|
28
27
|
import { loadExternalExecutionArtifactsConfig } from "../external-execution.mjs";
|
|
29
|
-
import {
|
|
30
|
-
import { parseYamlText } from "../yaml-helpers.mjs";
|
|
28
|
+
import { readTextIfFile } from "../fs-helpers.mjs";
|
|
31
29
|
import { buildCheck } from "./doctor-state.mjs";
|
|
32
30
|
import {
|
|
33
31
|
buildHostCompatibilityReport,
|
|
@@ -150,30 +148,6 @@ export async function finalizeDoctorState(projectRoot, bootstrapSurface, delegat
|
|
|
150
148
|
),
|
|
151
149
|
);
|
|
152
150
|
|
|
153
|
-
let highRiskAdmissionsTruthValid = true;
|
|
154
|
-
const admissionsTruthRef = ".nimi/spec/high-risk-admissions.yaml";
|
|
155
|
-
const admissionsInfo = await pathExists(path.join(projectRoot, admissionsTruthRef));
|
|
156
|
-
if (admissionsInfo && admissionsInfo.isFile()) {
|
|
157
|
-
const admissionsTruthText = await readTextIfFile(path.join(projectRoot, admissionsTruthRef));
|
|
158
|
-
const admissionsTruthParsed = admissionsTruthText ? parseYamlText(admissionsTruthText) : null;
|
|
159
|
-
const admissionsTruthValidation = highRiskAdmissionContract.ok
|
|
160
|
-
? validateHighRiskAdmissionsSpec(admissionsTruthParsed, highRiskAdmissionContract)
|
|
161
|
-
: {
|
|
162
|
-
ok: false,
|
|
163
|
-
reason: `${HIGH_RISK_ADMISSION_CONTRACT_REF} is missing or malformed`,
|
|
164
|
-
};
|
|
165
|
-
highRiskAdmissionsTruthValid = admissionsTruthValidation.ok;
|
|
166
|
-
checks.push(
|
|
167
|
-
buildCheck(
|
|
168
|
-
"high_risk_admissions_truth",
|
|
169
|
-
admissionsTruthValidation.ok,
|
|
170
|
-
admissionsTruthValidation.ok
|
|
171
|
-
? "Canonical high-risk admissions truth satisfies the packaged admission schema contract"
|
|
172
|
-
: `Canonical high-risk admissions truth drifted: ${admissionsTruthValidation.reason}`,
|
|
173
|
-
),
|
|
174
|
-
);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
151
|
const adapterProfiles = await loadAdmittedAdapterProfiles(delegatedSurface.admittedAdapterIds);
|
|
178
152
|
adapterProfiles.selected = selectAdapterProfile(adapterProfiles, delegatedSurface.selectedAdapterId);
|
|
179
153
|
const adapterProfilesValid = adapterProfiles.invalid.length === 0;
|
|
@@ -312,7 +286,6 @@ export async function finalizeDoctorState(projectRoot, bootstrapSurface, delegat
|
|
|
312
286
|
&& externalHostCompatibilityContract.ok
|
|
313
287
|
&& highRiskExecutionContract.ok
|
|
314
288
|
&& highRiskAdmissionContract.ok
|
|
315
|
-
&& highRiskAdmissionsTruthValid
|
|
316
289
|
&& externalExecutionArtifacts.ok
|
|
317
290
|
&& packageBoundaryTruthOk
|
|
318
291
|
&& (usesV2SurfaceModel || bootstrapSurface.specTreeModel.ok)
|
|
@@ -48,7 +48,6 @@ const DOCTOR_DETAIL_TRANSLATIONS = new Map([
|
|
|
48
48
|
["Packaged high-risk admission schema contract is present and aligned", "包内 high-risk admission schema 契约存在且一致"],
|
|
49
49
|
["external execution artifact landing-path contract is present and structurally valid", "external execution artifact landing-path 契约存在且结构有效"],
|
|
50
50
|
["High-risk execution schema seeds are present and structurally valid", "high-risk execution schema seed 已存在且结构有效"],
|
|
51
|
-
["Canonical high-risk admissions truth satisfies the packaged admission schema contract", "canonical high-risk admissions truth 满足包内 admission schema 契约"],
|
|
52
51
|
["No host adapter selected; vendor-neutral delegated host posture remains active", "未选择 host adapter;vendor-neutral 的 delegated host 姿态仍然生效"],
|
|
53
52
|
["Package-owned adapter profile overlays are present and valid: codex, oh_my_codex, claude", "包内 adapter profile overlay 已存在且有效:codex, oh_my_codex, claude"],
|
|
54
53
|
["Host adapter boundary keeps semantic review in nimicoding and limits handoff to prompt/output/evidence", "host adapter 边界保持 semantic review 在 nimicoding 内,并将 handoff 限制为 prompt/output/evidence"],
|
|
@@ -241,9 +241,6 @@ function classifyRef(ref, text, parsedYaml) {
|
|
|
241
241
|
if (ref === ".nimi/spec/bootstrap-state.yaml") {
|
|
242
242
|
return "lifecycle_progress_state";
|
|
243
243
|
}
|
|
244
|
-
if (ref === ".nimi/spec/high-risk-admissions.yaml") {
|
|
245
|
-
return "product_admission_registry";
|
|
246
|
-
}
|
|
247
244
|
if (ref === ".nimi/spec/product-scope.yaml") {
|
|
248
245
|
return "methodology_authority";
|
|
249
246
|
}
|
|
@@ -404,7 +401,6 @@ function ambiguityFor(requiredConfirmation, surfaceClass) {
|
|
|
404
401
|
|
|
405
402
|
function validationCommandsFor(entryClass) {
|
|
406
403
|
const commands = {
|
|
407
|
-
product_admission_registry: ["pnpm exec nimicoding validate-placement --profile nimi --root .nimi/spec"],
|
|
408
404
|
product_authority_table: ["pnpm exec nimicoding validate-table-family --profile nimi --root .nimi/spec"],
|
|
409
405
|
support_registry: ["pnpm exec nimicoding validate-table-family --profile nimi --root .nimi/spec"],
|
|
410
406
|
thin_guidance: ["pnpm exec nimicoding validate-guidance-bodies --profile nimi --root .nimi/spec"],
|
|
@@ -460,34 +456,6 @@ function validateRefPlacement(ref, surfaceClass, parsedYaml, text, contracts) {
|
|
|
460
456
|
if (surfaceClass === "product_authority" && isMarkdownRef(ref) && GENERATED_REF_PATTERN.test(text)) {
|
|
461
457
|
addError(errors, "derived_view_referenced_as_authority", ref);
|
|
462
458
|
}
|
|
463
|
-
if (surfaceClass === "product_admission_registry") {
|
|
464
|
-
errors.push(...validateProductAdmissionRegistryRef(ref, parsedYaml, text, contracts));
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
return errors;
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
function validateProductAdmissionRegistryRef(ref, parsedYaml, text, contracts) {
|
|
471
|
-
const errors = [];
|
|
472
|
-
if (ref !== ".nimi/spec/high-risk-admissions.yaml") {
|
|
473
|
-
addError(errors, "product_admission_registry_outside_allowed_root", ref);
|
|
474
|
-
return errors;
|
|
475
|
-
}
|
|
476
|
-
if (!isPlainObject(parsedYaml)) {
|
|
477
|
-
addError(errors, "product_admission_registry_invalid_yaml", ref);
|
|
478
|
-
return errors;
|
|
479
|
-
}
|
|
480
|
-
const requiredKeys = Array.isArray(contracts.highRiskAdmission.data?.top_level_required_keys)
|
|
481
|
-
? contracts.highRiskAdmission.data.top_level_required_keys
|
|
482
|
-
: [];
|
|
483
|
-
for (const key of requiredKeys) {
|
|
484
|
-
if (!(key in parsedYaml)) {
|
|
485
|
-
addError(errors, "product_admission_registry_missing_required_key", ref, key);
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
if (/package_name:\s*"?@nimiplatform\/nimi-coding"?|spec_tree_model:|canonical_spec_root:/i.test(text)) {
|
|
489
|
-
addError(errors, "product_admission_registry_contains_package_methodology_body", ref);
|
|
490
|
-
}
|
|
491
459
|
return errors;
|
|
492
460
|
}
|
|
493
461
|
|
|
@@ -738,7 +706,6 @@ export async function classifySpecSurface(projectRoot, options = {}) {
|
|
|
738
706
|
target_class_enum: [
|
|
739
707
|
"product_authority",
|
|
740
708
|
"product_authority_table",
|
|
741
|
-
"product_admission_registry",
|
|
742
709
|
"thin_guidance",
|
|
743
710
|
"derived_view",
|
|
744
711
|
"spec_generation_state",
|
|
@@ -779,7 +746,6 @@ export function isProductAuthoritySurfaceClass(surfaceClass) {
|
|
|
779
746
|
return [
|
|
780
747
|
"product_authority",
|
|
781
748
|
"product_authority_table",
|
|
782
|
-
"product_admission_registry",
|
|
783
749
|
"thin_guidance",
|
|
784
750
|
"host_projection_anchor",
|
|
785
751
|
"support_registry",
|
package/config/bootstrap.yaml
CHANGED
|
@@ -7,7 +7,7 @@ spec_generation_inputs:
|
|
|
7
7
|
docs_inputs:
|
|
8
8
|
- root: .nimi/spec
|
|
9
9
|
class_filter: product_authority_only
|
|
10
|
-
allowed_surface_classes: [product_authority, product_authority_table,
|
|
10
|
+
allowed_surface_classes: [product_authority, product_authority_table, thin_guidance, host_projection_anchor, support_registry]
|
|
11
11
|
forbidden_surface_classes: [derived_view, spec_generation_state, audit_evidence_state, operational_local_artifact, nimicoding_managed_projection, candidate_roadmap, lifecycle_progress_state, methodology_authority]
|
|
12
12
|
owner: nimi_host
|
|
13
13
|
use_as_authority: true
|
|
@@ -22,11 +22,20 @@ optional_top_level_fields:
|
|
|
22
22
|
- authority_kind
|
|
23
23
|
- app_id
|
|
24
24
|
- package_authority_id
|
|
25
|
+
- delegated_projection_id
|
|
25
26
|
- admission_ref
|
|
26
27
|
- authority_root
|
|
28
|
+
- source_authority_root
|
|
27
29
|
- evidence_root_admission_refs
|
|
28
30
|
- admitted_evidence_roots
|
|
29
31
|
- host_authority_projection_refs
|
|
32
|
+
- delegated_evidence_roots
|
|
33
|
+
- delegated_declared_evidence_prefixes
|
|
34
|
+
- delegated_declared_evidence_refs
|
|
35
|
+
- declared_evidence_delegation
|
|
36
|
+
- required_verification_commands
|
|
37
|
+
- declared_evidence_targets
|
|
38
|
+
- declared_evidence_unresolved
|
|
30
39
|
- evidence_roots
|
|
31
40
|
- evidence_inventory
|
|
32
41
|
- evidence_inventory_status
|
|
@@ -60,6 +69,10 @@ hard_constraints:
|
|
|
60
69
|
- spec_authority_chunks_must_declare_coverage_contract
|
|
61
70
|
- spec_authority_chunk_files_remain_authority_refs_only
|
|
62
71
|
- admitted_package_authority_projection_refs_must_be_explicitly_mapped
|
|
72
|
+
- delegated_projection_authority_must_be_explicitly_admitted
|
|
73
|
+
- delegated_declared_evidence_must_name_source_authority_boundary
|
|
74
|
+
- delegated_projection_is_audit_modeling_only_not_source_repo_execution
|
|
75
|
+
- delegated_projection_must_not_resolve_or_mutate_source_authority_refs
|
|
63
76
|
- spec_authority_ingest_requires_one_authority_outcome_per_authority_ref
|
|
64
77
|
- spec_authority_ingest_requires_evidence_files_exactly_matching_evidence_inventory
|
|
65
78
|
- spec_authority_authority_outcome_evidence_refs_must_belong_to_authority_refs_or_evidence_inventory
|
|
@@ -22,6 +22,8 @@ optional_top_level_fields:
|
|
|
22
22
|
- app_slice_admission_ref
|
|
23
23
|
- app_slice_admissions
|
|
24
24
|
- audit_evidence_root_refs
|
|
25
|
+
- delegated_projection_admission_refs
|
|
26
|
+
- delegated_projection_admissions
|
|
25
27
|
- package_authority_admission_refs
|
|
26
28
|
- package_authority_admissions
|
|
27
29
|
- evidence_inventory_hash
|
|
@@ -52,11 +54,20 @@ chunk_optional_fields:
|
|
|
52
54
|
- authority_kind
|
|
53
55
|
- app_id
|
|
54
56
|
- package_authority_id
|
|
57
|
+
- delegated_projection_id
|
|
55
58
|
- admission_ref
|
|
56
59
|
- authority_root
|
|
60
|
+
- source_authority_root
|
|
57
61
|
- evidence_root_admission_refs
|
|
58
62
|
- admitted_evidence_roots
|
|
59
63
|
- host_authority_projection_refs
|
|
64
|
+
- delegated_evidence_roots
|
|
65
|
+
- delegated_declared_evidence_prefixes
|
|
66
|
+
- delegated_declared_evidence_refs
|
|
67
|
+
- declared_evidence_delegation
|
|
68
|
+
- required_verification_commands
|
|
69
|
+
- declared_evidence_targets
|
|
70
|
+
- declared_evidence_unresolved
|
|
60
71
|
- evidence_roots
|
|
61
72
|
- evidence_inventory
|
|
62
73
|
- coverage_contract
|
|
@@ -112,6 +123,10 @@ hard_constraints:
|
|
|
112
123
|
- risk_budget_pause_must_not_mark_unresolved_findings_as_closed
|
|
113
124
|
- risk_budget_pause_blocks_further_dispatch_until_remediation_bundle_or_manager_action
|
|
114
125
|
- admitted_package_authority_projection_refs_must_be_explicitly_mapped
|
|
126
|
+
- delegated_projection_authority_must_be_explicitly_admitted
|
|
127
|
+
- delegated_declared_evidence_must_name_source_authority_boundary
|
|
128
|
+
- delegated_projection_is_audit_modeling_only_not_source_repo_execution
|
|
129
|
+
- delegated_projection_must_not_resolve_or_mutate_source_authority_refs
|
|
115
130
|
- spec_authority_plans_must_materialize_full_evidence_inventory
|
|
116
131
|
- spec_authority_chunks_must_assign_evidence_inventory_to_every_matching_authority_chunk
|
|
117
132
|
- spec_authority_evidence_inventory_files_may_be_reused_across_chunks_without_creating_parallel_truth
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
version: 1
|
|
2
2
|
truth_contract:
|
|
3
|
-
id:
|
|
3
|
+
id: local_high_risk_admission_evidence
|
|
4
4
|
top_level_required_keys:
|
|
5
5
|
- admissions
|
|
6
6
|
- admission_rules
|
|
@@ -18,6 +18,6 @@ disposition_enum:
|
|
|
18
18
|
- partial
|
|
19
19
|
- deferred
|
|
20
20
|
semantic_constraints:
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
21
|
+
- local_admission_records_must_not_promote_operational_runtime_state
|
|
22
|
+
- local_admission_records_must_not_be_used_as_product_authority
|
|
23
|
+
- local_admission_records_must_use_iso_8601_utc_admitted_at
|
|
@@ -32,7 +32,6 @@ disposition_enum:
|
|
|
32
32
|
target_class_enum:
|
|
33
33
|
- product_authority
|
|
34
34
|
- product_authority_table
|
|
35
|
-
- product_admission_registry
|
|
36
35
|
- thin_guidance
|
|
37
36
|
- derived_view
|
|
38
37
|
- spec_generation_state
|
|
@@ -75,6 +74,5 @@ semantic_constraints:
|
|
|
75
74
|
- block_entries_require_user_confirmation_before_migration
|
|
76
75
|
- future_under_spec_must_not_have_keep_disposition
|
|
77
76
|
- nimicoding_managed_projection_must_have_keep_disposition_and_must_not_be_promoted_to_product_authority
|
|
78
|
-
- product_admission_registry_must_not_be_moved_to_package
|
|
79
77
|
- generated_views_default_to_delete_with_stdout_view
|
|
80
78
|
- audit_state_defaults_to_move_local
|
|
@@ -42,12 +42,6 @@ placement_rules:
|
|
|
42
42
|
tracking_policy: tracked_required
|
|
43
43
|
requires_admission: none
|
|
44
44
|
validator_scope: thin_guidance
|
|
45
|
-
- root_pattern: .nimi/spec/high-risk-admissions.yaml
|
|
46
|
-
allowed_classes: [product_admission_registry]
|
|
47
|
-
owner: product_governance
|
|
48
|
-
tracking_policy: tracked_required
|
|
49
|
-
requires_admission: packaged_schema
|
|
50
|
-
validator_scope: product_admission_registry
|
|
51
45
|
- root_pattern: .nimi/spec/_meta/<package>-admission-anchor.yaml
|
|
52
46
|
allowed_classes: [host_projection_anchor]
|
|
53
47
|
owner: host_projection
|
|
@@ -155,9 +149,8 @@ fail_closed_cases:
|
|
|
155
149
|
- tracked_non_product_file_without_admission
|
|
156
150
|
- nimicoding_managed_projection_promoted_to_product_authority
|
|
157
151
|
- future_or_backlog_under_.nimi/spec
|
|
158
|
-
- product_admission_registry_contains_package_methodology_body
|
|
159
152
|
semantic_constraints:
|
|
160
153
|
- path_shape_is_never_sufficient_authority_proof
|
|
161
154
|
- keep_move_package_move_local_split_rewrite_delete_block_must_be_explicit
|
|
162
155
|
- product_semantic_forks_block_for_user_confirmation
|
|
163
|
-
-
|
|
156
|
+
- high_risk_admission_records_stay_local_evidence_while_domain_spec_holds_product_authority
|
|
@@ -23,7 +23,7 @@ document_instance:
|
|
|
23
23
|
docs_inputs:
|
|
24
24
|
- root: .nimi/spec
|
|
25
25
|
class_filter: product_authority_only
|
|
26
|
-
allowed_surface_classes: [product_authority, product_authority_table,
|
|
26
|
+
allowed_surface_classes: [product_authority, product_authority_table, thin_guidance, host_projection_anchor, support_registry]
|
|
27
27
|
forbidden_surface_classes: [derived_view, spec_generation_state, audit_evidence_state, operational_local_artifact, nimicoding_managed_projection, candidate_roadmap, lifecycle_progress_state, methodology_authority]
|
|
28
28
|
owner: nimi_host
|
|
29
29
|
use_as_authority: true
|
|
@@ -93,7 +93,7 @@ baseline_inputs:
|
|
|
93
93
|
docs_inputs:
|
|
94
94
|
- root: .nimi/spec
|
|
95
95
|
class_filter: product_authority_only
|
|
96
|
-
allowed_surface_classes: [product_authority, product_authority_table,
|
|
96
|
+
allowed_surface_classes: [product_authority, product_authority_table, thin_guidance, host_projection_anchor, support_registry]
|
|
97
97
|
forbidden_surface_classes: [derived_view, spec_generation_state, audit_evidence_state, operational_local_artifact, nimicoding_managed_projection, candidate_roadmap, lifecycle_progress_state, methodology_authority]
|
|
98
98
|
owner: nimi_host
|
|
99
99
|
use_as_authority: true
|
|
@@ -41,15 +41,6 @@ taxonomy:
|
|
|
41
41
|
reference_rules: [must_declare_table_family, may_reference_product_authority]
|
|
42
42
|
promotion_rules: [table_family_must_be_product_authority_family]
|
|
43
43
|
fail_closed_cases: [missing_table_family, contains_status_or_coverage_fields, unknown_table_family]
|
|
44
|
-
- class_id: product_admission_registry
|
|
45
|
-
owner_kind: product_governance
|
|
46
|
-
authority_rank: support_only
|
|
47
|
-
allowed_roots: [".nimi/spec/high-risk-admissions.yaml"]
|
|
48
|
-
tracking_policy: tracked_required
|
|
49
|
-
mutability: human_admitted
|
|
50
|
-
reference_rules: [may_reference_topic_packets, must_use_packaged_schema, must_not_copy_package_mechanics]
|
|
51
|
-
promotion_rules: [only_explicit_manager_owned_decision_may_append_rows]
|
|
52
|
-
fail_closed_cases: [contains_package_methodology_body, contains_operational_runtime_state, missing_packaged_schema_ref]
|
|
53
44
|
- class_id: thin_guidance
|
|
54
45
|
owner_kind: product_domain
|
|
55
46
|
authority_rank: guidance_only
|
|
@@ -152,7 +143,6 @@ taxonomy:
|
|
|
152
143
|
class_enum:
|
|
153
144
|
- product_authority
|
|
154
145
|
- product_authority_table
|
|
155
|
-
- product_admission_registry
|
|
156
146
|
- thin_guidance
|
|
157
147
|
- derived_view
|
|
158
148
|
- spec_generation_state
|
|
@@ -191,7 +181,6 @@ semantic_constraints:
|
|
|
191
181
|
- every_candidate_file_gets_exactly_one_surface_class
|
|
192
182
|
- unclassified_files_fail_closed
|
|
193
183
|
- product_authority_classes_must_not_contain_lifecycle_state_or_audit_coverage
|
|
194
|
-
- product_admission_registry_may_store_compact_semantic_admissions_but_not_package_mechanics
|
|
195
184
|
- generated_and_derived_classes_are_never_authority
|
|
196
185
|
- package_methodology_and_package_spec_remain_package_owned
|
|
197
186
|
- nimicoding_managed_projection_may_exist_in_host_project_but_is_not_product_authority
|
|
@@ -51,7 +51,6 @@ workflow_consumers:
|
|
|
51
51
|
required_surface_classes:
|
|
52
52
|
- product_authority
|
|
53
53
|
- product_authority_table
|
|
54
|
-
- product_admission_registry
|
|
55
54
|
- support_registry
|
|
56
55
|
forbidden_surface_classes:
|
|
57
56
|
- derived_view
|
|
@@ -71,7 +70,6 @@ workflow_consumers:
|
|
|
71
70
|
required_surface_classes:
|
|
72
71
|
- product_authority
|
|
73
72
|
- product_authority_table
|
|
74
|
-
- product_admission_registry
|
|
75
73
|
- thin_guidance
|
|
76
74
|
- methodology_authority
|
|
77
75
|
- host_projection_anchor
|
|
@@ -12,7 +12,6 @@ target_truth_profile:
|
|
|
12
12
|
- .nimi/spec/boundaries.yaml
|
|
13
13
|
- .nimi/spec/ownership.yaml
|
|
14
14
|
- .nimi/spec/change-policy.yaml
|
|
15
|
-
- .nimi/spec/high-risk-admissions.yaml
|
|
16
15
|
output_profiles:
|
|
17
16
|
- path: .nimi/spec/authority-map.yaml
|
|
18
17
|
purpose: map_project_authority_surfaces_and_declared_owners
|
|
@@ -38,12 +37,6 @@ target_truth_profile:
|
|
|
38
37
|
- work_types
|
|
39
38
|
- authority_gates
|
|
40
39
|
- parallel_truth_policy
|
|
41
|
-
- path: .nimi/spec/high-risk-admissions.yaml
|
|
42
|
-
purpose: record_explicit_high_risk_semantic_admissions_as_canonical_truth
|
|
43
|
-
minimum_sections:
|
|
44
|
-
- admissions
|
|
45
|
-
- admission_rules
|
|
46
|
-
- semantic_constraints
|
|
47
40
|
hard_constraints:
|
|
48
41
|
- do_not_seed_empty_target_truth_files_during_bootstrap
|
|
49
42
|
- do_not_treat_profile_as_canonical_tree_completion
|