@msn-control/liftoff 0.6.2 → 0.8.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/README.md +15 -1
- package/assets/governance/single-maintainer-gitflow/policy.md +705 -0
- package/assets/locks/frontend/package-lock.json +1012 -1694
- package/assets/locks/frontend/package.json +5 -6
- package/assets/locks/go-backend/go.mod +17 -0
- package/assets/locks/go-backend/go.sum +159 -0
- package/assets/locks/node-backend/package-lock.json +1473 -2320
- package/assets/locks/node-backend/package.json +8 -7
- package/assets/locks/opentofu-azure/.terraform.lock.hcl +39 -0
- package/assets/locks/opentofu-azure/versions.tf +10 -0
- package/assets/locks/python-genai/function-requirements.txt +1734 -0
- package/assets/locks/python-genai/liftoff_template_python_genai.egg-info/PKG-INFO +25 -0
- package/assets/locks/python-genai/liftoff_template_python_genai.egg-info/SOURCES.txt +6 -0
- package/assets/locks/python-genai/liftoff_template_python_genai.egg-info/dependency_links.txt +1 -0
- package/assets/locks/python-genai/liftoff_template_python_genai.egg-info/requires.txt +23 -0
- package/assets/locks/python-genai/liftoff_template_python_genai.egg-info/top_level.txt +1 -0
- package/assets/locks/python-genai/pyproject.toml +42 -0
- package/assets/locks/python-genai/uv.lock +2536 -0
- package/assets/locks/python-standard/pyproject.toml +36 -0
- package/assets/locks/python-standard/uv.lock +1780 -0
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/catalog.json +4 -4
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/package-lock.json +667 -1108
- package/assets/supported-stack.json +711 -0
- package/dist/args.js +26 -1
- package/dist/args.js.map +1 -1
- package/dist/catalogs.d.ts +3 -1
- package/dist/catalogs.js +29 -7
- package/dist/catalogs.js.map +1 -1
- package/dist/cli.js +2 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands.d.ts +6 -0
- package/dist/commands.js +364 -172
- package/dist/commands.js.map +1 -1
- package/dist/container-validation.d.ts +2 -0
- package/dist/container-validation.js +26 -0
- package/dist/container-validation.js.map +1 -0
- package/dist/file-system.d.ts +1 -0
- package/dist/file-system.js +141 -7
- package/dist/file-system.js.map +1 -1
- package/dist/framework-adapters.js +1 -0
- package/dist/framework-adapters.js.map +1 -1
- package/dist/go-template-assets.d.ts +2 -0
- package/dist/go-template-assets.js +14 -0
- package/dist/go-template-assets.js.map +1 -0
- package/dist/init-filesystem.js +5 -4
- package/dist/init-filesystem.js.map +1 -1
- package/dist/interactive.d.ts +0 -5
- package/dist/interactive.js +11 -73
- package/dist/interactive.js.map +1 -1
- package/dist/opentofu-template-assets.d.ts +2 -0
- package/dist/opentofu-template-assets.js +10 -0
- package/dist/opentofu-template-assets.js.map +1 -0
- package/dist/package-identity.d.ts +8 -0
- package/dist/package-identity.js +16 -0
- package/dist/package-identity.js.map +1 -0
- package/dist/planner.js +42 -3
- package/dist/planner.js.map +1 -1
- package/dist/power-apps-templates.js +6 -0
- package/dist/power-apps-templates.js.map +1 -1
- package/dist/project-dependencies.d.ts +1 -1
- package/dist/project-dependencies.js +15 -34
- package/dist/project-dependencies.js.map +1 -1
- package/dist/published-verifier.js +11 -1
- package/dist/published-verifier.js.map +1 -1
- package/dist/python-template-assets.d.ts +4 -0
- package/dist/python-template-assets.js +34 -0
- package/dist/python-template-assets.js.map +1 -0
- package/dist/repository-governance.d.ts +17 -0
- package/dist/repository-governance.js +507 -0
- package/dist/repository-governance.js.map +1 -0
- package/dist/runtime.d.ts +1 -1
- package/dist/runtime.js +3 -1
- package/dist/runtime.js.map +1 -1
- package/dist/self-upgrade.d.ts +77 -0
- package/dist/self-upgrade.js +499 -0
- package/dist/self-upgrade.js.map +1 -0
- package/dist/stable-release.d.ts +18 -0
- package/dist/stable-release.js +66 -0
- package/dist/stable-release.js.map +1 -0
- package/dist/standard-templates.js +28 -97
- package/dist/standard-templates.js.map +1 -1
- package/dist/supported-stack.d.ts +115 -0
- package/dist/supported-stack.js +439 -0
- package/dist/supported-stack.js.map +1 -0
- package/dist/telemetry/contract.d.ts +1 -1
- package/dist/telemetry/contract.js +1 -0
- package/dist/telemetry/contract.js.map +1 -1
- package/dist/templates.js +216 -125
- package/dist/templates.js.map +1 -1
- package/dist/types.d.ts +18 -1
- package/dist/workstation-catalog.js +15 -12
- package/dist/workstation-catalog.js.map +1 -1
- package/dist/workstation.js +16 -6
- package/dist/workstation.js.map +1 -1
- package/docs/cli-reference.md +99 -22
- package/docs/configuration-and-manifests.md +14 -7
- package/docs/existing-repositories.md +27 -6
- package/docs/getting-started.md +23 -7
- package/docs/prerequisites.md +30 -4
- package/docs/project-structure.md +20 -1
- package/docs/repository-governance.md +91 -0
- package/docs/safety-and-consent.md +42 -17
- package/docs/spec-workflows-and-agents.md +22 -8
- package/docs/supported-stack.md +89 -0
- package/docs/telemetry.md +6 -0
- package/docs/troubleshooting.md +84 -8
- package/docs/workloads.md +18 -5
- package/package.json +14 -6
- package/dist/update-impact.d.ts +0 -23
- package/dist/update-impact.js +0 -127
- package/dist/update-impact.js.map +0 -1
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { supportedStack } from './supported-stack.js';
|
|
3
|
+
export const governancePolicySchemaVersion = 1;
|
|
4
|
+
export const governancePolicyVersion = '1';
|
|
5
|
+
export const governanceContextSchemaVersion = 1;
|
|
6
|
+
export const governanceArtifactPaths = {
|
|
7
|
+
policy: ['.liftoff', 'governance', 'policy.md'],
|
|
8
|
+
context: ['.liftoff', 'governance', 'context.json'],
|
|
9
|
+
guide: ['.liftoff', 'governance', 'README.md'],
|
|
10
|
+
'github-copilot': [
|
|
11
|
+
'.github',
|
|
12
|
+
'prompts',
|
|
13
|
+
'liftoff-repository-governance.prompt.md'
|
|
14
|
+
],
|
|
15
|
+
claude: [
|
|
16
|
+
'.claude',
|
|
17
|
+
'commands',
|
|
18
|
+
'liftoff-repository-governance.md'
|
|
19
|
+
]
|
|
20
|
+
};
|
|
21
|
+
const suppliedPolicy = readFileSync(new URL('../assets/governance/single-maintainer-gitflow/policy.md', import.meta.url), 'utf8').replace(/\r\n/g, '\n').trimEnd();
|
|
22
|
+
export function renderCanonicalGovernancePolicy() {
|
|
23
|
+
const rendered = suppliedPolicy;
|
|
24
|
+
validateGovernancePolicy(rendered);
|
|
25
|
+
assertGovernanceContentSafe(rendered);
|
|
26
|
+
return `${rendered.trimEnd()}\n`;
|
|
27
|
+
}
|
|
28
|
+
const requiredPolicyFragments = [
|
|
29
|
+
'schemaVersion: 1',
|
|
30
|
+
'profile: single-maintainer-gitflow',
|
|
31
|
+
'policyVersion: "1"',
|
|
32
|
+
'develop` is the integration branch and the **default branch**',
|
|
33
|
+
'main` is production truth',
|
|
34
|
+
'release/X.Y.Z',
|
|
35
|
+
'hotfix/X.Y.Z',
|
|
36
|
+
'required_approving_review_count: 0',
|
|
37
|
+
'require_code_owner_review: false',
|
|
38
|
+
'require_last_push_approval: false',
|
|
39
|
+
'Do not create a `CODEOWNERS` file',
|
|
40
|
+
'no required reviewers',
|
|
41
|
+
'GITHUB_TOKEN',
|
|
42
|
+
'Repository-scoped only',
|
|
43
|
+
'GitHub Secret Protection',
|
|
44
|
+
'Dependabot + Dependency Review',
|
|
45
|
+
'CodeQL + Copilot Autofix',
|
|
46
|
+
'Checkov',
|
|
47
|
+
'Trivy',
|
|
48
|
+
'Grype',
|
|
49
|
+
'OWASP ZAP',
|
|
50
|
+
'slsa-github-generator',
|
|
51
|
+
'OSSF Scorecard',
|
|
52
|
+
'Explicitly excluded as duplicates',
|
|
53
|
+
'build once',
|
|
54
|
+
'zero traffic',
|
|
55
|
+
'fresh baseline revision',
|
|
56
|
+
'Rollback must never be gated',
|
|
57
|
+
'Alerting is infrastructure as code',
|
|
58
|
+
'Route everything to Slack',
|
|
59
|
+
'Add a heartbeat',
|
|
60
|
+
'Test that each alert fires',
|
|
61
|
+
'shallow from deep checks',
|
|
62
|
+
'DORA four keys',
|
|
63
|
+
'trusted_root.jsonl',
|
|
64
|
+
'Fail-closed sequencing.',
|
|
65
|
+
'Prove each check fails',
|
|
66
|
+
'STOP FOR EXPLICIT USER APPROVAL',
|
|
67
|
+
'governance/activation-baseline.json',
|
|
68
|
+
'rulesets idempotently last',
|
|
69
|
+
'read the live rulesets'
|
|
70
|
+
];
|
|
71
|
+
export function validateGovernancePolicy(policy) {
|
|
72
|
+
const missing = requiredPolicyFragments.filter((fragment) => !policy.includes(fragment));
|
|
73
|
+
if (missing.length > 0) {
|
|
74
|
+
throw new Error(`Governance policy is missing required contract fragment: ${missing[0]}`);
|
|
75
|
+
}
|
|
76
|
+
if (!/No change in this repository\s+requires another person's approval/.test(policy) ||
|
|
77
|
+
!policy.includes('Never enable a ruleset whose required contexts have not been observed green')) {
|
|
78
|
+
throw new Error('Governance policy does not preserve fail-closed single-maintainer invariants.');
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const secretValuePatterns = [
|
|
82
|
+
/\bghp_[A-Za-z0-9]{20,}\b/,
|
|
83
|
+
/\bgithub_pat_[A-Za-z0-9_]{20,}\b/,
|
|
84
|
+
/https:\/\/hooks\.slack\.com\/services\/[A-Za-z0-9/]+/,
|
|
85
|
+
/\bAccountKey=[^;\s]+/i,
|
|
86
|
+
/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/
|
|
87
|
+
];
|
|
88
|
+
export function assertGovernanceContentSafe(content) {
|
|
89
|
+
for (const pattern of secretValuePatterns) {
|
|
90
|
+
if (pattern.test(content)) {
|
|
91
|
+
throw new Error('Governance artifact contains a credential-shaped value.');
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function apiCommands(plan) {
|
|
96
|
+
const backend = plan.apiStack.id === 'python-fastapi'
|
|
97
|
+
? [
|
|
98
|
+
{
|
|
99
|
+
id: 'backend-install',
|
|
100
|
+
cwdPathParts: ['backend'],
|
|
101
|
+
executable: 'uv',
|
|
102
|
+
args: [
|
|
103
|
+
'sync',
|
|
104
|
+
'--frozen',
|
|
105
|
+
'--extra',
|
|
106
|
+
'test',
|
|
107
|
+
...(plan.workload === 'genai' && plan.pattern.worker
|
|
108
|
+
? ['--extra', 'functions']
|
|
109
|
+
: [])
|
|
110
|
+
]
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: 'backend-test',
|
|
114
|
+
cwdPathParts: ['backend'],
|
|
115
|
+
executable: 'uv',
|
|
116
|
+
args: ['run', 'python', '-m', 'pytest', '-q']
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
: plan.apiStack.id === 'node-fastify'
|
|
120
|
+
? [
|
|
121
|
+
{
|
|
122
|
+
id: 'backend-install',
|
|
123
|
+
cwdPathParts: ['backend'],
|
|
124
|
+
executable: 'npm',
|
|
125
|
+
args: ['ci']
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
id: 'backend-build',
|
|
129
|
+
cwdPathParts: ['backend'],
|
|
130
|
+
executable: 'npm',
|
|
131
|
+
args: ['run', 'build']
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
id: 'backend-test',
|
|
135
|
+
cwdPathParts: ['backend'],
|
|
136
|
+
executable: 'npm',
|
|
137
|
+
args: ['test']
|
|
138
|
+
}
|
|
139
|
+
]
|
|
140
|
+
: [
|
|
141
|
+
{
|
|
142
|
+
id: 'backend-install',
|
|
143
|
+
cwdPathParts: ['backend'],
|
|
144
|
+
executable: 'go',
|
|
145
|
+
args: ['mod', 'download']
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
id: 'backend-test',
|
|
149
|
+
cwdPathParts: ['backend'],
|
|
150
|
+
executable: 'go',
|
|
151
|
+
args: ['test', './...']
|
|
152
|
+
}
|
|
153
|
+
];
|
|
154
|
+
return [
|
|
155
|
+
...backend,
|
|
156
|
+
...(plan.includeFrontend
|
|
157
|
+
? [
|
|
158
|
+
{
|
|
159
|
+
id: 'frontend-install',
|
|
160
|
+
cwdPathParts: ['frontend'],
|
|
161
|
+
executable: 'npm',
|
|
162
|
+
args: ['ci']
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
id: 'frontend-build',
|
|
166
|
+
cwdPathParts: ['frontend'],
|
|
167
|
+
executable: 'npm',
|
|
168
|
+
args: ['run', 'build']
|
|
169
|
+
}
|
|
170
|
+
]
|
|
171
|
+
: []),
|
|
172
|
+
...(plan.workload === 'genai' && plan.pattern.worker
|
|
173
|
+
? [{
|
|
174
|
+
id: 'function-worker-test',
|
|
175
|
+
cwdPathParts: ['functions', `${plan.pattern.id}-worker`],
|
|
176
|
+
executable: 'uv',
|
|
177
|
+
args: [
|
|
178
|
+
'run',
|
|
179
|
+
'--project',
|
|
180
|
+
'../../backend',
|
|
181
|
+
'--directory',
|
|
182
|
+
'.',
|
|
183
|
+
'python',
|
|
184
|
+
'-m',
|
|
185
|
+
'pytest',
|
|
186
|
+
'-q'
|
|
187
|
+
]
|
|
188
|
+
}]
|
|
189
|
+
: []),
|
|
190
|
+
{
|
|
191
|
+
id: 'local-stack-validate',
|
|
192
|
+
cwdPathParts: [],
|
|
193
|
+
executable: 'docker',
|
|
194
|
+
args: ['compose', 'config', '-q']
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
id: 'opentofu-format',
|
|
198
|
+
cwdPathParts: ['infrastructure', 'opentofu', 'azure'],
|
|
199
|
+
executable: 'tofu',
|
|
200
|
+
args: ['fmt', '-check', '-recursive']
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
id: 'opentofu-initialize',
|
|
204
|
+
cwdPathParts: ['infrastructure', 'opentofu', 'azure'],
|
|
205
|
+
executable: 'tofu',
|
|
206
|
+
args: ['init', '-backend=false']
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
id: 'opentofu-validate',
|
|
210
|
+
cwdPathParts: ['infrastructure', 'opentofu', 'azure'],
|
|
211
|
+
executable: 'tofu',
|
|
212
|
+
args: ['validate']
|
|
213
|
+
}
|
|
214
|
+
];
|
|
215
|
+
}
|
|
216
|
+
function governanceContext(plan) {
|
|
217
|
+
const common = {
|
|
218
|
+
schemaVersion: governanceContextSchemaVersion,
|
|
219
|
+
policy: {
|
|
220
|
+
profile: plan.governanceProfile.id,
|
|
221
|
+
version: governancePolicyVersion,
|
|
222
|
+
state: 'handoff-generated',
|
|
223
|
+
liveEnforcement: 'not-active'
|
|
224
|
+
},
|
|
225
|
+
project: {
|
|
226
|
+
name: plan.projectName,
|
|
227
|
+
safeName: plan.safeProjectName,
|
|
228
|
+
workload: plan.workload,
|
|
229
|
+
artifactForm: plan.workload === 'power-apps-code-app'
|
|
230
|
+
? 'browser-hosted-power-apps-code-app'
|
|
231
|
+
: plan.includeFrontend
|
|
232
|
+
? 'containerized-api-with-web-frontend'
|
|
233
|
+
: 'containerized-api'
|
|
234
|
+
},
|
|
235
|
+
supportedStack: {
|
|
236
|
+
id: supportedStack.id,
|
|
237
|
+
verifiedOn: supportedStack.verifiedOn,
|
|
238
|
+
node: supportedStack.runtimes.node.version,
|
|
239
|
+
npm: supportedStack.packageManagers.npm.version,
|
|
240
|
+
framework: {
|
|
241
|
+
id: plan.framework.id,
|
|
242
|
+
version: plan.framework.version
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
agents: plan.agents.map((agent) => agent.id),
|
|
246
|
+
framework: {
|
|
247
|
+
id: plan.specWorkflow.id,
|
|
248
|
+
version: plan.framework.version,
|
|
249
|
+
...(plan.defaultAgent
|
|
250
|
+
? { defaultAgent: plan.defaultAgent.id }
|
|
251
|
+
: {})
|
|
252
|
+
},
|
|
253
|
+
discovery: {
|
|
254
|
+
githubRepository: 'undiscovered',
|
|
255
|
+
defaultBranch: 'undiscovered',
|
|
256
|
+
refs: 'undiscovered',
|
|
257
|
+
workflowsAndExactChecks: 'undiscovered',
|
|
258
|
+
rulesets: 'undiscovered',
|
|
259
|
+
releasesAndTags: 'undiscovered',
|
|
260
|
+
licensedSecurityFeatures: 'undiscovered',
|
|
261
|
+
privateRunnerAccess: 'undiscovered',
|
|
262
|
+
liveDeployments: 'undiscovered',
|
|
263
|
+
parallelVersionCapability: 'undiscovered',
|
|
264
|
+
canaryTrafficVolume: 'undiscovered',
|
|
265
|
+
monitoringAndAlerts: 'undiscovered',
|
|
266
|
+
slackSeverityRoutes: 'undiscovered',
|
|
267
|
+
providerStatus: 'undiscovered'
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
if (plan.workload === 'power-apps-code-app') {
|
|
271
|
+
return {
|
|
272
|
+
...common,
|
|
273
|
+
supportedStack: {
|
|
274
|
+
...common.supportedStack,
|
|
275
|
+
application: {
|
|
276
|
+
react: supportedStack.npmProjects['power-apps-code-app']
|
|
277
|
+
.resolved.dependencies.react,
|
|
278
|
+
vite: supportedStack.npmProjects['power-apps-code-app']
|
|
279
|
+
.resolved.devDependencies.vite,
|
|
280
|
+
typescript: supportedStack.npmProjects['power-apps-code-app']
|
|
281
|
+
.resolved.devDependencies.typescript,
|
|
282
|
+
powerAppsSdk: supportedStack.npmProjects['power-apps-code-app']
|
|
283
|
+
.resolved.dependencies['@microsoft/power-apps']
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
source: {
|
|
287
|
+
repository: plan.starter.repository,
|
|
288
|
+
path: plan.starter.path,
|
|
289
|
+
commit: plan.starter.commit
|
|
290
|
+
},
|
|
291
|
+
commands: [
|
|
292
|
+
{ id: 'root-install', cwdPathParts: [], executable: 'npm', args: ['ci'] },
|
|
293
|
+
{ id: 'root-lint', cwdPathParts: [], executable: 'npm', args: ['run', 'lint'] },
|
|
294
|
+
{ id: 'root-build', cwdPathParts: [], executable: 'npm', args: ['run', 'build'] }
|
|
295
|
+
],
|
|
296
|
+
generatedBoundaries: {
|
|
297
|
+
rootApplication: 'generated',
|
|
298
|
+
backend: 'inapplicable',
|
|
299
|
+
database: 'inapplicable',
|
|
300
|
+
docker: 'inapplicable',
|
|
301
|
+
opentofu: 'inapplicable',
|
|
302
|
+
apiEnvironments: 'inapplicable',
|
|
303
|
+
customContainerPromotion: 'inapplicable',
|
|
304
|
+
apiDast: 'inapplicable',
|
|
305
|
+
backendHealth: 'inapplicable',
|
|
306
|
+
powerPlatformDeployment: 'live-discovery-required'
|
|
307
|
+
},
|
|
308
|
+
environments: []
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
const worker = plan.workload === 'genai' && plan.pattern.worker;
|
|
312
|
+
return {
|
|
313
|
+
...common,
|
|
314
|
+
supportedStack: {
|
|
315
|
+
...common.supportedStack,
|
|
316
|
+
backendRuntime: plan.apiStack.id === 'python-fastapi'
|
|
317
|
+
? supportedStack.runtimes.python.version
|
|
318
|
+
: plan.apiStack.id === 'node-fastify'
|
|
319
|
+
? supportedStack.runtimes.node.version
|
|
320
|
+
: supportedStack.runtimes.go.version,
|
|
321
|
+
opentofu: supportedStack.runtimes.opentofu.version
|
|
322
|
+
},
|
|
323
|
+
api: {
|
|
324
|
+
stack: plan.apiStack.id,
|
|
325
|
+
...(plan.workload === 'genai'
|
|
326
|
+
? { pattern: plan.pattern.id }
|
|
327
|
+
: {})
|
|
328
|
+
},
|
|
329
|
+
commands: apiCommands(plan),
|
|
330
|
+
generatedBoundaries: {
|
|
331
|
+
backend: {
|
|
332
|
+
state: 'generated',
|
|
333
|
+
pathParts: ['backend']
|
|
334
|
+
},
|
|
335
|
+
frontend: plan.includeFrontend
|
|
336
|
+
? { state: 'generated', pathParts: ['frontend'] }
|
|
337
|
+
: { state: 'inapplicable' },
|
|
338
|
+
worker: worker
|
|
339
|
+
? {
|
|
340
|
+
state: 'generated',
|
|
341
|
+
pathParts: ['functions', `${plan.pattern.id}-worker`]
|
|
342
|
+
}
|
|
343
|
+
: { state: 'inapplicable' },
|
|
344
|
+
docker: {
|
|
345
|
+
state: 'generated',
|
|
346
|
+
pathParts: ['docker-compose.yml']
|
|
347
|
+
},
|
|
348
|
+
opentofu: {
|
|
349
|
+
state: 'generated-not-deployed',
|
|
350
|
+
pathParts: ['infrastructure', 'opentofu', 'azure']
|
|
351
|
+
}
|
|
352
|
+
},
|
|
353
|
+
environments: plan.environments.map((environment) => environment.id),
|
|
354
|
+
deployment: {
|
|
355
|
+
provider: plan.provider.id,
|
|
356
|
+
region: plan.region.slug,
|
|
357
|
+
liveState: 'undiscovered',
|
|
358
|
+
customContainerPromotion: 'requires-live-discovery',
|
|
359
|
+
apiDast: 'requires-live-staging-and-runner-discovery'
|
|
360
|
+
},
|
|
361
|
+
health: [
|
|
362
|
+
{
|
|
363
|
+
component: 'backend',
|
|
364
|
+
path: '/health',
|
|
365
|
+
depth: 'shallow'
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
component: 'backend',
|
|
369
|
+
path: '/ready',
|
|
370
|
+
depth: 'shallow',
|
|
371
|
+
gap: 'generated endpoint does not prove dependency reachability'
|
|
372
|
+
}
|
|
373
|
+
]
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
function isRecord(value) {
|
|
377
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
378
|
+
}
|
|
379
|
+
export function validateGovernanceContext(value) {
|
|
380
|
+
if (!isRecord(value) || value.schemaVersion !== governanceContextSchemaVersion) {
|
|
381
|
+
throw new Error('Governance context must use schemaVersion 1.');
|
|
382
|
+
}
|
|
383
|
+
if (!isRecord(value.policy)) {
|
|
384
|
+
throw new Error('Governance context policy identity is missing.');
|
|
385
|
+
}
|
|
386
|
+
if (value.policy.profile !== 'single-maintainer-gitflow' ||
|
|
387
|
+
value.policy.version !== governancePolicyVersion ||
|
|
388
|
+
value.policy.state !== 'handoff-generated' ||
|
|
389
|
+
value.policy.liveEnforcement !== 'not-active') {
|
|
390
|
+
throw new Error('Governance context cannot claim live enforcement.');
|
|
391
|
+
}
|
|
392
|
+
if (!isRecord(value.discovery)) {
|
|
393
|
+
throw new Error('Governance context discovery state is missing.');
|
|
394
|
+
}
|
|
395
|
+
if (Object.values(value.discovery).some((entry) => entry !== 'undiscovered')) {
|
|
396
|
+
throw new Error('Governance context contains a fabricated live discovery fact.');
|
|
397
|
+
}
|
|
398
|
+
if (!Array.isArray(value.commands) || value.commands.length === 0) {
|
|
399
|
+
throw new Error('Governance context must contain real generated commands.');
|
|
400
|
+
}
|
|
401
|
+
if (!isRecord(value.generatedBoundaries)) {
|
|
402
|
+
throw new Error('Governance context generated boundaries are missing.');
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
export function renderGovernanceContext(plan) {
|
|
406
|
+
const value = governanceContext(plan);
|
|
407
|
+
validateGovernanceContext(value);
|
|
408
|
+
const rendered = `${JSON.stringify(value, null, 2)}\n`;
|
|
409
|
+
assertGovernanceContentSafe(rendered);
|
|
410
|
+
return rendered;
|
|
411
|
+
}
|
|
412
|
+
function renderGovernanceGuide(plan) {
|
|
413
|
+
const launchers = plan.agents.map((agent) => agent.id === 'github-copilot'
|
|
414
|
+
? '- GitHub Copilot: `/liftoff-repository-governance` from the repository root.'
|
|
415
|
+
: '- Claude Code: `/liftoff-repository-governance` from the repository root.').join('\n');
|
|
416
|
+
return `# Repository governance handoff
|
|
417
|
+
|
|
418
|
+
State: **handoff generated; live enforcement is not active**.
|
|
419
|
+
|
|
420
|
+
Liftoff generated deterministic policy and workload context only. It did not
|
|
421
|
+
create or change branches, commits, tags, remotes, pull requests, releases,
|
|
422
|
+
rulesets, GitHub settings, security features, environments, runners, cloud
|
|
423
|
+
resources, deployments, monitoring, alerts, or Slack routes.
|
|
424
|
+
|
|
425
|
+
## Before activation
|
|
426
|
+
|
|
427
|
+
1. Review \`policy.md\` and \`context.json\`.
|
|
428
|
+
2. Commit the complete project and push it to its intended GitHub repository.
|
|
429
|
+
3. Invoke one selected-agent launcher:
|
|
430
|
+
|
|
431
|
+
${launchers}
|
|
432
|
+
|
|
433
|
+
4. The agent performs read-only Phase 0, reports evidence, gaps,
|
|
434
|
+
inapplicable controls, the proposed current \`main\` activation SHA, and an
|
|
435
|
+
ordered plan.
|
|
436
|
+
5. The agent stops. Explicitly approve or revise that conversational plan.
|
|
437
|
+
This approval is required before implementation and is distinct from the
|
|
438
|
+
policy's prohibition on human merge or deployment approval gates.
|
|
439
|
+
6. After approval, the agent creates a new ${plan.specWorkflow.label}
|
|
440
|
+
governance change. Liftoff does not own or recreate that change.
|
|
441
|
+
|
|
442
|
+
Live status must be proven from user-owned activation evidence and GitHub
|
|
443
|
+
read-back, never inferred from these local files.
|
|
444
|
+
`;
|
|
445
|
+
}
|
|
446
|
+
function renderAgentLauncher(plan) {
|
|
447
|
+
return `# Activate Liftoff repository governance
|
|
448
|
+
|
|
449
|
+
Require a committed and pushed GitHub repository. Read
|
|
450
|
+
\`.liftoff/governance/policy.md\` and
|
|
451
|
+
\`.liftoff/governance/context.json\` as the canonical inputs.
|
|
452
|
+
|
|
453
|
+
Perform only the policy's read-only Phase 0. Report all evidence, gaps,
|
|
454
|
+
inapplicable controls, GitFlow or continuous-delivery conflicts, the proposed
|
|
455
|
+
current \`main\` activation baseline SHA, and the ordered implementation plan.
|
|
456
|
+
Then stop for explicit user approval.
|
|
457
|
+
|
|
458
|
+
Before approval, do not write files, create a ${plan.specWorkflow.label} change,
|
|
459
|
+
mutate Git, call a mutating GitHub API, configure security, deploy, or create
|
|
460
|
+
monitoring. After approval, create a new ${plan.specWorkflow.label} governance
|
|
461
|
+
change from the discovered facts. Never treat the Liftoff handoff as live
|
|
462
|
+
enforcement and never create or modify
|
|
463
|
+
\`governance/activation-baseline.json\` before approval.
|
|
464
|
+
`;
|
|
465
|
+
}
|
|
466
|
+
export function buildRepositoryGovernanceArtifacts(plan) {
|
|
467
|
+
if (plan.governanceProfile.id === 'none') {
|
|
468
|
+
return [];
|
|
469
|
+
}
|
|
470
|
+
const policy = renderCanonicalGovernancePolicy();
|
|
471
|
+
const context = renderGovernanceContext(plan);
|
|
472
|
+
const guide = `${renderGovernanceGuide(plan).trimEnd()}\n`;
|
|
473
|
+
const launcher = `${renderAgentLauncher(plan).trimEnd()}\n`;
|
|
474
|
+
const artifacts = [
|
|
475
|
+
{
|
|
476
|
+
logicalName: 'repository-governance-policy',
|
|
477
|
+
category: 'governance',
|
|
478
|
+
pathParts: [...governanceArtifactPaths.policy],
|
|
479
|
+
content: policy
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
logicalName: 'repository-governance-context',
|
|
483
|
+
category: 'governance',
|
|
484
|
+
pathParts: [...governanceArtifactPaths.context],
|
|
485
|
+
content: context
|
|
486
|
+
},
|
|
487
|
+
{
|
|
488
|
+
logicalName: 'repository-governance-guide',
|
|
489
|
+
category: 'governance',
|
|
490
|
+
pathParts: [...governanceArtifactPaths.guide],
|
|
491
|
+
content: guide
|
|
492
|
+
},
|
|
493
|
+
...plan.agents.map((agent) => ({
|
|
494
|
+
logicalName: agent.id === 'github-copilot'
|
|
495
|
+
? 'repository-governance-copilot-launcher'
|
|
496
|
+
: 'repository-governance-claude-launcher',
|
|
497
|
+
category: 'governance',
|
|
498
|
+
pathParts: [...governanceArtifactPaths[agent.id]],
|
|
499
|
+
content: launcher
|
|
500
|
+
}))
|
|
501
|
+
];
|
|
502
|
+
for (const artifact of artifacts) {
|
|
503
|
+
assertGovernanceContentSafe(artifact.content);
|
|
504
|
+
}
|
|
505
|
+
return artifacts;
|
|
506
|
+
}
|
|
507
|
+
//# sourceMappingURL=repository-governance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository-governance.js","sourceRoot":"","sources":["../src/repository-governance.ts"],"names":[],"mappings":"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"}
|
package/dist/runtime.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const minimumNodeVersion
|
|
1
|
+
export declare const minimumNodeVersion: string;
|
|
2
2
|
export declare function nodeRuntimeError(observedVersion?: string): string | undefined;
|
package/dist/runtime.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { compareSemver } from './semver.js';
|
|
2
|
-
|
|
2
|
+
import { supportedStack } from './supported-stack.js';
|
|
3
|
+
export const minimumNodeVersion = supportedStack.runtimes.node.minimumVersion ??
|
|
4
|
+
supportedStack.runtimes.node.version;
|
|
3
5
|
export function nodeRuntimeError(observedVersion = process.versions.node) {
|
|
4
6
|
if (compareSemver(observedVersion, minimumNodeVersion) >= 0) {
|
|
5
7
|
return undefined;
|
package/dist/runtime.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,CAAC,MAAM,kBAAkB,GAAG,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc;IAC3E,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC;AAEvC,MAAM,UAAU,gBAAgB,CAAC,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI;IACtE,IAAI,aAAa,CAAC,eAAe,EAAE,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5D,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,4BAA4B,kBAAkB,oBAAoB,eAAe,oCAAoC,CAAC;AAC/H,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { Stats } from 'node:fs';
|
|
2
|
+
import { type StableRelease } from './stable-release.js';
|
|
3
|
+
import { type CommandRunner } from './process-runner.js';
|
|
4
|
+
import type { ExternalCommand } from './types.js';
|
|
5
|
+
export declare const selfUpgradeSchemaVersion: 1;
|
|
6
|
+
export declare const selfUpgradeInstallTimeoutMs: number;
|
|
7
|
+
export declare const selfUpgradeProbeTimeoutMs = 30000;
|
|
8
|
+
export declare const selfUpgradeVerificationTimeoutMs = 15000;
|
|
9
|
+
export type SelfUpgradeMode = 'apply' | 'check';
|
|
10
|
+
export type SelfUpgradeStatus = 'blocked' | 'current' | 'failed' | 'update-available' | 'upgraded';
|
|
11
|
+
export type SelfUpgradeRegistryKind = 'canonical' | 'configured';
|
|
12
|
+
export type SelfUpgradeReasonCode = 'canonical_invalid' | 'canonical_timeout' | 'canonical_unavailable' | 'current' | 'downgrade_refused' | 'invalid_global_root' | 'invalid_package' | 'npm_install_failed' | 'npm_install_timeout' | 'npm_unavailable' | 'registry_invalid' | 'registry_stale' | 'registry_unavailable' | 'unsupported_installation' | 'update_available' | 'upgrade_complete' | 'verification_failed';
|
|
13
|
+
interface SelfUpgradeResultBase {
|
|
14
|
+
schemaVersion: typeof selfUpgradeSchemaVersion;
|
|
15
|
+
mode: SelfUpgradeMode;
|
|
16
|
+
status: SelfUpgradeStatus;
|
|
17
|
+
currentVersion: string;
|
|
18
|
+
reasonCode: SelfUpgradeReasonCode;
|
|
19
|
+
}
|
|
20
|
+
export type SelfUpgradeResult = (SelfUpgradeResultBase & {
|
|
21
|
+
status: 'current';
|
|
22
|
+
reasonCode: 'current';
|
|
23
|
+
}) | (SelfUpgradeResultBase & {
|
|
24
|
+
status: 'update-available';
|
|
25
|
+
reasonCode: 'update_available';
|
|
26
|
+
targetVersion: string;
|
|
27
|
+
registryKind: SelfUpgradeRegistryKind;
|
|
28
|
+
}) | (SelfUpgradeResultBase & {
|
|
29
|
+
status: 'upgraded';
|
|
30
|
+
reasonCode: 'upgrade_complete';
|
|
31
|
+
targetVersion: string;
|
|
32
|
+
registryKind: SelfUpgradeRegistryKind;
|
|
33
|
+
}) | (SelfUpgradeResultBase & {
|
|
34
|
+
status: 'blocked' | 'failed';
|
|
35
|
+
targetVersion?: string;
|
|
36
|
+
registryKind?: SelfUpgradeRegistryKind;
|
|
37
|
+
});
|
|
38
|
+
export type SelfUpgradeStage = 'Inspect global installation' | 'Resolve canonical stable target' | 'Verify configured registry parity' | 'Install exact Liftoff release' | 'Verify replacement';
|
|
39
|
+
export interface SelfUpgradeRequest {
|
|
40
|
+
mode: SelfUpgradeMode;
|
|
41
|
+
currentVersion: string;
|
|
42
|
+
stdout: NodeJS.WritableStream;
|
|
43
|
+
stderr: NodeJS.WritableStream;
|
|
44
|
+
json: boolean;
|
|
45
|
+
runningPackageRoot?: string;
|
|
46
|
+
onStage?: (stage: SelfUpgradeStage, detail?: string) => void;
|
|
47
|
+
onInstallCommand?: (command: ExternalCommand) => void;
|
|
48
|
+
}
|
|
49
|
+
export type SelfUpgradeExecutor = (request: SelfUpgradeRequest) => Promise<SelfUpgradeResult>;
|
|
50
|
+
export interface SelfUpgradeDependencies {
|
|
51
|
+
runner: CommandRunner;
|
|
52
|
+
lookupStableRelease(): Promise<StableRelease>;
|
|
53
|
+
makeNeutralDirectory(): Promise<string>;
|
|
54
|
+
removeNeutralDirectory(directory: string): Promise<void>;
|
|
55
|
+
readJson(filePath: string): Promise<unknown>;
|
|
56
|
+
lstat(filePath: string): Promise<Stats>;
|
|
57
|
+
realpath(filePath: string): Promise<string>;
|
|
58
|
+
platform: NodeJS.Platform;
|
|
59
|
+
execPath: string;
|
|
60
|
+
environment: NodeJS.ProcessEnv;
|
|
61
|
+
}
|
|
62
|
+
export type ConfiguredRegistryTargetResult = {
|
|
63
|
+
status: 'available';
|
|
64
|
+
registryKind: SelfUpgradeRegistryKind;
|
|
65
|
+
} | {
|
|
66
|
+
status: 'stale' | 'unavailable';
|
|
67
|
+
};
|
|
68
|
+
export type ConfiguredRegistryTargetLookup = (targetVersion: string) => Promise<ConfiguredRegistryTargetResult>;
|
|
69
|
+
export declare function pathIsContained(root: string, candidate: string, platform: NodeJS.Platform): boolean;
|
|
70
|
+
export declare function expectedGlobalPackageRoot(globalRoot: string, platform: NodeJS.Platform): string;
|
|
71
|
+
export declare function buildGlobalNpmInstallCommand(targetVersion: string, platform: NodeJS.Platform): ExternalCommand;
|
|
72
|
+
export declare function selfUpgradeExitCode(value: SelfUpgradeResult): number;
|
|
73
|
+
export declare function selfUpgradeRemedy(value: SelfUpgradeResult): string | undefined;
|
|
74
|
+
export declare function selfUpgradeSummary(value: SelfUpgradeResult): string;
|
|
75
|
+
export declare function checkConfiguredRegistryTarget(targetVersion: string, overrides?: Partial<SelfUpgradeDependencies>): Promise<ConfiguredRegistryTargetResult>;
|
|
76
|
+
export declare function runSelfUpgrade(request: SelfUpgradeRequest, overrides?: Partial<SelfUpgradeDependencies>): Promise<SelfUpgradeResult>;
|
|
77
|
+
export {};
|