@nimiplatform/nimi-coding 0.2.5 → 0.2.6
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 +10 -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/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/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
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,16 @@ 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.6
|
|
8
|
+
|
|
9
|
+
- Hard-cut high-risk admission records out of active `.nimi/spec/**`
|
|
10
|
+
authority. Admission records are now local-only evidence under
|
|
11
|
+
`.nimi/local/high-risk-admissions.yaml`; product authority must live in
|
|
12
|
+
domain spec files.
|
|
13
|
+
- Removed the `product_admission_registry` surface class and changed
|
|
14
|
+
`admit-high-risk-decision` to write local evidence through `--write-local`
|
|
15
|
+
instead of writing canonical spec truth.
|
|
16
|
+
|
|
7
17
|
## 0.2.5
|
|
8
18
|
|
|
9
19
|
- Fixed the `cli_version` field in `config/bootstrap.yaml` drifting away from
|
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 (340 tests at 0.2.6)
|
|
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.6 共 340 用例)
|
|
260
260
|
pnpm check:pack # npm pack --dry-run
|
|
261
261
|
pnpm check:ci # test + pack + CLI help/version smoke
|
|
262
262
|
```
|
|
@@ -69,7 +69,7 @@ named host-profile recognition, and explicit manager-owned admission, but
|
|
|
69
69
|
final high-risk completion should still stay bounded by `nimicoding`
|
|
70
70
|
validators, explicit local closeout/decision/ingest/review surfaces, and
|
|
71
71
|
manual manager-side admission rather than automatic semantic promotion. The
|
|
72
|
-
|
|
72
|
+
local admission evidence target is now also shape-validated by a package-owned
|
|
73
73
|
admission schema contract before `nimicoding` accepts it as semantic truth.
|
|
74
74
|
|
|
75
75
|
## Recommended First-User Flow
|
|
@@ -10,7 +10,7 @@ function parseAdmitHighRiskDecisionOptions(args) {
|
|
|
10
10
|
fromPath: null,
|
|
11
11
|
admittedAt: null,
|
|
12
12
|
json: false,
|
|
13
|
-
|
|
13
|
+
writeLocal: false,
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
for (let index = 0; index < args.length; index += 1) {
|
|
@@ -21,8 +21,8 @@ function parseAdmitHighRiskDecisionOptions(args) {
|
|
|
21
21
|
continue;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
if (arg === "--write-
|
|
25
|
-
options.
|
|
24
|
+
if (arg === "--write-local") {
|
|
25
|
+
options.writeLocal = true;
|
|
26
26
|
continue;
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -92,7 +92,7 @@ export async function runAdmitHighRiskDecision(args) {
|
|
|
92
92
|
return payload.exitCode;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
if (payload.ok && parsed.options.
|
|
95
|
+
if (payload.ok && parsed.options.writeLocal) {
|
|
96
96
|
await writeHighRiskAdmission(process.cwd(), payload);
|
|
97
97
|
}
|
|
98
98
|
|
package/cli/constants.mjs
CHANGED
package/cli/help.mjs
CHANGED
|
@@ -71,7 +71,7 @@ export function helpText() {
|
|
|
71
71
|
` ${styleCommand("nimicoding sweep design finalize --run-id <id> [--json]")}`,
|
|
72
72
|
` ${styleCommand("nimicoding sweep design wave-plan --run-id <id> --topic-id <id> [--json]")}`,
|
|
73
73
|
` ${styleCommand("nimicoding sweep design fix-topic --run-id <id> [--slug <slug>] [--title <title>] [--admit-first-wave|--admit-wave-id <id>] [--json]")}`,
|
|
74
|
-
` ${styleCommand("nimicoding admit-high-risk-decision --from <json> --admitted-at <iso8601> [--json] [--write-
|
|
74
|
+
` ${styleCommand("nimicoding admit-high-risk-decision --from <json> --admitted-at <iso8601> [--json] [--write-local]")}`,
|
|
75
75
|
` ${styleCommand("nimicoding closeout --skill <skill-id> --outcome <completed|blocked|failed> --verified-at <iso8601>")}`,
|
|
76
76
|
` ${styleCommand("nimicoding closeout --skill <skill-id> --outcome <completed|blocked|failed> --verified-at <iso8601> --json")}`,
|
|
77
77
|
` ${styleCommand("nimicoding closeout --skill <skill-id> --outcome <completed|blocked|failed> --verified-at <iso8601> --write-local")}`,
|
package/cli/lib/closeout.mjs
CHANGED
|
@@ -44,7 +44,6 @@ function translateCloseoutReason(reason) {
|
|
|
44
44
|
["Completed closeout requires declared canonical tree files to be valid", "完成 closeout 需要声明的 canonical tree 文件有效"],
|
|
45
45
|
["Completed closeout requires a valid `.nimi/local/state/spec-generation/spec-generation-audit.yaml` artifact", "完成 closeout 需要一个有效的 `.nimi/local/state/spec-generation/spec-generation-audit.yaml` 产物"],
|
|
46
46
|
["Completed doc_spec_audit closeout must compare against `.nimi/spec`", "完成 doc_spec_audit closeout 时必须对 `.nimi/spec` 进行比较"],
|
|
47
|
-
["Completed high_risk_execution closeout requires canonical admissions truth to remain `.nimi/spec/high-risk-admissions.yaml`", "完成 high_risk_execution closeout 需要 canonical admissions truth 继续落在 `.nimi/spec/high-risk-admissions.yaml`"],
|
|
48
47
|
["Completed closeout is consistent with the current canonical tree state", "completed closeout 与当前 canonical tree 状态一致"],
|
|
49
48
|
["Imported spec_reconstruction summary must match active spec-generation audit coverage", "导入的 spec_reconstruction 摘要必须与当前 spec-generation audit 覆盖情况一致"],
|
|
50
49
|
]);
|
|
@@ -395,19 +394,6 @@ function evaluateCloseoutReadiness(skillId, outcome, doctorResult, summary) {
|
|
|
395
394
|
}
|
|
396
395
|
}
|
|
397
396
|
|
|
398
|
-
if (rule.completedRequires.high_risk_admissions_truth_ref) {
|
|
399
|
-
const admissionsTruthPath = rule.completedRequires.high_risk_admissions_truth_ref;
|
|
400
|
-
const expectedAdmissionsPath = doctorResult.commandGating.entries.find(
|
|
401
|
-
(entry) => entry.command === "admit-high-risk-decision" && entry.requires?.canonical_admissions_truth,
|
|
402
|
-
)?.requires?.canonical_admissions_truth ?? ".nimi/spec/high-risk-admissions.yaml";
|
|
403
|
-
if (admissionsTruthPath !== expectedAdmissionsPath) {
|
|
404
|
-
return {
|
|
405
|
-
ok: false,
|
|
406
|
-
reason: "Completed high_risk_execution closeout requires canonical admissions truth to remain `.nimi/spec/high-risk-admissions.yaml`",
|
|
407
|
-
};
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
|
|
411
397
|
if (!doctorResult.ok || !doctorResult.handoffReadiness.ok) {
|
|
412
398
|
return {
|
|
413
399
|
ok: false,
|
package/cli/lib/entrypoints.mjs
CHANGED
|
@@ -18,7 +18,7 @@ function managedAgentsBlock() {
|
|
|
18
18
|
- Treat \`/.nimi/spec/**\` as the current repo-wide product authority for this project, and use Git history for retired pre-cutover authority evidence.
|
|
19
19
|
- If .nimi/spec remains bootstrap-only, use .nimi/methodology/spec-reconstruction.yaml and .nimi/config/skills.yaml to drive AI-side truth reconstruction.
|
|
20
20
|
- Treat .nimi/methodology/spec-target-truth-profile.yaml as repo-local support guidance for future governance slices, not as the canonical reconstruction completion target or a guaranteed fresh-bootstrap seed.
|
|
21
|
-
- Treat .nimi/contracts/spec-reconstruction-result.yaml, .nimi/contracts/doc-spec-audit-result.yaml, .nimi/contracts/high-risk-execution-result.yaml, and .nimi/contracts/high-risk-admission.schema.yaml as machine contracts for reconstruction, audit, local-only high-risk closeout summaries, and
|
|
21
|
+
- Treat .nimi/contracts/spec-reconstruction-result.yaml, .nimi/contracts/doc-spec-audit-result.yaml, .nimi/contracts/high-risk-execution-result.yaml, and .nimi/contracts/high-risk-admission.schema.yaml as machine contracts for reconstruction, audit, local-only high-risk closeout summaries, and local-only high-risk admission evidence.
|
|
22
22
|
- Treat .nimi/config/skill-manifest.yaml, .nimi/config/host-profile.yaml, .nimi/config/host-adapter.yaml, .nimi/config/external-execution-artifacts.yaml, .nimi/config/skill-installer.yaml, .nimi/methodology/skill-runtime.yaml, .nimi/methodology/skill-installer-result.yaml, .nimi/methodology/skill-handoff.yaml, and admitted package-owned adapter profiles under adapters/**/profile.yaml as the canonical bridge to any external AI/skill execution.
|
|
23
23
|
- Treat standalone nimicoding as boundary-complete for bootstrap, handoff, validation, projection, and explicit admission only; do not assume packaged run-kernel, provider, scheduler, notification, or automation ownership.
|
|
24
24
|
- Treat .nimi/config/installer-evidence.yaml and .nimi/methodology/skill-installer-summary-projection.yaml as the operational-to-semantic installer projection boundary; do not promote concrete evidence artifacts into semantic truth.
|
|
@@ -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
|
|
@@ -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
|
package/package.json
CHANGED
|
@@ -119,7 +119,7 @@ command_gating_matrix:
|
|
|
119
119
|
completed_requires:
|
|
120
120
|
tree_state: canonical_tree_ready
|
|
121
121
|
canonical_required_files_valid: true
|
|
122
|
-
|
|
122
|
+
high_risk_admission_evidence_ref: .nimi/local/high-risk-admissions.yaml
|
|
123
123
|
- command: ingest-high-risk-execution
|
|
124
124
|
requires:
|
|
125
125
|
tree_state: canonical_tree_ready
|
|
@@ -136,7 +136,7 @@ command_gating_matrix:
|
|
|
136
136
|
- command: admit-high-risk-decision
|
|
137
137
|
requires:
|
|
138
138
|
tree_state: canonical_tree_ready
|
|
139
|
-
|
|
139
|
+
high_risk_admission_evidence: .nimi/local/high-risk-admissions.yaml
|
|
140
140
|
allowed_authority_modes:
|
|
141
141
|
- external_authority_active
|
|
142
142
|
- canonical_cutover_ready
|
package/spec/product-scope.yaml
CHANGED
|
@@ -56,4 +56,4 @@ canonical_spec_model:
|
|
|
56
56
|
- command_behavior_rewrites_not_admitted
|
|
57
57
|
- authority_cutover_not_admitted
|
|
58
58
|
- physical_spec_tree_migration_not_admitted
|
|
59
|
-
|
|
59
|
+
high_risk_admission_evidence: .nimi/local/high-risk-admissions.yaml
|