@msn-control/liftoff 0.9.9 → 0.10.0
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/DEVELOPER.md +142 -0
- package/README.md +26 -18
- package/assets/governance/single-maintainer-gitflow/policy.md +13 -11
- package/dist/args.js +21 -0
- package/dist/args.js.map +1 -1
- package/dist/artifact-lifecycle.d.ts +1 -1
- package/dist/artifact-lifecycle.js +5 -0
- package/dist/artifact-lifecycle.js.map +1 -1
- package/dist/commands.js +355 -13
- package/dist/commands.js.map +1 -1
- package/dist/file-system.js +100 -13
- package/dist/file-system.js.map +1 -1
- package/dist/governance-activation/activation-state.d.ts +32 -0
- package/dist/governance-activation/activation-state.js +165 -0
- package/dist/governance-activation/activation-state.js.map +1 -0
- package/dist/governance-activation/approvals.d.ts +188 -0
- package/dist/governance-activation/approvals.js +508 -0
- package/dist/governance-activation/approvals.js.map +1 -0
- package/dist/governance-activation/canonical-json.d.ts +3 -0
- package/dist/governance-activation/canonical-json.js +36 -0
- package/dist/governance-activation/canonical-json.js.map +1 -0
- package/dist/governance-activation/commands.d.ts +10 -0
- package/dist/governance-activation/commands.js +1023 -0
- package/dist/governance-activation/commands.js.map +1 -0
- package/dist/governance-activation/compatibility.d.ts +68 -0
- package/dist/governance-activation/compatibility.js +447 -0
- package/dist/governance-activation/compatibility.js.map +1 -0
- package/dist/governance-activation/credentials.d.ts +160 -0
- package/dist/governance-activation/credentials.js +403 -0
- package/dist/governance-activation/credentials.js.map +1 -0
- package/dist/governance-activation/doctor.d.ts +10 -0
- package/dist/governance-activation/doctor.js +379 -0
- package/dist/governance-activation/doctor.js.map +1 -0
- package/dist/governance-activation/evidence.d.ts +49 -0
- package/dist/governance-activation/evidence.js +246 -0
- package/dist/governance-activation/evidence.js.map +1 -0
- package/dist/governance-activation/graph.d.ts +397 -0
- package/dist/governance-activation/graph.js +441 -0
- package/dist/governance-activation/graph.js.map +1 -0
- package/dist/governance-activation/identity.d.ts +35 -0
- package/dist/governance-activation/identity.js +89 -0
- package/dist/governance-activation/identity.js.map +1 -0
- package/dist/governance-activation/index.d.ts +18 -0
- package/dist/governance-activation/index.js +19 -0
- package/dist/governance-activation/index.js.map +1 -0
- package/dist/governance-activation/migration.d.ts +44 -0
- package/dist/governance-activation/migration.js +268 -0
- package/dist/governance-activation/migration.js.map +1 -0
- package/dist/governance-activation/readiness.d.ts +23 -0
- package/dist/governance-activation/readiness.js +158 -0
- package/dist/governance-activation/readiness.js.map +1 -0
- package/dist/governance-activation/reconciliation.d.ts +11 -0
- package/dist/governance-activation/reconciliation.js +58 -0
- package/dist/governance-activation/reconciliation.js.map +1 -0
- package/dist/governance-activation/release-integrity.d.ts +11 -0
- package/dist/governance-activation/release-integrity.js +49 -0
- package/dist/governance-activation/release-integrity.js.map +1 -0
- package/dist/governance-activation/seed-lifecycle.d.ts +116 -0
- package/dist/governance-activation/seed-lifecycle.js +609 -0
- package/dist/governance-activation/seed-lifecycle.js.map +1 -0
- package/dist/governance-activation/source-of-truth.d.ts +164 -0
- package/dist/governance-activation/source-of-truth.js +986 -0
- package/dist/governance-activation/source-of-truth.js.map +1 -0
- package/dist/governance-activation/task-projection.d.ts +21 -0
- package/dist/governance-activation/task-projection.js +75 -0
- package/dist/governance-activation/task-projection.js.map +1 -0
- package/dist/governance-activation/transitions.d.ts +163 -0
- package/dist/governance-activation/transitions.js +2128 -0
- package/dist/governance-activation/transitions.js.map +1 -0
- package/dist/governance-activation/type-contract.d.ts +1 -0
- package/dist/governance-activation/type-contract.js +27 -0
- package/dist/governance-activation/type-contract.js.map +1 -0
- package/dist/governance-activation/types.d.ts +390 -0
- package/dist/governance-activation/types.js +108 -0
- package/dist/governance-activation/types.js.map +1 -0
- package/dist/governance-activation/validators.d.ts +17 -0
- package/dist/governance-activation/validators.js +1305 -0
- package/dist/governance-activation/validators.js.map +1 -0
- package/dist/init-filesystem.js +5 -1
- package/dist/init-filesystem.js.map +1 -1
- package/dist/planner.js +3 -3
- package/dist/planner.js.map +1 -1
- package/dist/power-apps-templates.js +14 -1
- package/dist/power-apps-templates.js.map +1 -1
- package/dist/process-runner.d.ts +3 -0
- package/dist/process-runner.js +68 -10
- package/dist/process-runner.js.map +1 -1
- package/dist/repository-governance.d.ts +13 -3
- package/dist/repository-governance.js +357 -51
- package/dist/repository-governance.js.map +1 -1
- package/dist/telemetry/contract.d.ts +1 -1
- package/dist/telemetry/contract.js +6 -0
- package/dist/telemetry/contract.js.map +1 -1
- package/dist/templates.js +320 -25
- package/dist/templates.js.map +1 -1
- package/dist/types.d.ts +14 -6
- package/docs/cli-reference.md +60 -12
- package/docs/configuration-and-manifests.md +40 -16
- package/docs/existing-repositories.md +22 -11
- package/docs/getting-started.md +46 -10
- package/docs/project-structure.md +34 -5
- package/docs/repository-governance.md +200 -245
- package/docs/safety-and-consent.md +24 -2
- package/docs/troubleshooting.md +55 -4
- package/docs/workloads.md +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
import { readdir } from 'node:fs/promises';
|
|
2
|
+
import { readProjectFile, resolveProjectPath } from '../file-system.js';
|
|
3
|
+
import { loadActivationState } from './activation-state.js';
|
|
4
|
+
import { credentialPolicyPathParts } from './credentials.js';
|
|
5
|
+
import { evidenceContextForPhase, requiredLiveReadbackProviders, validateEvidenceFreshness } from './evidence.js';
|
|
6
|
+
import { canonicalPhaseGraph, currentActivationIdentity, phaseContractDigests } from './graph.js';
|
|
7
|
+
import { planHistoricalActivationStateMigration } from './migration.js';
|
|
8
|
+
import { calculatePhaseReadiness } from './readiness.js';
|
|
9
|
+
import { inspectGovernanceSourceOfTruth } from './source-of-truth.js';
|
|
10
|
+
import { phaseIds } from './types.js';
|
|
11
|
+
import { validateCredentialPolicy, validateEvidenceHeader } from './validators.js';
|
|
12
|
+
const evidencePathParts = ['governance', 'evidence'];
|
|
13
|
+
const terminalEvidenceStates = new Set([
|
|
14
|
+
'verified',
|
|
15
|
+
'failed',
|
|
16
|
+
'inapplicable',
|
|
17
|
+
'retained',
|
|
18
|
+
'disposed'
|
|
19
|
+
]);
|
|
20
|
+
function errorCode(error) {
|
|
21
|
+
if (typeof error !== 'object' || error === null || !('code' in error)) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
const code = error.code;
|
|
25
|
+
return typeof code === 'string' ? code : undefined;
|
|
26
|
+
}
|
|
27
|
+
function errorMessage(error) {
|
|
28
|
+
return error instanceof Error ? error.message : String(error);
|
|
29
|
+
}
|
|
30
|
+
function asRecord(value, pathLabel) {
|
|
31
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
32
|
+
throw new Error(`${pathLabel} must be a JSON object.`);
|
|
33
|
+
}
|
|
34
|
+
return value;
|
|
35
|
+
}
|
|
36
|
+
async function readJsonDirectory(projectRoot, pathParts) {
|
|
37
|
+
const directory = await resolveProjectPath(projectRoot, [...pathParts]);
|
|
38
|
+
let entries;
|
|
39
|
+
try {
|
|
40
|
+
entries = await readdir(directory, { withFileTypes: true });
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
if (errorCode(error) === 'ENOENT') {
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
const values = [];
|
|
49
|
+
for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name, 'en'))) {
|
|
50
|
+
if (!entry.isFile() || !entry.name.endsWith('.json')) {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const filePathParts = [...pathParts, entry.name];
|
|
54
|
+
const bytes = await readProjectFile(projectRoot, filePathParts);
|
|
55
|
+
if (bytes === undefined) {
|
|
56
|
+
throw new Error(`${filePathParts.join('/')} disappeared during doctor inspection.`);
|
|
57
|
+
}
|
|
58
|
+
values.push({
|
|
59
|
+
name: entry.name,
|
|
60
|
+
value: JSON.parse(bytes.toString('utf8'))
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return values;
|
|
64
|
+
}
|
|
65
|
+
function evidenceRecord(value, evidenceId) {
|
|
66
|
+
const record = asRecord(value, `governance/evidence/${evidenceId}.json`);
|
|
67
|
+
if (Object.hasOwn(record, 'header')) {
|
|
68
|
+
return {
|
|
69
|
+
evidenceId: typeof record.evidenceId === 'string' && record.evidenceId.length > 0
|
|
70
|
+
? record.evidenceId
|
|
71
|
+
: evidenceId,
|
|
72
|
+
header: validateEvidenceHeader(record.header),
|
|
73
|
+
...(Array.isArray(record.liveReadback) ? { liveReadback: record.liveReadback } : {}),
|
|
74
|
+
...(Object.hasOwn(record, 'payload') ? { payload: record.payload } : {})
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
evidenceId,
|
|
79
|
+
header: validateEvidenceHeader(value)
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
async function loadEvidenceForDoctor(projectRoot) {
|
|
83
|
+
const entries = await readJsonDirectory(projectRoot, evidencePathParts);
|
|
84
|
+
return entries.map((entry) => evidenceRecord(entry.value, entry.name.replace(/\.json$/u, '')));
|
|
85
|
+
}
|
|
86
|
+
function contextForPhase(phaseId, state, now) {
|
|
87
|
+
const phase = canonicalPhaseGraph.phases.find((entry) => entry.id === phaseId);
|
|
88
|
+
return {
|
|
89
|
+
...evidenceContextForPhase(phaseId, {
|
|
90
|
+
repositoryId: state.repository.id,
|
|
91
|
+
identity: state.identity,
|
|
92
|
+
phaseGraphHash: state.identity.phaseGraphHash,
|
|
93
|
+
now,
|
|
94
|
+
liveReadbackProviders: requiredLiveReadbackProviders(phase)
|
|
95
|
+
}),
|
|
96
|
+
phaseContractDigest: phaseContractDigests(canonicalPhaseGraph)[phaseId]
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function evidenceStaleCheck(state, evidence, now) {
|
|
100
|
+
const stale = [];
|
|
101
|
+
for (const phaseId of phaseIds) {
|
|
102
|
+
const stored = state.phases[phaseId];
|
|
103
|
+
if (!terminalEvidenceStates.has(stored.state)) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
const context = contextForPhase(phaseId, state, now);
|
|
107
|
+
const records = evidence.filter((entry) => entry.header.phaseId === phaseId);
|
|
108
|
+
const valid = records.some((entry) => {
|
|
109
|
+
const result = validateEvidenceFreshness(entry, context);
|
|
110
|
+
return result.valid && result.record.header.result === stored.state;
|
|
111
|
+
});
|
|
112
|
+
if (!valid) {
|
|
113
|
+
stale.push(phaseId);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (stale.length === 0) {
|
|
117
|
+
return undefined;
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
id: 'governance-evidence-stale',
|
|
121
|
+
label: 'governance evidence',
|
|
122
|
+
severity: 'fail',
|
|
123
|
+
state: 'evidence-stale',
|
|
124
|
+
detail: `stored terminal phase(s) lack current authoritative evidence: ${stale.join(', ')}`,
|
|
125
|
+
remedy: 'Rerun liftoff governance verify and provide fresh evidence or an explicit approved reconciliation mapping; do not use checkboxes, filenames, or prose as evidence.'
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function phaseBlockedCheck(state) {
|
|
129
|
+
const blocked = phaseIds.filter((phaseId) => state.phases[phaseId].state === 'blocked' &&
|
|
130
|
+
state.phases[phaseId].blockers.length > 0);
|
|
131
|
+
if (blocked.length === 0) {
|
|
132
|
+
return undefined;
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
id: 'governance-phase-blocked',
|
|
136
|
+
label: 'governance phase',
|
|
137
|
+
severity: 'warn',
|
|
138
|
+
state: 'phase-blocked',
|
|
139
|
+
detail: `${blocked[0]} is blocked: ${state.phases[blocked[0]].blockers[0]}`,
|
|
140
|
+
remedy: 'Resolve the named blocker, then run liftoff governance resume --json.'
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function enforcementIncompleteCheck(state) {
|
|
144
|
+
const approved = state.phases['enforcement-approved'].state === 'approved' ||
|
|
145
|
+
state.phases['enforcement-approved'].state === 'verified';
|
|
146
|
+
const liveReadbackComplete = state.phases['live-readback'].state === 'verified';
|
|
147
|
+
if (!approved || liveReadbackComplete) {
|
|
148
|
+
return undefined;
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
id: 'governance-enforcement-incomplete',
|
|
152
|
+
label: 'governance enforcement',
|
|
153
|
+
severity: 'warn',
|
|
154
|
+
state: 'enforcement-incomplete',
|
|
155
|
+
detail: 'final enforcement was approved but ruleset application/live readback is incomplete',
|
|
156
|
+
remedy: 'Run liftoff governance plan --json and continue only through approved rulesets-applied and live-readback phases.'
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function disposalPendingCheck(state, now) {
|
|
160
|
+
if (state.bootstrapState?.status !== 'retained') {
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
const due = Date.parse(state.bootstrapState.disposeAfter) <= now.getTime();
|
|
164
|
+
return {
|
|
165
|
+
id: 'governance-disposal-pending',
|
|
166
|
+
label: 'bootstrap state disposal',
|
|
167
|
+
severity: due ? 'warn' : 'skipped',
|
|
168
|
+
state: 'disposal-pending',
|
|
169
|
+
detail: due
|
|
170
|
+
? `retained bootstrap state reached disposal date ${state.bootstrapState.disposeAfter}`
|
|
171
|
+
: `retained bootstrap state is not disposable until ${state.bootstrapState.disposeAfter}`,
|
|
172
|
+
remedy: due
|
|
173
|
+
? 'Approve destructive disposal, then run liftoff governance apply-next --execute.'
|
|
174
|
+
: 'Leave retained local bootstrap state untouched until the disposal date.'
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
async function credentialExpiringCheck(projectRoot, now) {
|
|
178
|
+
const bytes = await readProjectFile(projectRoot, [...credentialPolicyPathParts]);
|
|
179
|
+
if (bytes === undefined) {
|
|
180
|
+
return undefined;
|
|
181
|
+
}
|
|
182
|
+
const policy = validateCredentialPolicy(JSON.parse(bytes.toString('utf8')));
|
|
183
|
+
const rotationDue = Date.parse(policy.rotationDueAt) <= now.getTime();
|
|
184
|
+
const expired = Date.parse(policy.expiresAt) <= now.getTime();
|
|
185
|
+
if (policy.status !== 'expiring' && policy.status !== 'expired' && !rotationDue && !expired) {
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
id: 'governance-credential-expiring',
|
|
190
|
+
label: 'governance credential',
|
|
191
|
+
severity: expired || policy.status === 'expired' ? 'fail' : 'warn',
|
|
192
|
+
state: 'credential-expiring',
|
|
193
|
+
detail: `credential policy status ${policy.status}; rotation due ${policy.rotationDueAt}; expires ${policy.expiresAt}`,
|
|
194
|
+
remedy: 'Revoke/rotate the runner preflight credential through the deterministic masked enrollment flow before using credential-ready evidence.'
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
export async function governanceDoctorChecks(projectRoot, manifest, now = new Date()) {
|
|
198
|
+
if (manifest.governance.profile === 'none' || manifest.governance.profile === 'unspecified') {
|
|
199
|
+
return [];
|
|
200
|
+
}
|
|
201
|
+
const checks = [];
|
|
202
|
+
const migration = await planHistoricalActivationStateMigration(projectRoot, now.toISOString());
|
|
203
|
+
if (migration.status === 'blocked') {
|
|
204
|
+
checks.push({
|
|
205
|
+
id: 'governance-identity-incompatible',
|
|
206
|
+
label: 'governance activation identity',
|
|
207
|
+
severity: 'fail',
|
|
208
|
+
state: 'identity-incompatible',
|
|
209
|
+
detail: migration.report.issues[0] ?? 'activation state is not compatible with this Liftoff version',
|
|
210
|
+
remedy: 'Upgrade Liftoff or provide an explicit versioned import mapping. Preserve user-owned state and evidence bytes; never import checkboxes, filenames, or prose as evidence.'
|
|
211
|
+
});
|
|
212
|
+
return checks;
|
|
213
|
+
}
|
|
214
|
+
if (migration.status === 'migrate') {
|
|
215
|
+
checks.push({
|
|
216
|
+
id: 'governance-reconciliation-required',
|
|
217
|
+
label: 'governance reconciliation',
|
|
218
|
+
severity: 'warn',
|
|
219
|
+
state: 'reconciliation-required',
|
|
220
|
+
detail: `historical activation state has an explicit migration mapping to graph ${currentActivationIdentity.phaseGraphHash}`,
|
|
221
|
+
remedy: 'Run liftoff update after review; the migration is staged with managed definitions and preserves evidence bytes.'
|
|
222
|
+
});
|
|
223
|
+
return checks;
|
|
224
|
+
}
|
|
225
|
+
let loaded;
|
|
226
|
+
try {
|
|
227
|
+
loaded = await loadActivationState(projectRoot);
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
checks.push({
|
|
231
|
+
id: 'governance-identity-incompatible',
|
|
232
|
+
label: 'governance activation identity',
|
|
233
|
+
severity: 'fail',
|
|
234
|
+
state: 'identity-incompatible',
|
|
235
|
+
detail: errorMessage(error),
|
|
236
|
+
remedy: 'Restore a supported activation identity tuple and recognized graph hash, or upgrade Liftoff before running setup.'
|
|
237
|
+
});
|
|
238
|
+
return checks;
|
|
239
|
+
}
|
|
240
|
+
let evidence;
|
|
241
|
+
try {
|
|
242
|
+
evidence = await loadEvidenceForDoctor(projectRoot);
|
|
243
|
+
}
|
|
244
|
+
catch (error) {
|
|
245
|
+
checks.push({
|
|
246
|
+
id: 'governance-evidence-stale',
|
|
247
|
+
label: 'governance evidence',
|
|
248
|
+
severity: 'fail',
|
|
249
|
+
state: 'evidence-stale',
|
|
250
|
+
detail: errorMessage(error),
|
|
251
|
+
remedy: 'Repair malformed evidence or provide an explicit approved reconciliation mapping; do not infer evidence from filenames or prose.'
|
|
252
|
+
});
|
|
253
|
+
return checks;
|
|
254
|
+
}
|
|
255
|
+
const state = loaded?.state;
|
|
256
|
+
if (!state) {
|
|
257
|
+
const source = await inspectGovernanceSourceOfTruth({
|
|
258
|
+
projectRoot,
|
|
259
|
+
manifest,
|
|
260
|
+
state: {
|
|
261
|
+
schemaVersion: currentActivationIdentity.activationStateSchemaVersion,
|
|
262
|
+
identity: currentActivationIdentity,
|
|
263
|
+
repository: {
|
|
264
|
+
id: `local:${manifest.project.name}`,
|
|
265
|
+
name: manifest.project.name,
|
|
266
|
+
defaultBranch: 'develop'
|
|
267
|
+
},
|
|
268
|
+
activeChange: null,
|
|
269
|
+
applicability: {
|
|
270
|
+
statePath: 'none',
|
|
271
|
+
privateStagingDast: false,
|
|
272
|
+
credentialRequired: false
|
|
273
|
+
},
|
|
274
|
+
phases: Object.fromEntries(phaseIds.map((phaseId) => [phaseId, {
|
|
275
|
+
state: 'pending',
|
|
276
|
+
updatedAt: '1970-01-01T00:00:00.000Z',
|
|
277
|
+
evidence: [],
|
|
278
|
+
approvals: [],
|
|
279
|
+
blockers: []
|
|
280
|
+
}])),
|
|
281
|
+
createdAt: '1970-01-01T00:00:00.000Z',
|
|
282
|
+
updatedAt: '1970-01-01T00:00:00.000Z'
|
|
283
|
+
},
|
|
284
|
+
evidence
|
|
285
|
+
});
|
|
286
|
+
if (source.status === 'seed-blocked') {
|
|
287
|
+
checks.push({
|
|
288
|
+
id: 'governance-seed-incomplete',
|
|
289
|
+
label: 'governance seed',
|
|
290
|
+
severity: 'warn',
|
|
291
|
+
state: 'seed-incomplete',
|
|
292
|
+
detail: source.blockers.join('; '),
|
|
293
|
+
remedy: 'Run /liftoff-setup to complete, sync, and archive the generated seed before governance activation.'
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
checks.push({
|
|
298
|
+
id: 'governance-activation',
|
|
299
|
+
label: 'governance activation',
|
|
300
|
+
severity: 'skipped',
|
|
301
|
+
state: 'phase-blocked',
|
|
302
|
+
detail: 'no user-owned activation state exists yet',
|
|
303
|
+
remedy: 'Run /liftoff-setup or liftoff governance status --json to start deterministic setup.'
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
return checks;
|
|
307
|
+
}
|
|
308
|
+
const source = await inspectGovernanceSourceOfTruth({ projectRoot, manifest, state, evidence });
|
|
309
|
+
if (source.status === 'seed-blocked') {
|
|
310
|
+
checks.push({
|
|
311
|
+
id: 'governance-seed-incomplete',
|
|
312
|
+
label: 'governance seed',
|
|
313
|
+
severity: 'warn',
|
|
314
|
+
state: 'seed-incomplete',
|
|
315
|
+
detail: source.blockers.join('; '),
|
|
316
|
+
remedy: 'Complete and archive the generated bootstrap seed; update modes do not bypass this gate.'
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
else if (source.status === 'selected' && source.reconciliation.status !== 'not-required') {
|
|
320
|
+
checks.push({
|
|
321
|
+
id: 'governance-reconciliation-required',
|
|
322
|
+
label: 'governance reconciliation',
|
|
323
|
+
severity: source.reconciliation.status === 'blocked' ? 'fail' : 'warn',
|
|
324
|
+
state: 'reconciliation-required',
|
|
325
|
+
detail: source.reconciliation.issues.join('; '),
|
|
326
|
+
remedy: 'Acknowledge the installed activation identity and graph hash in the active governance change before executing affected phases.'
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
else if (source.status === 'ambiguous' || source.status === 'incompatible') {
|
|
330
|
+
checks.push({
|
|
331
|
+
id: 'governance-identity-incompatible',
|
|
332
|
+
label: 'governance activation identity',
|
|
333
|
+
severity: 'fail',
|
|
334
|
+
state: 'identity-incompatible',
|
|
335
|
+
detail: source.blockers.join('; '),
|
|
336
|
+
remedy: 'Resolve active-change ownership with schema-valid metadata or supersession records before continuing setup.'
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
const readiness = calculatePhaseReadiness({
|
|
340
|
+
graph: canonicalPhaseGraph,
|
|
341
|
+
state,
|
|
342
|
+
approvals: [],
|
|
343
|
+
evidence,
|
|
344
|
+
now
|
|
345
|
+
});
|
|
346
|
+
if (!readiness.identityCompatible) {
|
|
347
|
+
checks.push({
|
|
348
|
+
id: 'governance-identity-incompatible',
|
|
349
|
+
label: 'governance activation identity',
|
|
350
|
+
severity: 'fail',
|
|
351
|
+
state: 'identity-incompatible',
|
|
352
|
+
detail: readiness.identityBlocker ?? 'activation identity tuple is not compatible',
|
|
353
|
+
remedy: 'Upgrade Liftoff or restore a supported tuple and recognized phase graph hash.'
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
for (const check of [
|
|
357
|
+
evidenceStaleCheck(state, evidence, now),
|
|
358
|
+
phaseBlockedCheck(state),
|
|
359
|
+
await credentialExpiringCheck(projectRoot, now),
|
|
360
|
+
enforcementIncompleteCheck(state),
|
|
361
|
+
disposalPendingCheck(state, now)
|
|
362
|
+
]) {
|
|
363
|
+
if (check) {
|
|
364
|
+
checks.push(check);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
if (checks.length === 0) {
|
|
368
|
+
checks.push({
|
|
369
|
+
id: 'governance-activation',
|
|
370
|
+
label: 'governance activation',
|
|
371
|
+
severity: 'ok',
|
|
372
|
+
state: 'ready',
|
|
373
|
+
detail: 'state, evidence, credentials, source of truth, and compatibility identity are readable',
|
|
374
|
+
remedy: 'Continue with liftoff governance plan --json when a phase is ready.'
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
return checks;
|
|
378
|
+
}
|
|
379
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/governance-activation/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { ActivationIdentity, EvidenceHeader, EvidenceTransitionIdentity, LiveReadbackProof, LiveReadbackProvider, ManagedPhaseGraph, PhaseEvidenceRecord, PhaseGraphNode, PhaseId } from './types.js';
|
|
2
|
+
export interface EvidenceValidationIssue {
|
|
3
|
+
evidenceId?: string;
|
|
4
|
+
field: string;
|
|
5
|
+
expected?: string | number | boolean;
|
|
6
|
+
actual?: string | number | boolean;
|
|
7
|
+
message: string;
|
|
8
|
+
}
|
|
9
|
+
export interface EvidenceFreshnessContext {
|
|
10
|
+
repositoryId: string;
|
|
11
|
+
identity: ActivationIdentity;
|
|
12
|
+
phaseGraphHash: string;
|
|
13
|
+
phaseId: PhaseId;
|
|
14
|
+
phaseContractDigest: string;
|
|
15
|
+
baselineSha: string;
|
|
16
|
+
inputDigest: string;
|
|
17
|
+
transition: EvidenceTransitionIdentity;
|
|
18
|
+
now?: Date;
|
|
19
|
+
liveReadbackProviders?: readonly LiveReadbackProvider[];
|
|
20
|
+
}
|
|
21
|
+
export interface ValidatedPhaseEvidenceRecord {
|
|
22
|
+
evidenceId: string;
|
|
23
|
+
header: EvidenceHeader;
|
|
24
|
+
headerDigest: string;
|
|
25
|
+
producedAtEpochMs: number;
|
|
26
|
+
liveReadback: readonly LiveReadbackProof[];
|
|
27
|
+
}
|
|
28
|
+
export interface EvidenceSelectionResult {
|
|
29
|
+
selected: ValidatedPhaseEvidenceRecord | null;
|
|
30
|
+
issues: readonly EvidenceValidationIssue[];
|
|
31
|
+
ignoredOlderContradictions: readonly string[];
|
|
32
|
+
}
|
|
33
|
+
export declare function evidenceHeaderDigest(header: EvidenceHeader): string;
|
|
34
|
+
export declare function validateEvidenceFreshness(record: PhaseEvidenceRecord, context: EvidenceFreshnessContext): {
|
|
35
|
+
valid: true;
|
|
36
|
+
record: ValidatedPhaseEvidenceRecord;
|
|
37
|
+
} | {
|
|
38
|
+
valid: false;
|
|
39
|
+
issues: readonly EvidenceValidationIssue[];
|
|
40
|
+
};
|
|
41
|
+
export declare function selectLatestPhaseEvidence(records: readonly PhaseEvidenceRecord[], context: EvidenceFreshnessContext): EvidenceSelectionResult;
|
|
42
|
+
export declare function evidenceContextForPhase(phaseId: PhaseId, overrides?: Partial<Omit<EvidenceFreshnessContext, 'phaseId' | 'phaseContractDigest' | 'transition'>> & {
|
|
43
|
+
transitionDigest?: string;
|
|
44
|
+
}): EvidenceFreshnessContext;
|
|
45
|
+
export declare function requiredLiveReadbackProviders(node: PhaseGraphNode): readonly LiveReadbackProvider[];
|
|
46
|
+
export declare function phaseRequiresLiveReadback(node: PhaseGraphNode): boolean;
|
|
47
|
+
export declare function phaseNode(graph: ManagedPhaseGraph, phaseId: PhaseId): PhaseGraphNode;
|
|
48
|
+
export declare function canonicalEvidenceContextForPhase(phaseId: PhaseId): EvidenceFreshnessContext;
|
|
49
|
+
export declare function emptyEvidenceRecordsByPhase(): Record<PhaseId, readonly PhaseEvidenceRecord[]>;
|