@msn-control/liftoff 0.10.2 → 0.10.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/DEVELOPER.md +209 -1
  2. package/README.md +12 -1
  3. package/assets/governance/single-maintainer-gitflow/assessment-controls.json +39 -0
  4. package/assets/supported-stack.json +4 -2
  5. package/dist/args.d.ts +2 -2
  6. package/dist/args.js +41 -10
  7. package/dist/args.js.map +1 -1
  8. package/dist/artifact-lifecycle.d.ts +1 -1
  9. package/dist/artifact-lifecycle.js +3 -1
  10. package/dist/artifact-lifecycle.js.map +1 -1
  11. package/dist/cli.js +2 -1
  12. package/dist/cli.js.map +1 -1
  13. package/dist/commands.js +214 -57
  14. package/dist/commands.js.map +1 -1
  15. package/dist/file-system.d.ts +3 -0
  16. package/dist/file-system.js +51 -10
  17. package/dist/file-system.js.map +1 -1
  18. package/dist/governance-activation/commands.js +165 -7
  19. package/dist/governance-activation/commands.js.map +1 -1
  20. package/dist/governance-activation/readiness.d.ts +2 -0
  21. package/dist/governance-activation/readiness.js +77 -12
  22. package/dist/governance-activation/readiness.js.map +1 -1
  23. package/dist/governance-activation/seed-lifecycle.d.ts +19 -1
  24. package/dist/governance-activation/seed-lifecycle.js +158 -7
  25. package/dist/governance-activation/seed-lifecycle.js.map +1 -1
  26. package/dist/governance-activation/transitions.d.ts +9 -0
  27. package/dist/governance-activation/transitions.js +37 -4
  28. package/dist/governance-activation/transitions.js.map +1 -1
  29. package/dist/governance-assessment/catalog.d.ts +8 -0
  30. package/dist/governance-assessment/catalog.js +98 -0
  31. package/dist/governance-assessment/catalog.js.map +1 -0
  32. package/dist/governance-assessment/command.d.ts +10 -0
  33. package/dist/governance-assessment/command.js +81 -0
  34. package/dist/governance-assessment/command.js.map +1 -0
  35. package/dist/governance-assessment/engine.d.ts +19 -0
  36. package/dist/governance-assessment/engine.js +586 -0
  37. package/dist/governance-assessment/engine.js.map +1 -0
  38. package/dist/governance-assessment/index.d.ts +5 -0
  39. package/dist/governance-assessment/index.js +6 -0
  40. package/dist/governance-assessment/index.js.map +1 -0
  41. package/dist/governance-assessment/live-normalize.d.ts +19 -0
  42. package/dist/governance-assessment/live-normalize.js +403 -0
  43. package/dist/governance-assessment/live-normalize.js.map +1 -0
  44. package/dist/governance-assessment/live-transport.d.ts +38 -0
  45. package/dist/governance-assessment/live-transport.js +467 -0
  46. package/dist/governance-assessment/live-transport.js.map +1 -0
  47. package/dist/governance-assessment/live.d.ts +2 -0
  48. package/dist/governance-assessment/live.js +639 -0
  49. package/dist/governance-assessment/live.js.map +1 -0
  50. package/dist/governance-assessment/predicates.d.ts +27 -0
  51. package/dist/governance-assessment/predicates.js +330 -0
  52. package/dist/governance-assessment/predicates.js.map +1 -0
  53. package/dist/governance-assessment/project.d.ts +37 -0
  54. package/dist/governance-assessment/project.js +268 -0
  55. package/dist/governance-assessment/project.js.map +1 -0
  56. package/dist/governance-assessment/readers.d.ts +18 -0
  57. package/dist/governance-assessment/readers.js +130 -0
  58. package/dist/governance-assessment/readers.js.map +1 -0
  59. package/dist/governance-assessment/report.d.ts +23 -0
  60. package/dist/governance-assessment/report.js +266 -0
  61. package/dist/governance-assessment/report.js.map +1 -0
  62. package/dist/governance-assessment/sanitize.d.ts +8 -0
  63. package/dist/governance-assessment/sanitize.js +57 -0
  64. package/dist/governance-assessment/sanitize.js.map +1 -0
  65. package/dist/governance-assessment/types.d.ts +178 -0
  66. package/dist/governance-assessment/types.js +13 -0
  67. package/dist/governance-assessment/types.js.map +1 -0
  68. package/dist/governance-assessment/yaml.d.ts +6 -0
  69. package/dist/governance-assessment/yaml.js +30 -0
  70. package/dist/governance-assessment/yaml.js.map +1 -0
  71. package/dist/migrate-plan.d.ts +4 -0
  72. package/dist/migrate-plan.js +73 -2
  73. package/dist/migrate-plan.js.map +1 -1
  74. package/dist/power-apps-templates.js +4 -0
  75. package/dist/power-apps-templates.js.map +1 -1
  76. package/dist/process-runner.d.ts +4 -0
  77. package/dist/process-runner.js +164 -8
  78. package/dist/process-runner.js.map +1 -1
  79. package/dist/published-verifier.js +6 -0
  80. package/dist/published-verifier.js.map +1 -1
  81. package/dist/release-identity.js +19 -0
  82. package/dist/release-identity.js.map +1 -1
  83. package/dist/repository-governance.d.ts +5 -0
  84. package/dist/repository-governance.js +133 -3
  85. package/dist/repository-governance.js.map +1 -1
  86. package/dist/telemetry/contract.d.ts +2 -0
  87. package/dist/telemetry/contract.js +7 -0
  88. package/dist/telemetry/contract.js.map +1 -1
  89. package/dist/templates.js +74 -29
  90. package/dist/templates.js.map +1 -1
  91. package/docs/cli-reference.md +83 -1
  92. package/docs/configuration-and-manifests.md +11 -1
  93. package/docs/project-structure.md +8 -3
  94. package/docs/repository-governance.md +125 -3
  95. package/docs/telemetry.md +9 -3
  96. package/docs/workloads.md +7 -0
  97. package/package.json +3 -2
