@msn-control/liftoff 0.9.8 → 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 +62 -13
- 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 +385 -52
- 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/prerequisites.md +5 -0
- package/docs/project-structure.md +34 -5
- package/docs/repository-governance.md +200 -203
- package/docs/safety-and-consent.md +29 -2
- package/docs/troubleshooting.md +74 -4
- package/docs/workloads.md +1 -1
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-runner.js","sourceRoot":"","sources":["../src/process-runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,aAAa,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"process-runner.js","sourceRoot":"","sources":["../src/process-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,17 +1,27 @@
|
|
|
1
1
|
import type { GeneratedArtifact, ProjectPlan } from './types.js';
|
|
2
2
|
export declare const governancePolicySchemaVersion: 1;
|
|
3
|
-
export declare const governancePolicyVersion: '
|
|
3
|
+
export declare const governancePolicyVersion: '6';
|
|
4
4
|
export declare const governanceContextSchemaVersion: 1;
|
|
5
5
|
export declare const governanceArtifactPaths: {
|
|
6
6
|
readonly policy: readonly ['.liftoff', 'governance', 'policy.md'];
|
|
7
7
|
readonly context: readonly ['.liftoff', 'governance', 'context.json'];
|
|
8
8
|
readonly guide: readonly ['.liftoff', 'governance', 'README.md'];
|
|
9
|
-
readonly
|
|
10
|
-
readonly
|
|
9
|
+
readonly phaseGraph: readonly ['.liftoff', 'governance', 'phase-graph.json'];
|
|
10
|
+
readonly compatibility: readonly ['.liftoff', 'governance', 'compatibility.json'];
|
|
11
|
+
readonly credentialPolicySchema: readonly ['.liftoff', 'governance', 'credential-policy.schema.json'];
|
|
12
|
+
readonly setup: {
|
|
13
|
+
readonly 'github-copilot': readonly ['.github', 'prompts', 'liftoff-setup.prompt.md'];
|
|
14
|
+
readonly claude: readonly ['.claude', 'commands', 'liftoff-setup.md'];
|
|
15
|
+
};
|
|
16
|
+
readonly alias: {
|
|
17
|
+
readonly 'github-copilot': readonly ['.github', 'prompts', 'liftoff-repository-governance.prompt.md'];
|
|
18
|
+
readonly claude: readonly ['.claude', 'commands', 'liftoff-repository-governance.md'];
|
|
19
|
+
};
|
|
11
20
|
};
|
|
12
21
|
export declare function renderCanonicalGovernancePolicy(): string;
|
|
13
22
|
export declare function validateGovernancePolicy(policy: string): void;
|
|
14
23
|
export declare function assertGovernanceContentSafe(content: string): void;
|
|
24
|
+
export declare function renderCredentialPolicySchema(): string;
|
|
15
25
|
export declare function validateGovernanceContext(value: unknown): void;
|
|
16
26
|
export declare function renderGovernanceContext(plan: ProjectPlan): string;
|
|
17
27
|
export declare function buildRepositoryGovernanceArtifacts(plan: ProjectPlan): GeneratedArtifact[];
|
|
@@ -1,22 +1,48 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
2
|
import { supportedStack } from './supported-stack.js';
|
|
3
|
+
import { canonicalJson } from './governance-activation/canonical-json.js';
|
|
4
|
+
import { buildGovernanceCompatibilityMetadata, validateGovernanceCompatibilityMetadata } from './governance-activation/compatibility.js';
|
|
5
|
+
import { canonicalPhaseGraphJson, currentActivationIdentity } from './governance-activation/graph.js';
|
|
6
|
+
import { activationContractVersion, activationStateSchemaVersion, approvalEnvelopeSchemaVersion, credentialPolicySchemaVersion, evidenceHeaderSchemaVersion, governanceActivationPolicyVersion, liftoffActivationPackageVersion, liftoffManifestArtifactVersion, phaseGraphSchemaVersion, supersessionSchemaVersion } from './governance-activation/identity.js';
|
|
7
|
+
import { runnerPreflightDisplayNameTemplate, runnerPreflightOrganizationPermissions, runnerPreflightPatLifetimeDays, runnerPreflightRepositoryPermissions, runnerPreflightRotationLeadDays, runnerPreflightSecretName } from './governance-activation/types.js';
|
|
3
8
|
export const governancePolicySchemaVersion = 1;
|
|
4
|
-
export const governancePolicyVersion = '
|
|
9
|
+
export const governancePolicyVersion = '6';
|
|
5
10
|
export const governanceContextSchemaVersion = 1;
|
|
11
|
+
const governanceManagedCoreLogicalNames = [
|
|
12
|
+
'repository-governance-policy',
|
|
13
|
+
'repository-governance-context',
|
|
14
|
+
'repository-governance-guide',
|
|
15
|
+
'repository-governance-phase-graph',
|
|
16
|
+
'repository-governance-compatibility',
|
|
17
|
+
'repository-governance-credential-policy-schema',
|
|
18
|
+
'liftoff-setup-copilot',
|
|
19
|
+
'liftoff-setup-claude',
|
|
20
|
+
'repository-governance-copilot-launcher',
|
|
21
|
+
'repository-governance-claude-launcher'
|
|
22
|
+
];
|
|
6
23
|
export const governanceArtifactPaths = {
|
|
7
24
|
policy: ['.liftoff', 'governance', 'policy.md'],
|
|
8
25
|
context: ['.liftoff', 'governance', 'context.json'],
|
|
9
26
|
guide: ['.liftoff', 'governance', 'README.md'],
|
|
10
|
-
'
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
'
|
|
19
|
-
|
|
27
|
+
phaseGraph: ['.liftoff', 'governance', 'phase-graph.json'],
|
|
28
|
+
compatibility: ['.liftoff', 'governance', 'compatibility.json'],
|
|
29
|
+
credentialPolicySchema: ['.liftoff', 'governance', 'credential-policy.schema.json'],
|
|
30
|
+
setup: {
|
|
31
|
+
'github-copilot': ['.github', 'prompts', 'liftoff-setup.prompt.md'],
|
|
32
|
+
claude: ['.claude', 'commands', 'liftoff-setup.md']
|
|
33
|
+
},
|
|
34
|
+
alias: {
|
|
35
|
+
'github-copilot': [
|
|
36
|
+
'.github',
|
|
37
|
+
'prompts',
|
|
38
|
+
'liftoff-repository-governance.prompt.md'
|
|
39
|
+
],
|
|
40
|
+
claude: [
|
|
41
|
+
'.claude',
|
|
42
|
+
'commands',
|
|
43
|
+
'liftoff-repository-governance.md'
|
|
44
|
+
]
|
|
45
|
+
}
|
|
20
46
|
};
|
|
21
47
|
const suppliedPolicy = readFileSync(new URL('../assets/governance/single-maintainer-gitflow/policy.md', import.meta.url), 'utf8').replace(/\r\n/g, '\n').trimEnd();
|
|
22
48
|
export function renderCanonicalGovernancePolicy() {
|
|
@@ -28,7 +54,9 @@ export function renderCanonicalGovernancePolicy() {
|
|
|
28
54
|
const requiredPolicyFragments = [
|
|
29
55
|
'schemaVersion: 1',
|
|
30
56
|
'profile: single-maintainer-gitflow',
|
|
31
|
-
'policyVersion: "
|
|
57
|
+
'policyVersion: "6"',
|
|
58
|
+
'capability chapters, not execution order',
|
|
59
|
+
'managed phase graph is the sole execution-order authority',
|
|
32
60
|
'develop` is the integration branch and the **default branch**',
|
|
33
61
|
'main` is production truth',
|
|
34
62
|
'release/X.Y.Z',
|
|
@@ -82,6 +110,26 @@ const requiredPolicyFragments = [
|
|
|
82
110
|
'Dev LRS',
|
|
83
111
|
'ZRS in every environment',
|
|
84
112
|
'30 days read-only after verified remote import',
|
|
113
|
+
'Derive the minimal namespace set',
|
|
114
|
+
'Microsoft.Network',
|
|
115
|
+
'GitHub.Network',
|
|
116
|
+
'resource_provider_registrations = "none"',
|
|
117
|
+
'missing required namespace and no unrelated provider',
|
|
118
|
+
'provider-ready',
|
|
119
|
+
'terminal `Registered` readback',
|
|
120
|
+
'directly or transitively after its namespace registration',
|
|
121
|
+
'retained subscription capabilities',
|
|
122
|
+
'teardown from unregistering them',
|
|
123
|
+
'Register subscription features only for intended capabilities',
|
|
124
|
+
'SubscriptionNotRegisteredForFeature',
|
|
125
|
+
'Do not broaden subscription features',
|
|
126
|
+
'Microsoft.Network/AllowBringYourOwnPublicIpAddress',
|
|
127
|
+
'Do not register the BYOIP feature as a workaround',
|
|
128
|
+
"Validate every network service tag's direction and action",
|
|
129
|
+
'AzurePlatformDNS',
|
|
130
|
+
'used only in a Deny rule',
|
|
131
|
+
'Allow rule for that tag',
|
|
132
|
+
'allow TCP and UDP port 53 to the exact resolver addresses',
|
|
85
133
|
'Production: zone-redundant HA',
|
|
86
134
|
'User-assigned managed identity with OIDC federation',
|
|
87
135
|
'Small — fewer than 1,000 users',
|
|
@@ -136,7 +184,15 @@ const forbiddenPolicyFragments = [
|
|
|
136
184
|
'retain local bootstrap state indefinitely',
|
|
137
185
|
'upload local bootstrap state as a GitHub artifact',
|
|
138
186
|
'delete local bootstrap state immediately after import',
|
|
139
|
-
'retained local state remains an active backend'
|
|
187
|
+
'retained local state remains an active backend',
|
|
188
|
+
'provider registration may remain pending while resources are created',
|
|
189
|
+
'approved minimum `bootstrap-local`; delegated private',
|
|
190
|
+
'register all Azure providers',
|
|
191
|
+
'unregister provider registrations during teardown',
|
|
192
|
+
'resource_provider_registrations = "none" requires no explicit registrations',
|
|
193
|
+
'register AllowBringYourOwnPublicIpAddress for every Standard public IP',
|
|
194
|
+
'Allow AzurePlatformDNS in an outbound NSG rule',
|
|
195
|
+
'register any feature named by SubscriptionNotRegisteredForFeature'
|
|
140
196
|
];
|
|
141
197
|
export function validateGovernancePolicy(policy) {
|
|
142
198
|
const missing = requiredPolicyFragments.filter((fragment) => !policy.includes(fragment));
|
|
@@ -154,6 +210,7 @@ export function validateGovernancePolicy(policy) {
|
|
|
154
210
|
}
|
|
155
211
|
const secretValuePatterns = [
|
|
156
212
|
/\bghp_[A-Za-z0-9]{20,}\b/,
|
|
213
|
+
/\bgh[orsup]_[A-Za-z0-9_]{20,}\b/,
|
|
157
214
|
/\bgithub_pat_[A-Za-z0-9_]{20,}\b/,
|
|
158
215
|
/https:\/\/hooks\.slack\.com\/services\/[A-Za-z0-9/]+/,
|
|
159
216
|
/\bAccountKey=[^;\s]+/i,
|
|
@@ -166,6 +223,187 @@ export function assertGovernanceContentSafe(content) {
|
|
|
166
223
|
}
|
|
167
224
|
}
|
|
168
225
|
}
|
|
226
|
+
function credentialPolicySchema() {
|
|
227
|
+
const activationIdentityProperties = {
|
|
228
|
+
liftoffVersion: { const: liftoffActivationPackageVersion },
|
|
229
|
+
manifestArtifactVersion: { const: liftoffManifestArtifactVersion },
|
|
230
|
+
policyVersion: { const: governanceActivationPolicyVersion },
|
|
231
|
+
activationContractVersion: { const: activationContractVersion },
|
|
232
|
+
phaseGraphSchemaVersion: { const: phaseGraphSchemaVersion },
|
|
233
|
+
phaseGraphHash: { const: currentActivationIdentity.phaseGraphHash },
|
|
234
|
+
activationStateSchemaVersion: { const: activationStateSchemaVersion },
|
|
235
|
+
evidenceHeaderSchemaVersion: { const: evidenceHeaderSchemaVersion },
|
|
236
|
+
approvalEnvelopeSchemaVersion: { const: approvalEnvelopeSchemaVersion },
|
|
237
|
+
supersessionSchemaVersion: { const: supersessionSchemaVersion },
|
|
238
|
+
credentialPolicySchemaVersion: { const: credentialPolicySchemaVersion }
|
|
239
|
+
};
|
|
240
|
+
return {
|
|
241
|
+
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
|
242
|
+
$id: 'https://mission-control.local/liftoff/governance/credential-policy.schema.v1.json',
|
|
243
|
+
title: 'Liftoff governance credential policy v1',
|
|
244
|
+
type: 'object',
|
|
245
|
+
additionalProperties: false,
|
|
246
|
+
required: [
|
|
247
|
+
'schemaVersion',
|
|
248
|
+
'identity',
|
|
249
|
+
'repository',
|
|
250
|
+
'owner',
|
|
251
|
+
'authKind',
|
|
252
|
+
'displayNameTemplate',
|
|
253
|
+
'displayName',
|
|
254
|
+
'secretName',
|
|
255
|
+
'createdAt',
|
|
256
|
+
'expiresAt',
|
|
257
|
+
'rotationLeadDays',
|
|
258
|
+
'rotationDueAt',
|
|
259
|
+
'permissions',
|
|
260
|
+
'allowedWorkflows',
|
|
261
|
+
'nonForwarding',
|
|
262
|
+
'status',
|
|
263
|
+
'proof',
|
|
264
|
+
'app',
|
|
265
|
+
'pat'
|
|
266
|
+
],
|
|
267
|
+
properties: {
|
|
268
|
+
schemaVersion: { const: credentialPolicySchemaVersion },
|
|
269
|
+
identity: {
|
|
270
|
+
type: 'object',
|
|
271
|
+
additionalProperties: false,
|
|
272
|
+
required: Object.keys(activationIdentityProperties),
|
|
273
|
+
properties: activationIdentityProperties
|
|
274
|
+
},
|
|
275
|
+
repository: {
|
|
276
|
+
type: 'object',
|
|
277
|
+
additionalProperties: false,
|
|
278
|
+
required: ['id', 'owner', 'name', 'fullName'],
|
|
279
|
+
properties: {
|
|
280
|
+
id: { type: 'string', minLength: 1 },
|
|
281
|
+
owner: { type: 'string', minLength: 1 },
|
|
282
|
+
name: { type: 'string', minLength: 1 },
|
|
283
|
+
fullName: { type: 'string', minLength: 1 }
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
owner: { type: 'string', minLength: 1 },
|
|
287
|
+
authKind: { enum: ['github-app', 'fine-grained-pat'] },
|
|
288
|
+
displayNameTemplate: { const: runnerPreflightDisplayNameTemplate },
|
|
289
|
+
displayName: { type: 'string', pattern: '^[A-Za-z0-9_.-]+-runner-preflight-read$' },
|
|
290
|
+
secretName: { const: runnerPreflightSecretName },
|
|
291
|
+
createdAt: { type: 'string', format: 'date-time' },
|
|
292
|
+
expiresAt: { type: 'string', format: 'date-time' },
|
|
293
|
+
rotationLeadDays: { const: runnerPreflightRotationLeadDays },
|
|
294
|
+
rotationDueAt: { type: 'string', format: 'date-time' },
|
|
295
|
+
permissions: {
|
|
296
|
+
type: 'object',
|
|
297
|
+
additionalProperties: false,
|
|
298
|
+
required: ['repository', 'organization'],
|
|
299
|
+
properties: {
|
|
300
|
+
repository: {
|
|
301
|
+
type: 'array',
|
|
302
|
+
const: [...runnerPreflightRepositoryPermissions]
|
|
303
|
+
},
|
|
304
|
+
organization: {
|
|
305
|
+
type: 'array',
|
|
306
|
+
const: [...runnerPreflightOrganizationPermissions]
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
},
|
|
310
|
+
allowedWorkflows: {
|
|
311
|
+
type: 'array',
|
|
312
|
+
items: {
|
|
313
|
+
type: 'object',
|
|
314
|
+
additionalProperties: false,
|
|
315
|
+
required: ['path', 'jobs'],
|
|
316
|
+
properties: {
|
|
317
|
+
path: { type: 'string', minLength: 1 },
|
|
318
|
+
jobs: {
|
|
319
|
+
type: 'array',
|
|
320
|
+
items: { type: 'string', minLength: 1 },
|
|
321
|
+
uniqueItems: true
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
},
|
|
326
|
+
nonForwarding: { const: true },
|
|
327
|
+
status: { enum: ['active', 'expiring', 'expired', 'compromised'] },
|
|
328
|
+
proof: {
|
|
329
|
+
type: 'object',
|
|
330
|
+
additionalProperties: false,
|
|
331
|
+
required: ['verifiedAt', 'readbackDigest', 'readbackProvider', 'payloadFree'],
|
|
332
|
+
properties: {
|
|
333
|
+
verifiedAt: { type: 'string', format: 'date-time' },
|
|
334
|
+
readbackDigest: { type: 'string', pattern: '^[a-f0-9]{64}$' },
|
|
335
|
+
readbackProvider: { enum: ['github-api', 'adapter-fixture'] },
|
|
336
|
+
payloadFree: { const: true }
|
|
337
|
+
}
|
|
338
|
+
},
|
|
339
|
+
app: {
|
|
340
|
+
anyOf: [
|
|
341
|
+
{ type: 'null' },
|
|
342
|
+
{
|
|
343
|
+
type: 'object',
|
|
344
|
+
additionalProperties: false,
|
|
345
|
+
required: ['installationId', 'appSlug', 'selection', 'repositoryFullName', 'permissionsVerifiedAt', 'token'],
|
|
346
|
+
properties: {
|
|
347
|
+
installationId: { type: 'integer', minimum: 1 },
|
|
348
|
+
appSlug: { type: 'string', minLength: 1 },
|
|
349
|
+
selection: { const: 'selected-repository' },
|
|
350
|
+
repositoryFullName: { type: 'string', minLength: 1 },
|
|
351
|
+
permissionsVerifiedAt: { type: 'string', format: 'date-time' },
|
|
352
|
+
token: {
|
|
353
|
+
type: 'object',
|
|
354
|
+
additionalProperties: false,
|
|
355
|
+
required: ['strategy', 'ttlSeconds', 'generatedBy'],
|
|
356
|
+
properties: {
|
|
357
|
+
strategy: { const: 'installation-token' },
|
|
358
|
+
ttlSeconds: { type: 'integer', minimum: 1, maximum: 3600 },
|
|
359
|
+
generatedBy: { const: 'github-app' }
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
]
|
|
365
|
+
},
|
|
366
|
+
pat: {
|
|
367
|
+
anyOf: [
|
|
368
|
+
{ type: 'null' },
|
|
369
|
+
{
|
|
370
|
+
type: 'object',
|
|
371
|
+
additionalProperties: false,
|
|
372
|
+
required: ['lifetimeDays', 'selectedRepositoryOnly', 'createdBy'],
|
|
373
|
+
properties: {
|
|
374
|
+
lifetimeDays: { const: runnerPreflightPatLifetimeDays },
|
|
375
|
+
selectedRepositoryOnly: { const: true },
|
|
376
|
+
createdBy: { const: 'manual-masked-entry' }
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
]
|
|
380
|
+
}
|
|
381
|
+
},
|
|
382
|
+
allOf: [
|
|
383
|
+
{
|
|
384
|
+
if: { properties: { authKind: { const: 'github-app' } }, required: ['authKind'] },
|
|
385
|
+
then: {
|
|
386
|
+
properties: {
|
|
387
|
+
app: { type: 'object' },
|
|
388
|
+
pat: { type: 'null' }
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
if: { properties: { authKind: { const: 'fine-grained-pat' } }, required: ['authKind'] },
|
|
394
|
+
then: {
|
|
395
|
+
properties: {
|
|
396
|
+
app: { type: 'null' },
|
|
397
|
+
pat: { type: 'object' }
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
]
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
export function renderCredentialPolicySchema() {
|
|
405
|
+
return canonicalJson(credentialPolicySchema());
|
|
406
|
+
}
|
|
169
407
|
function apiCommands(plan) {
|
|
170
408
|
const backend = plan.apiStack.id === 'python-fastapi'
|
|
171
409
|
? [
|
|
@@ -485,58 +723,112 @@ export function renderGovernanceContext(plan) {
|
|
|
485
723
|
}
|
|
486
724
|
function renderGovernanceGuide(plan) {
|
|
487
725
|
const launchers = plan.agents.map((agent) => agent.id === 'github-copilot'
|
|
488
|
-
? '- GitHub Copilot: `/liftoff-repository-governance`
|
|
489
|
-
: '- Claude Code: `/liftoff-repository-governance`
|
|
490
|
-
return `#
|
|
726
|
+
? '- GitHub Copilot: `/liftoff-setup` (`/liftoff-repository-governance` remains an alias).'
|
|
727
|
+
: '- Claude Code: `/liftoff-setup` (`/liftoff-repository-governance` remains an alias).').join('\n');
|
|
728
|
+
return `# Liftoff deterministic setup
|
|
491
729
|
|
|
492
|
-
State: **
|
|
730
|
+
State: **managed setup generated; live enforcement is not active**.
|
|
493
731
|
|
|
494
732
|
Liftoff generated deterministic policy and workload context only. It did not
|
|
495
733
|
create or change branches, commits, tags, remotes, pull requests, releases,
|
|
496
734
|
rulesets, GitHub settings, security features, environments, runners, cloud
|
|
497
735
|
resources, deployments, monitoring, alerts, or Slack routes.
|
|
498
736
|
|
|
499
|
-
##
|
|
737
|
+
## Next command after init
|
|
738
|
+
|
|
739
|
+
\`\`\`text
|
|
740
|
+
liftoff init ${plan.safeProjectName}
|
|
741
|
+
cd ${plan.safeProjectName}
|
|
742
|
+
/liftoff-setup
|
|
743
|
+
\`\`\`
|
|
500
744
|
|
|
501
|
-
|
|
502
|
-
2. Commit the complete project and push it to its intended GitHub repository.
|
|
503
|
-
3. Invoke one selected-agent launcher:
|
|
745
|
+
Use the generated setup integration from any selected agent:
|
|
504
746
|
|
|
505
747
|
${launchers}
|
|
506
748
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
749
|
+
\`/liftoff-repository-governance\` is preserved only as a compatibility alias
|
|
750
|
+
that enters the same Liftoff governance engine and user-owned activation state.
|
|
751
|
+
|
|
752
|
+
## What setup does
|
|
753
|
+
|
|
754
|
+
\`/liftoff-setup\` delegates every transition to
|
|
755
|
+
\`liftoff governance status|plan|apply-next|resume|verify\`. The CLI resolves
|
|
756
|
+
the project root, loads \`phase-graph.json\`, validates policy ${governancePolicyVersion},
|
|
757
|
+
and records no separate setup-integration version.
|
|
758
|
+
|
|
759
|
+
Before any live governance work, setup completes the deterministic baseline seed:
|
|
760
|
+
\`liftoff validate\`, applicable backend tests, frontend build,
|
|
761
|
+
\`docker compose config -q\`, \`tofu fmt -check -recursive\`,
|
|
762
|
+
\`tofu init -backend=false\`, \`tofu validate\`, and strict ${plan.specWorkflow.label}
|
|
763
|
+
checks. Missing project boundaries are recorded as inapplicable, not successful.
|
|
764
|
+
The seed's completion means generated files were locally verified and archived;
|
|
765
|
+
it does not mean product behavior, infrastructure, or enforcement exists.
|
|
766
|
+
|
|
767
|
+
Questions are limited to repository publication, credentials, billed resources
|
|
768
|
+
or policy exceptions, final enforcement, destructive cleanup, and external
|
|
769
|
+
blockers. Rerun \`/liftoff-setup\` to resume; verified phases are not repeated.
|
|
770
|
+
|
|
771
|
+
Runner-preflight credentials are deterministic. Setup first prefers an existing
|
|
772
|
+
verified selected-repository GitHub App with the required read permissions. If a
|
|
773
|
+
fine-grained PAT is required, use display name
|
|
774
|
+
\`${runnerPreflightDisplayNameTemplate}\`, secret
|
|
775
|
+
\`${runnerPreflightSecretName}\`, 30-day lifetime, current repository only,
|
|
776
|
+
repository metadata read, organization hosted-runner and network-configuration
|
|
777
|
+
read, no writes, and the recorded workflow/job allowlist. Enter the value only
|
|
778
|
+
through the masked input; never paste or show it in chat, argv, command
|
|
779
|
+
arguments, logs, evidence, files, or screenshots. A leaked value is compromised and must be
|
|
780
|
+
manually revoked and rotated.
|
|
515
781
|
|
|
516
782
|
Live status must be proven from user-owned activation evidence and GitHub
|
|
517
783
|
read-back, never inferred from these local files.
|
|
518
784
|
`;
|
|
519
785
|
}
|
|
520
|
-
function
|
|
521
|
-
return `#
|
|
786
|
+
function renderSetupIntegration() {
|
|
787
|
+
return `# /liftoff-setup
|
|
788
|
+
|
|
789
|
+
Continue deterministic Liftoff setup for this repository through the same
|
|
790
|
+
deterministic Liftoff governance engine used by compatibility aliases.
|
|
522
791
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
792
|
+
Contract:
|
|
793
|
+
|
|
794
|
+
1. Work from the current directory; the Liftoff CLI resolves the nearest project root.
|
|
795
|
+
2. Invoke only these commands: \`liftoff governance status --json\`,
|
|
796
|
+
\`liftoff governance plan --json\`, \`liftoff governance apply-next --json\`,
|
|
797
|
+
\`liftoff governance resume --json\`, and \`liftoff governance verify --json\`.
|
|
798
|
+
3. Explain blockers, approval requirements, and permitted next actions exactly
|
|
799
|
+
from command output.
|
|
800
|
+
4. If a blocker may have changed, run \`liftoff governance resume --json\`.
|
|
801
|
+
5. If a next transition is ready and approved, run
|
|
802
|
+
\`liftoff governance apply-next --json\`, then
|
|
803
|
+
\`liftoff governance verify --json\`.
|
|
804
|
+
6. Never infer phase completion from prose, tasks, or local files. Never use a
|
|
805
|
+
separate activation state or duplicate the Liftoff engine.
|
|
806
|
+
`;
|
|
807
|
+
}
|
|
808
|
+
function renderGovernanceAlias() {
|
|
809
|
+
return `# /liftoff-repository-governance
|
|
526
810
|
|
|
527
|
-
|
|
528
|
-
inapplicable controls, GitFlow or continuous-delivery conflicts, the proposed
|
|
529
|
-
current \`main\` activation baseline SHA, and the ordered implementation plan.
|
|
530
|
-
Then stop for explicit user approval.
|
|
811
|
+
Compatibility alias for \`/liftoff-setup\`.
|
|
531
812
|
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
813
|
+
Enter the same deterministic Liftoff governance engine and user-owned activation
|
|
814
|
+
state. Follow the \`/liftoff-setup\` contract exactly: invoke only
|
|
815
|
+
\`liftoff governance status --json\`, \`liftoff governance plan --json\`,
|
|
816
|
+
\`liftoff governance apply-next --json\`, \`liftoff governance resume --json\`,
|
|
817
|
+
and \`liftoff governance verify --json\`; explain blockers, approvals, and
|
|
818
|
+
results from their output; and never infer completion or create a separate path.
|
|
538
819
|
`;
|
|
539
820
|
}
|
|
821
|
+
function managedCompatibilityInventory(artifacts) {
|
|
822
|
+
return artifacts.map((artifact) => ({
|
|
823
|
+
logicalName: artifact.logicalName,
|
|
824
|
+
pathParts: artifact.pathParts,
|
|
825
|
+
lifecycle: 'managed-core',
|
|
826
|
+
contentHashAuthority: 'liftoff.manifest.json managedArtifacts[].contentHash'
|
|
827
|
+
}));
|
|
828
|
+
}
|
|
829
|
+
function sortedGovernancePathAllowlist(artifacts) {
|
|
830
|
+
return artifacts.map((artifact) => [...artifact.pathParts]);
|
|
831
|
+
}
|
|
540
832
|
export function buildRepositoryGovernanceArtifacts(plan) {
|
|
541
833
|
if (plan.governanceProfile.id === 'none') {
|
|
542
834
|
return [];
|
|
@@ -544,7 +836,8 @@ export function buildRepositoryGovernanceArtifacts(plan) {
|
|
|
544
836
|
const policy = renderCanonicalGovernancePolicy();
|
|
545
837
|
const context = renderGovernanceContext(plan);
|
|
546
838
|
const guide = `${renderGovernanceGuide(plan).trimEnd()}\n`;
|
|
547
|
-
const
|
|
839
|
+
const setupIntegration = `${renderSetupIntegration().trimEnd()}\n`;
|
|
840
|
+
const alias = `${renderGovernanceAlias().trimEnd()}\n`;
|
|
548
841
|
const artifacts = [
|
|
549
842
|
{
|
|
550
843
|
logicalName: 'repository-governance-policy',
|
|
@@ -567,16 +860,56 @@ export function buildRepositoryGovernanceArtifacts(plan) {
|
|
|
567
860
|
pathParts: [...governanceArtifactPaths.guide],
|
|
568
861
|
content: guide
|
|
569
862
|
},
|
|
570
|
-
|
|
571
|
-
logicalName:
|
|
572
|
-
|
|
573
|
-
|
|
863
|
+
{
|
|
864
|
+
logicalName: 'repository-governance-phase-graph',
|
|
865
|
+
category: 'governance',
|
|
866
|
+
lifecycle: 'managed-core',
|
|
867
|
+
pathParts: [...governanceArtifactPaths.phaseGraph],
|
|
868
|
+
content: canonicalPhaseGraphJson
|
|
869
|
+
},
|
|
870
|
+
{
|
|
871
|
+
logicalName: 'repository-governance-compatibility',
|
|
574
872
|
category: 'governance',
|
|
575
873
|
lifecycle: 'managed-core',
|
|
576
|
-
pathParts: [...governanceArtifactPaths
|
|
577
|
-
content:
|
|
578
|
-
}
|
|
874
|
+
pathParts: [...governanceArtifactPaths.compatibility],
|
|
875
|
+
content: ''
|
|
876
|
+
},
|
|
877
|
+
{
|
|
878
|
+
logicalName: 'repository-governance-credential-policy-schema',
|
|
879
|
+
category: 'governance',
|
|
880
|
+
lifecycle: 'managed-core',
|
|
881
|
+
pathParts: [...governanceArtifactPaths.credentialPolicySchema],
|
|
882
|
+
content: renderCredentialPolicySchema()
|
|
883
|
+
},
|
|
884
|
+
...plan.agents.flatMap((agent) => [{
|
|
885
|
+
logicalName: agent.id === 'github-copilot'
|
|
886
|
+
? 'liftoff-setup-copilot'
|
|
887
|
+
: 'liftoff-setup-claude',
|
|
888
|
+
category: 'governance',
|
|
889
|
+
lifecycle: 'managed-core',
|
|
890
|
+
pathParts: [...governanceArtifactPaths.setup[agent.id]],
|
|
891
|
+
content: setupIntegration
|
|
892
|
+
}, {
|
|
893
|
+
logicalName: agent.id === 'github-copilot'
|
|
894
|
+
? 'repository-governance-copilot-launcher'
|
|
895
|
+
: 'repository-governance-claude-launcher',
|
|
896
|
+
category: 'governance',
|
|
897
|
+
lifecycle: 'managed-core',
|
|
898
|
+
pathParts: [...governanceArtifactPaths.alias[agent.id]],
|
|
899
|
+
content: alias
|
|
900
|
+
}])
|
|
579
901
|
];
|
|
902
|
+
const compatibility = artifacts.find((artifact) => artifact.logicalName === 'repository-governance-compatibility');
|
|
903
|
+
if (!compatibility) {
|
|
904
|
+
throw new Error('Governance compatibility artifact was not rendered.');
|
|
905
|
+
}
|
|
906
|
+
const compatibilityMetadata = buildGovernanceCompatibilityMetadata(managedCompatibilityInventory(artifacts), governanceManagedCoreLogicalNames, sortedGovernancePathAllowlist(artifacts));
|
|
907
|
+
validateGovernanceCompatibilityMetadata(compatibilityMetadata, {
|
|
908
|
+
logicalNameAllowlist: governanceManagedCoreLogicalNames,
|
|
909
|
+
pathAllowlist: sortedGovernancePathAllowlist(artifacts),
|
|
910
|
+
inventory: managedCompatibilityInventory(artifacts)
|
|
911
|
+
});
|
|
912
|
+
compatibility.content = `${canonicalJson(compatibilityMetadata)}\n`;
|
|
580
913
|
for (const artifact of artifacts) {
|
|
581
914
|
assertGovernanceContentSafe(artifact.content);
|
|
582
915
|
}
|