@@ -0,0 +1,266 @@
1
+ import { canonicalJson, canonicalSha256 } from '../governance-activation/canonical-json.js';
2
+ import { phaseIds } from '../governance-activation/types.js';
3
+ import { validateActivationIdentity } from '../governance-activation/validators.js';
4
+ import { classifications } from './types.js';
5
+ import { containsSensitiveText, isRecord, jsonValue, notObserved, sanitizeAssessmentText } from './sanitize.js';
6
+ export function classifyFinding(input) {
7
+ const { control } = input;
8
+ const expected = input.expected ?? control.expected;
9
+ const observations = { ...input.observations };
10
+ for (const layer of control.proofLayers) {
11
+ if (!observations[layer])
12
+ observations[layer] = notObserved(`No ${layer} proof was collected.`);
13
+ }
14
+ const missingProof = control.proofLayers.filter((layer) => observations[layer]?.availability === 'not-observed');
15
+ const reasons = control.proofLayers.flatMap((layer) => observations[layer]?.reason ? [`${layer}: ${observations[layer].reason}`] : []);
16
+ let classification;
17
+ let exception = null;
18
+ if (input.applicability === 'inapplicable') {
19
+ classification = 'inapplicable';
20
+ }
21
+ else if (input.applicability === 'unknown' || !control.supported) {
22
+ classification = 'not-observed';
23
+ reasons.push(input.applicability === 'unknown'
24
+ ? 'Applicability has not been established from authoritative workload facts.'
25
+ : 'This control has no supported assessment evaluator; required proof is not being inferred.');
26
+ }
27
+ else {
28
+ const required = control.proofLayers.map((layer) => observations[layer]);
29
+ const absent = required.some((observation) => observation.availability === 'missing');
30
+ const differs = required.some((observation) => observation.availability === 'observed' && canonicalJson(observation.value) !== canonicalJson(expected));
31
+ classification = input.difference ?? (absent ? 'missing' : differs ? 'conflicting' : missingProof.length ? 'not-observed' : 'aligned');
32
+ if (classification !== 'aligned' && classification !== 'not-observed' && missingProof.length === 0 &&
33
+ input.exception && control.exceptionAllowed) {
34
+ classification = 'approved-exception';
35
+ exception = input.exception;
36
+ reasons.push('The observed difference has an exact, current, scoped exception; it is not an exact target match.');
37
+ }
38
+ else if (classification === 'aligned') {
39
+ reasons.push('All required observations match the installed target.');
40
+ }
41
+ }
42
+ if (input.applicability === 'inapplicable')
43
+ reasons.push('Validated workload facts exclude this control.');
44
+ return {
45
+ controlId: control.id, title: control.title, policySection: control.policySection, severity: control.severity,
46
+ scope: input.scope, expected, applicability: input.applicability, classification, observations,
47
+ requiredProof: [...control.proofLayers],
48
+ missingProof: input.applicability === 'inapplicable' ? [] : missingProof,
49
+ unsupported: !control.supported, reasons, affectedPhases: [...control.phaseIds], exception,
50
+ recommendation: {
51
+ ownership: control.ownership,
52
+ approvalRequired: control.ownership !== 'managed-core',
53
+ action: control.recommendation
54
+ }
55
+ };
56
+ }
57
+ export function reportCoverage(findings) {
58
+ const applicable = findings.filter((finding) => finding.applicability === 'applicable');
59
+ return {
60
+ total: findings.length,
61
+ applicable: applicable.length,
62
+ inapplicable: findings.filter((finding) => finding.applicability === 'inapplicable').length,
63
+ unknownApplicability: findings.filter((finding) => finding.applicability === 'unknown').length,
64
+ fullyObserved: applicable.filter((finding) => !finding.unsupported && finding.missingProof.length === 0 && finding.classification !== 'not-observed').length,
65
+ unobserved: findings.filter((finding) => finding.applicability !== 'inapplicable' &&
66
+ (finding.classification === 'not-observed' || finding.missingProof.length > 0)).length,
67
+ unsupported: findings.filter((finding) => finding.applicability !== 'inapplicable' && finding.unsupported).length,
68
+ differences: findings.filter((finding) => ['outdated', 'missing', 'conflicting', 'approved-exception'].includes(finding.classification)).length,
69
+ approvedExceptions: findings.filter((finding) => finding.classification === 'approved-exception').length
70
+ };
71
+ }
72
+ export function assembleAssessmentReport(input) {
73
+ const findings = [...input.findings].sort((left, right) => `${left.controlId}\0${canonicalJson(left.scope)}`.localeCompare(`${right.controlId}\0${canonicalJson(right.scope)}`, 'en'));
74
+ const diagnostics = [...input.diagnostics].sort((a, b) => `${a.code}\0${a.source ?? ''}\0${a.message}`.localeCompare(`${b.code}\0${b.source ?? ''}\0${b.message}`, 'en'));
75
+ const coverage = reportCoverage(findings);
76
+ const failed = input.failed || diagnostics.some((diagnostic) => diagnostic.severity === 'error');
77
+ const outcome = failed ? 'error' : input.disabled ? 'not-applicable'
78
+ : !input.snapshot.inputsStable || coverage.unknownApplicability > 0 || coverage.unobserved > 0 || coverage.unsupported > 0 ? 'partial'
79
+ : coverage.differences > 0 ? 'differences' : findings.length === 0 ? 'error' : 'aligned';
80
+ const report = {
81
+ schemaVersion: 1, command: 'governance assess', readOnly: true, mode: input.mode,
82
+ projectRoot: sanitizeAssessmentText(input.projectRoot), target: input.target,
83
+ projectIdentity: input.projectIdentity, snapshot: input.snapshot, outcome,
84
+ exitCode: outcome === 'error' ? 1 : outcome === 'aligned' || outcome === 'not-applicable' ? 0 : 2,
85
+ coverage, findings, diagnostics, resultDigest: ''
86
+ };
87
+ report.resultDigest = canonicalSha256({ ...report, resultDigest: '' });
88
+ return validateAssessmentReport(report);
89
+ }
90
+ function exact(value, fields, label, optional = []) {
91
+ if (!isRecord(value) || fields.some((key) => !Object.hasOwn(value, key)) ||
92
+ Object.keys(value).some((key) => !fields.includes(key) && !optional.includes(key)))
93
+ throw new Error(`${label} has invalid fields.`);
94
+ return value;
95
+ }
96
+ function enumeration(value, options, label) {
97
+ if (typeof value !== 'string' || !options.includes(value))
98
+ throw new Error(`${label} is invalid.`);
99
+ }
100
+ function string(value, label, nullable = false) {
101
+ if ((nullable && value === null) || typeof value === 'string')
102
+ return;
103
+ throw new Error(`${label} must be a string${nullable ? ' or null' : ''}.`);
104
+ }
105
+ function strings(value, label, allowed) {
106
+ if (!Array.isArray(value) || value.some((entry) => typeof entry !== 'string' || (allowed && !allowed.includes(entry)))) {
107
+ throw new Error(`${label} must contain valid strings.`);
108
+ }
109
+ }
110
+ function boolean(value, label) {
111
+ if (typeof value !== 'boolean')
112
+ throw new Error(`${label} must be a boolean.`);
113
+ }
114
+ function digest(value, label, nullable = false) {
115
+ if (nullable && value === null)
116
+ return;
117
+ if (typeof value !== 'string' || !/^[a-f0-9]{64}$/u.test(value))
118
+ throw new Error(`${label} must be a SHA-256 digest.`);
119
+ }
120
+ function timestamp(value, label) {
121
+ if (typeof value !== 'string' || !Number.isFinite(Date.parse(value)))
122
+ throw new Error(`${label} must be an ISO timestamp.`);
123
+ }
124
+ function validateObservation(value) {
125
+ const observation = exact(value, ['availability', 'value', 'source', 'reason'], 'Observation', ['facts']);
126
+ enumeration(observation.availability, ['observed', 'missing', 'not-observed'], 'Observation availability');
127
+ jsonValue(observation.value);
128
+ if (observation.facts !== undefined)
129
+ jsonValue(observation.facts);
130
+ string(observation.reason, 'Observation reason', true);
131
+ if (observation.source !== null) {
132
+ const source = exact(observation.source, ['kind', 'location', 'digest', 'capturedAt', 'revision', 'line'], 'Observation source');
133
+ enumeration(source.kind, ['package', 'file', 'git', 'evidence', 'github', 'azure'], 'Source kind');
134
+ string(source.location, 'Source location');
135
+ digest(source.digest, 'Source digest', true);
136
+ timestamp(source.capturedAt, 'Source capture time');
137
+ string(source.revision, 'Source revision', true);
138
+ if (source.line !== null && (!Number.isInteger(source.line) || Number(source.line) < 1))
139
+ throw new Error('Source line is invalid.');
140
+ }
141
+ else if (observation.availability !== 'not-observed') {
142
+ throw new Error('Observed facts or absence require provenance.');
143
+ }
144
+ }
145
+ function assertAssessmentReport(value) {
146
+ const report = exact(value, ['schemaVersion', 'command', 'readOnly', 'mode', 'projectRoot', 'target',
147
+ 'projectIdentity', 'snapshot', 'outcome', 'exitCode', 'coverage', 'findings', 'diagnostics', 'resultDigest'], 'Assessment report');
148
+ if (report.schemaVersion !== 1 || report.command !== 'governance assess' || report.readOnly !== true)
149
+ throw new Error('Assessment report identity is invalid.');
150
+ enumeration(report.mode, ['local', 'live'], 'Assessment mode');
151
+ enumeration(report.outcome, ['aligned', 'differences', 'partial', 'not-applicable', 'error'], 'Assessment outcome');
152
+ string(report.projectRoot, 'Project root');
153
+ if (report.target !== null) {
154
+ const target = exact(report.target, ['cliVersion', 'profile', 'policyVersion', 'policyDigest', 'activationIdentity',
155
+ 'phaseGraphHash', 'catalogSchemaVersion', 'catalogDigest'], 'Target');
156
+ if (target.profile !== 'single-maintainer-gitflow' || target.catalogSchemaVersion !== 1)
157
+ throw new Error('Target identity is invalid.');
158
+ for (const key of ['cliVersion', 'policyVersion'])
159
+ string(target[key], `Target ${key}`);
160
+ for (const key of ['policyDigest', 'phaseGraphHash', 'catalogDigest'])
161
+ digest(target[key], `Target ${key}`);
162
+ const identity = validateActivationIdentity(target.activationIdentity);
163
+ if (identity.policyVersion !== target.policyVersion || identity.phaseGraphHash !== target.phaseGraphHash)
164
+ throw new Error('Target version fields disagree.');
165
+ }
166
+ const identity = exact(report.projectIdentity, ['availability', 'manifestVersion', 'cliVersion', 'profile', 'policyVersion', 'recordedActivationIdentity', 'stateSource'], 'Project identity');
167
+ enumeration(identity.availability, ['known', 'unsupported', 'unavailable'], 'Identity availability');
168
+ enumeration(identity.stateSource, ['not-started', 'user', 'unsupported', 'unavailable'], 'State source');
169
+ if (identity.manifestVersion !== null && !Number.isInteger(identity.manifestVersion))
170
+ throw new Error('Manifest version is invalid.');
171
+ string(identity.cliVersion, 'Recorded CLI version', true);
172
+ string(identity.profile, 'Recorded profile', true);
173
+ string(identity.policyVersion, 'Recorded policy version', true);
174
+ jsonValue(identity.recordedActivationIdentity);
175
+ const snapshot = exact(report.snapshot, ['capturedAt', 'repository', 'localHead', 'worktreeDigest', 'inputsStable'], 'Snapshot');
176
+ timestamp(snapshot.capturedAt, 'Snapshot capture time');
177
+ digest(snapshot.worktreeDigest, 'Snapshot digest');
178
+ for (const key of ['repository', 'localHead'])
179
+ string(snapshot[key], `Snapshot ${key}`, true);
180
+ boolean(snapshot.inputsStable, 'Snapshot stability');
181
+ const counts = ['total', 'applicable', 'inapplicable', 'unknownApplicability', 'fullyObserved', 'unobserved', 'unsupported', 'differences', 'approvedExceptions'];
182
+ const coverage = exact(report.coverage, counts, 'Coverage');
183
+ for (const key of counts)
184
+ if (!Number.isInteger(coverage[key]) || Number(coverage[key]) < 0)
185
+ throw new Error(`Coverage ${key} is invalid.`);
186
+ if (!Array.isArray(report.findings) || !Array.isArray(report.diagnostics))
187
+ throw new Error('Findings and diagnostics must be arrays.');
188
+ for (const value of report.findings) {
189
+ const finding = exact(value, ['controlId', 'title', 'policySection', 'severity', 'scope', 'expected', 'applicability',
190
+ 'classification', 'observations', 'requiredProof', 'missingProof', 'unsupported', 'reasons', 'affectedPhases', 'exception', 'recommendation'], 'Finding');
191
+ for (const key of ['controlId', 'title', 'policySection'])
192
+ string(finding[key], `Finding ${key}`);
193
+ enumeration(finding.severity, ['info', 'warning', 'error'], 'Finding severity');
194
+ enumeration(finding.applicability, ['applicable', 'inapplicable', 'unknown'], 'Finding applicability');
195
+ enumeration(finding.classification, classifications, 'Finding classification');
196
+ boolean(finding.unsupported, 'Finding support');
197
+ jsonValue(finding.expected);
198
+ strings(finding.requiredProof, 'Required proof', ['recorded', 'declared', 'live', 'evidence']);
199
+ strings(finding.missingProof, 'Missing proof', ['recorded', 'declared', 'live', 'evidence']);
200
+ strings(finding.reasons, 'Finding reasons');
201
+ strings(finding.affectedPhases, 'Phase references', phaseIds);
202
+ const scope = exact(finding.scope, ['repository', 'environment', 'resource'], 'Finding scope');
203
+ for (const key of Object.keys(scope))
204
+ string(scope[key], `Scope ${key}`, true);
205
+ if (!isRecord(finding.observations) || Object.keys(finding.observations).some((key) => !['recorded', 'declared', 'live', 'evidence'].includes(key))) {
206
+ throw new Error('Finding observations are invalid.');
207
+ }
208
+ for (const observation of Object.values(finding.observations))
209
+ validateObservation(observation);
210
+ if (finding.exception !== null) {
211
+ const exception = exact(finding.exception, ['id', 'expiresAt', 'envelopeDigest'], 'Exception');
212
+ for (const key of Object.keys(exception))
213
+ string(exception[key], `Exception ${key}`);
214
+ }
215
+ const recommendation = exact(finding.recommendation, ['ownership', 'approvalRequired', 'action'], 'Recommendation');
216
+ enumeration(recommendation.ownership, ['managed-core', 'project-owned', 'remote', 'external-authority'], 'Recommendation ownership');
217
+ boolean(recommendation.approvalRequired, 'Recommendation approval');
218
+ string(recommendation.action, 'Recommendation action');
219
+ }
220
+ for (const value of report.diagnostics) {
221
+ const diagnostic = exact(value, ['code', 'severity', 'message', 'source'], 'Diagnostic');
222
+ string(diagnostic.code, 'Diagnostic code');
223
+ string(diagnostic.message, 'Diagnostic message');
224
+ string(diagnostic.source, 'Diagnostic source', true);
225
+ enumeration(diagnostic.severity, ['info', 'warning', 'error'], 'Diagnostic severity');
226
+ }
227
+ digest(report.resultDigest, 'Result digest');
228
+ }
229
+ export function validateAssessmentReport(value) {
230
+ assertAssessmentReport(value);
231
+ if (canonicalJson(reportCoverage(value.findings)) !== canonicalJson(value.coverage))
232
+ throw new Error('Assessment coverage does not match findings.');
233
+ for (const finding of value.findings) {
234
+ const missing = finding.applicability === 'inapplicable' ? [] : finding.requiredProof.filter((layer) => !finding.observations[layer] || finding.observations[layer].availability === 'not-observed');
235
+ if (canonicalJson(missing) !== canonicalJson(finding.missingProof))
236
+ throw new Error('Finding missing-proof inventory is inconsistent.');
237
+ if (finding.classification === 'aligned' && (finding.applicability !== 'applicable' || finding.unsupported ||
238
+ missing.length > 0 || finding.requiredProof.some((layer) => {
239
+ const observation = finding.observations[layer];
240
+ return observation?.availability !== 'observed' || canonicalJson(observation.value) !== canonicalJson(finding.expected);
241
+ })))
242
+ throw new Error('Finding claims alignment without matching required proof.');
243
+ if (finding.classification === 'inapplicable' && finding.applicability !== 'inapplicable')
244
+ throw new Error('Finding invents inapplicability.');
245
+ if (finding.classification === 'approved-exception' && (!finding.exception || missing.length ||
246
+ !Number.isFinite(Date.parse(finding.exception.expiresAt)) || Date.parse(finding.exception.expiresAt) <= Date.parse(value.snapshot.capturedAt))) {
247
+ throw new Error('Finding has no current, fully observed exception.');
248
+ }
249
+ }
250
+ const expectedExit = value.outcome === 'error' ? 1 : ['aligned', 'not-applicable'].includes(value.outcome) ? 0 : 2;
251
+ if (value.exitCode !== expectedExit)
252
+ throw new Error('Assessment exit code does not match outcome.');
253
+ if (value.outcome === 'aligned' && (value.findings.length === 0 || !value.snapshot.inputsStable ||
254
+ value.coverage.unobserved || value.coverage.unsupported || value.coverage.unknownApplicability || value.coverage.differences)) {
255
+ throw new Error('Assessment cannot claim alignment with missing coverage or differences.');
256
+ }
257
+ if (value.outcome === 'not-applicable' && (value.projectIdentity.profile !== 'none' || value.findings.length !== 0)) {
258
+ throw new Error('Disabled assessment outcome does not match project profile.');
259
+ }
260
+ if (value.resultDigest !== canonicalSha256({ ...value, resultDigest: '' }))
261
+ throw new Error('Assessment result digest does not match report.');
262
+ if (containsSensitiveText(JSON.stringify(value)))
263
+ throw new Error('Assessment report contains sensitive data and was withheld.');
264
+ return value;
265
+ }
266
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/governance-assessment/report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { JsonValue, Observation, ObservationSource } from './types.js';
2
+ export declare function containsSensitiveText(text: string): boolean;
3
+ export declare function sanitizeAssessmentText(text: string, limit?: number): string;
4
+ export declare function isRecord(value: unknown): value is Record<string, unknown>;
5
+ export declare function jsonValue(value: unknown, depth?: number): JsonValue;
6
+ export declare function notObserved(reason: string, source?: ObservationSource | null): Observation;
7
+ export declare function observed(value: JsonValue, source: ObservationSource): Observation;
8
+ export declare function source(kind: ObservationSource['kind'], location: string, capturedAt: string, content?: JsonValue, revision?: string | null, line?: number | null): ObservationSource;
@@ -0,0 +1,57 @@
1
+ import { stripVTControlCharacters } from 'node:util';
2
+ import { detectCredentialLeaks } from '../governance-activation/credentials.js';
3
+ import { canonicalSha256 } from '../governance-activation/canonical-json.js';
4
+ const sensitiveText = [
5
+ /\b(?:bearer|basic)\s+[a-z0-9+/_.=-]+/iu,
6
+ /\b(?:password|passwd|client[_-]?secret|access[_-]?token|api[_-]?key|token|secret|signature|sig)\s*["']?\s*[:=]\s*["']?[^;\s"'<>]+/iu,
7
+ /\bnpm_[a-z0-9]{20,}/iu,
8
+ /[a-z][a-z0-9+.-]*:\/\/[^\s/@]+:[^\s/@]+@/iu,
9
+ /\beyJ[a-z0-9_-]+\.[a-z0-9_-]+\.[a-z0-9_-]+/iu
10
+ ];
11
+ export function containsSensitiveText(text) {
12
+ return detectCredentialLeaks([{ source: 'process-log', label: 'assessment', text }]).status === 'compromised' ||
13
+ sensitiveText.some((pattern) => pattern.test(text));
14
+ }
15
+ export function sanitizeAssessmentText(text, limit = 2048) {
16
+ const plain = stripVTControlCharacters(text)
17
+ .replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f-\u009f]/gu, '').trim();
18
+ if (containsSensitiveText(plain))
19
+ return '[withheld: sensitive content]';
20
+ return plain.length > limit ? `${plain.slice(0, limit - 12)} [truncated]` : plain;
21
+ }
22
+ export function isRecord(value) {
23
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
24
+ }
25
+ export function jsonValue(value, depth = 0) {
26
+ if (depth > 12)
27
+ throw new Error('Assessment value exceeds nesting limit.');
28
+ if (value === null || typeof value === 'boolean')
29
+ return value;
30
+ if (typeof value === 'number' && Number.isFinite(value))
31
+ return value;
32
+ if (typeof value === 'string')
33
+ return value;
34
+ if (Array.isArray(value))
35
+ return value.map((entry) => jsonValue(entry, depth + 1));
36
+ if (isRecord(value)) {
37
+ return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, jsonValue(entry, depth + 1)]));
38
+ }
39
+ throw new Error('Assessment values must be JSON data.');
40
+ }
41
+ export function notObserved(reason, source = null) {
42
+ return { availability: 'not-observed', value: null, source, reason: sanitizeAssessmentText(reason) };
43
+ }
44
+ export function observed(value, source) {
45
+ if (containsSensitiveText(JSON.stringify(value)) || containsSensitiveText(source.location)) {
46
+ return notObserved('Observation withheld because sensitive content was detected.');
47
+ }
48
+ return { availability: 'observed', value, source, reason: null };
49
+ }
50
+ export function source(kind, location, capturedAt, content, revision = null, line = null) {
51
+ return {
52
+ kind, location: sanitizeAssessmentText(location), capturedAt,
53
+ digest: content === undefined ? null : canonicalSha256(content),
54
+ revision, line
55
+ };
56
+ }
57
+ //# sourceMappingURL=sanitize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../src/governance-assessment/sanitize.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,178 @@
1
+ import type { ActivationIdentity, PhaseId } from '../governance-activation/types.js';
2
+ import type { CommandRunner } from '../process-runner.js';
3
+ export type JsonValue = null | boolean | number | string | JsonValue[] | {
4
+ [key: string]: JsonValue;
5
+ };
6
+ export declare const classifications: readonly ['aligned', 'outdated', 'missing', 'conflicting', 'approved-exception', 'inapplicable', 'not-observed'];
7
+ export type Classification = typeof classifications[number];
8
+ export type Severity = 'info' | 'warning' | 'error';
9
+ export type Layer = 'recorded' | 'declared' | 'live' | 'evidence';
10
+ export type Ownership = 'managed-core' | 'project-owned' | 'remote' | 'external-authority';
11
+ export type Outcome = 'aligned' | 'differences' | 'partial' | 'not-applicable' | 'error';
12
+ export interface ObservationSource {
13
+ kind: 'package' | 'file' | 'git' | 'evidence' | 'github' | 'azure';
14
+ location: string;
15
+ digest: string | null;
16
+ capturedAt: string;
17
+ revision: string | null;
18
+ line: number | null;
19
+ }
20
+ export interface Observation {
21
+ availability: 'observed' | 'missing' | 'not-observed';
22
+ value: JsonValue;
23
+ source: ObservationSource | null;
24
+ reason: string | null;
25
+ facts?: JsonValue;
26
+ }
27
+ export interface AssessmentDiagnostic {
28
+ code: string;
29
+ severity: Severity;
30
+ message: string;
31
+ source: string | null;
32
+ }
33
+ export interface ControlDefinition {
34
+ id: string;
35
+ title: string;
36
+ policySection: string;
37
+ severity: Severity;
38
+ applicability: 'always' | 'api' | 'private-dast' | 'state-path';
39
+ evaluator: string;
40
+ proofLayers: Layer[];
41
+ expected: JsonValue;
42
+ phaseIds: PhaseId[];
43
+ supported: boolean;
44
+ exceptionAllowed: boolean;
45
+ ownership: Ownership;
46
+ recommendation: string;
47
+ }
48
+ export interface AssessmentCatalog {
49
+ schemaVersion: 1;
50
+ profile: 'single-maintainer-gitflow';
51
+ policyVersion: string;
52
+ policyDigest: string;
53
+ families: string[];
54
+ controls: ControlDefinition[];
55
+ }
56
+ export interface AssessmentTarget {
57
+ cliVersion: string;
58
+ profile: 'single-maintainer-gitflow';
59
+ policyVersion: string;
60
+ policyDigest: string;
61
+ activationIdentity: ActivationIdentity;
62
+ phaseGraphHash: string;
63
+ catalogSchemaVersion: 1;
64
+ catalogDigest: string;
65
+ }
66
+ export interface FindingScope {
67
+ repository: string | null;
68
+ environment: string | null;
69
+ resource: string | null;
70
+ }
71
+ export interface AssessmentFinding {
72
+ controlId: string;
73
+ title: string;
74
+ policySection: string;
75
+ severity: Severity;
76
+ scope: FindingScope;
77
+ expected: JsonValue;
78
+ applicability: 'applicable' | 'inapplicable' | 'unknown';
79
+ classification: Classification;
80
+ observations: Partial<Record<Layer, Observation>>;
81
+ requiredProof: Layer[];
82
+ missingProof: Layer[];
83
+ unsupported: boolean;
84
+ reasons: string[];
85
+ affectedPhases: PhaseId[];
86
+ exception: {
87
+ id: string;
88
+ expiresAt: string;
89
+ envelopeDigest: string;
90
+ } | null;
91
+ recommendation: {
92
+ ownership: Ownership;
93
+ approvalRequired: boolean;
94
+ action: string;
95
+ };
96
+ }
97
+ export interface AssessmentProjectIdentity {
98
+ availability: 'known' | 'unsupported' | 'unavailable';
99
+ manifestVersion: number | null;
100
+ cliVersion: string | null;
101
+ profile: string | null;
102
+ policyVersion: string | null;
103
+ recordedActivationIdentity: JsonValue;
104
+ stateSource: 'not-started' | 'user' | 'unsupported' | 'unavailable';
105
+ }
106
+ export interface AssessmentReport {
107
+ schemaVersion: 1;
108
+ command: 'governance assess';
109
+ readOnly: true;
110
+ mode: 'local' | 'live';
111
+ projectRoot: string;
112
+ target: AssessmentTarget | null;
113
+ projectIdentity: AssessmentProjectIdentity;
114
+ snapshot: {
115
+ capturedAt: string;
116
+ repository: string | null;
117
+ localHead: string | null;
118
+ worktreeDigest: string;
119
+ inputsStable: boolean;
120
+ };
121
+ outcome: Outcome;
122
+ exitCode: 0 | 1 | 2;
123
+ coverage: {
124
+ total: number;
125
+ applicable: number;
126
+ inapplicable: number;
127
+ unknownApplicability: number;
128
+ fullyObserved: number;
129
+ unobserved: number;
130
+ unsupported: number;
131
+ differences: number;
132
+ approvedExceptions: number;
133
+ };
134
+ findings: AssessmentFinding[];
135
+ diagnostics: AssessmentDiagnostic[];
136
+ resultDigest: string;
137
+ }
138
+ export interface AzureAssessmentBinding {
139
+ subscriptionId: string;
140
+ environment: 'dev' | 'staging' | 'prod';
141
+ resourceId: string;
142
+ resourceType: string;
143
+ role: 'state' | 'application' | 'runner-network';
144
+ }
145
+ export interface LiveAssessmentScope {
146
+ repository: {
147
+ owner: string;
148
+ name: string;
149
+ id: string | null;
150
+ } | null;
151
+ refs: string[];
152
+ environments: string[];
153
+ runner: {
154
+ organization: string;
155
+ runnerId: number;
156
+ groupId: number | null;
157
+ networkConfigurationId: string | null;
158
+ } | null;
159
+ azure: AzureAssessmentBinding[];
160
+ }
161
+ export interface LiveAssessmentResult {
162
+ observations: Record<string, Observation>;
163
+ diagnostics: AssessmentDiagnostic[];
164
+ refsStable: boolean;
165
+ }
166
+ export interface LiveAssessmentOptions {
167
+ runner?: CommandRunner;
168
+ now?: () => Date;
169
+ }
170
+ export declare const assessmentLimits: {
171
+ readonly fileBytes: number;
172
+ readonly responseBytes: number;
173
+ readonly requestTimeoutMs: 10000;
174
+ readonly liveDeadlineMs: 60000;
175
+ readonly maxPages: 20;
176
+ readonly retries: 1;
177
+ readonly maxFiles: 500;
178
+ };
@@ -0,0 +1,13 @@
1
+ export const classifications = [
2
+ 'aligned', 'outdated', 'missing', 'conflicting', 'approved-exception', 'inapplicable', 'not-observed'
3
+ ];
4
+ export const assessmentLimits = {
5
+ fileBytes: 1024 * 1024,
6
+ responseBytes: 5 * 1024 * 1024,
7
+ requestTimeoutMs: 10_000,
8
+ liveDeadlineMs: 60_000,
9
+ maxPages: 20,
10
+ retries: 1,
11
+ maxFiles: 500
12
+ };
13
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/governance-assessment/types.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,oBAAoB,EAAE,cAAc,EAAE,cAAc;CAC7F,CAAC;AAuKX,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,SAAS,EAAE,IAAI,GAAG,IAAI;IACtB,aAAa,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI;IAC9B,gBAAgB,EAAE,MAAM;IACxB,cAAc,EAAE,MAAM;IACtB,QAAQ,EAAE,EAAE;IACZ,OAAO,EAAE,CAAC;IACV,QAAQ,EAAE,GAAG;CACL,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface ParsedWorkflow {
2
+ path: string;
3
+ value: Record<string, unknown>;
4
+ lineOf: (key: string) => number;
5
+ }
6
+ export declare function parseAssessmentWorkflow(text: string, path: string): ParsedWorkflow;
@@ -0,0 +1,30 @@
1
+ import { LineCounter, parseDocument } from 'yaml';
2
+ import { AssessmentInputError } from './readers.js';
3
+ import { isRecord } from './sanitize.js';
4
+ export function parseAssessmentWorkflow(text, path) {
5
+ const lineCounter = new LineCounter();
6
+ const document = parseDocument(text, {
7
+ version: '1.2', schema: 'core', uniqueKeys: true, strict: true, customTags: [], lineCounter
8
+ });
9
+ if (document.errors.length || document.warnings.length) {
10
+ throw new AssessmentInputError('malformed-workflow', `Workflow ${path} has invalid keys, tags, or YAML syntax.`, path);
11
+ }
12
+ let value;
13
+ try {
14
+ value = document.toJS({ maxAliasCount: 50 });
15
+ }
16
+ catch {
17
+ throw new AssessmentInputError('malformed-workflow', `Workflow ${path} exceeds safe YAML alias limits.`, path);
18
+ }
19
+ if (!isRecord(value))
20
+ throw new AssessmentInputError('malformed-workflow', `Workflow ${path} must be a YAML object.`, path);
21
+ return {
22
+ path, value,
23
+ lineOf(key) {
24
+ const node = document.get(key, true);
25
+ return typeof node === 'object' && node !== null && 'range' in node && Array.isArray(node.range)
26
+ ? lineCounter.linePos(Number(node.range[0])).line : 1;
27
+ }
28
+ };
29
+ }
30
+ //# sourceMappingURL=yaml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yaml.js","sourceRoot":"","sources":["../../src/governance-assessment/yaml.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAQzC,MAAM,UAAU,uBAAuB,CAAC,IAAY,EAAE,IAAY;IAChE,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;IACtC,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,EAAE;QACnC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,WAAW;KAC5F,CAAC,CAAC;IACH,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QACvD,MAAM,IAAI,oBAAoB,CAAC,oBAAoB,EAAE,YAAY,IAAI,0CAA0C,EAAE,IAAI,CAAC,CAAC;IACzH,CAAC;IACD,IAAI,KAAc,CAAC;IACnB,IAAI,CAAC;QACH,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE,CAAY,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,oBAAoB,CAAC,oBAAoB,EAAE,YAAY,IAAI,kCAAkC,EAAE,IAAI,CAAC,CAAC;IACjH,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,oBAAoB,CAAC,oBAAoB,EAAE,YAAY,IAAI,yBAAyB,EAAE,IAAI,CAAC,CAAC;IAC5H,OAAO;QACL,IAAI,EAAE,KAAK;QACX,MAAM,CAAC,GAAW;YAChB,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACrC,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;gBAC9F,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1D,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -4,7 +4,11 @@ export interface SeededGroup {
4
4
  title: string;
5
5
  tasks: string[];
6
6
  }
7
+ export declare const migrationChangeName = "migrate-to-liftoff";
8
+ export declare const migrationCapabilityId = "legacy-source-adoption";
7
9
  export declare function seedMigrationGroups(inventory: LegacyInventory, plan: ApiProjectPlan): SeededGroup[];
8
10
  export declare function renderMigrationTasks(groups: SeededGroup[]): string;
9
11
  export declare function renderMigrationProposal(plan: ApiProjectPlan, inventory: LegacyInventory): string;
12
+ export declare function renderMigrationDesign(plan: ApiProjectPlan, inventory: LegacyInventory): string;
13
+ export declare function renderMigrationSpec(): string;
10
14
  export declare function renderMigrationChecklist(plan: ApiProjectPlan, inventory: LegacyInventory, groups: SeededGroup[]): string;