@msn-control/liftoff 0.7.0 → 0.9.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.
Files changed (114) hide show
  1. package/README.md +13 -1
  2. package/assets/governance/single-maintainer-gitflow/policy.md +705 -0
  3. package/assets/locks/frontend/package-lock.json +1012 -1694
  4. package/assets/locks/frontend/package.json +5 -6
  5. package/assets/locks/go-backend/go.mod +17 -0
  6. package/assets/locks/go-backend/go.sum +159 -0
  7. package/assets/locks/node-backend/package-lock.json +1473 -2320
  8. package/assets/locks/node-backend/package.json +8 -7
  9. package/assets/locks/opentofu-azure/.terraform.lock.hcl +39 -0
  10. package/assets/locks/opentofu-azure/versions.tf +10 -0
  11. package/assets/locks/python-genai/function-requirements.txt +1734 -0
  12. package/assets/locks/python-genai/liftoff_template_python_genai.egg-info/PKG-INFO +25 -0
  13. package/assets/locks/python-genai/liftoff_template_python_genai.egg-info/SOURCES.txt +6 -0
  14. package/assets/locks/python-genai/liftoff_template_python_genai.egg-info/dependency_links.txt +1 -0
  15. package/assets/locks/python-genai/liftoff_template_python_genai.egg-info/requires.txt +23 -0
  16. package/assets/locks/python-genai/liftoff_template_python_genai.egg-info/top_level.txt +1 -0
  17. package/assets/locks/python-genai/pyproject.toml +42 -0
  18. package/assets/locks/python-genai/uv.lock +2536 -0
  19. package/assets/locks/python-standard/pyproject.toml +36 -0
  20. package/assets/locks/python-standard/uv.lock +1780 -0
  21. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/catalog.json +4 -4
  22. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/package-lock.json +667 -1108
  23. package/assets/supported-stack.json +711 -0
  24. package/dist/args.js +14 -0
  25. package/dist/args.js.map +1 -1
  26. package/dist/catalogs.d.ts +3 -1
  27. package/dist/catalogs.js +29 -7
  28. package/dist/catalogs.js.map +1 -1
  29. package/dist/cli.js +2 -1
  30. package/dist/cli.js.map +1 -1
  31. package/dist/commands.d.ts +6 -0
  32. package/dist/commands.js +331 -41
  33. package/dist/commands.js.map +1 -1
  34. package/dist/container-validation.d.ts +2 -0
  35. package/dist/container-validation.js +26 -0
  36. package/dist/container-validation.js.map +1 -0
  37. package/dist/file-system.js +130 -5
  38. package/dist/file-system.js.map +1 -1
  39. package/dist/framework-adapters.d.ts +1 -1
  40. package/dist/framework-adapters.js +10 -3
  41. package/dist/framework-adapters.js.map +1 -1
  42. package/dist/framework-validation.d.ts +1 -0
  43. package/dist/framework-validation.js +26 -0
  44. package/dist/framework-validation.js.map +1 -1
  45. package/dist/go-template-assets.d.ts +2 -0
  46. package/dist/go-template-assets.js +14 -0
  47. package/dist/go-template-assets.js.map +1 -0
  48. package/dist/init-filesystem.js +5 -4
  49. package/dist/init-filesystem.js.map +1 -1
  50. package/dist/interactive.d.ts +13 -0
  51. package/dist/interactive.js +25 -7
  52. package/dist/interactive.js.map +1 -1
  53. package/dist/openspec-profile.d.ts +28 -0
  54. package/dist/openspec-profile.js +172 -0
  55. package/dist/openspec-profile.js.map +1 -0
  56. package/dist/opentofu-template-assets.d.ts +2 -0
  57. package/dist/opentofu-template-assets.js +10 -0
  58. package/dist/opentofu-template-assets.js.map +1 -0
  59. package/dist/package-identity.d.ts +8 -0
  60. package/dist/package-identity.js +16 -0
  61. package/dist/package-identity.js.map +1 -0
  62. package/dist/planner.js +61 -4
  63. package/dist/planner.js.map +1 -1
  64. package/dist/power-apps-templates.js +18 -0
  65. package/dist/power-apps-templates.js.map +1 -1
  66. package/dist/project-dependencies.d.ts +1 -1
  67. package/dist/project-dependencies.js +15 -34
  68. package/dist/project-dependencies.js.map +1 -1
  69. package/dist/published-verifier.js +11 -1
  70. package/dist/published-verifier.js.map +1 -1
  71. package/dist/python-template-assets.d.ts +4 -0
  72. package/dist/python-template-assets.js +34 -0
  73. package/dist/python-template-assets.js.map +1 -0
  74. package/dist/repository-governance.d.ts +17 -0
  75. package/dist/repository-governance.js +507 -0
  76. package/dist/repository-governance.js.map +1 -0
  77. package/dist/runtime.d.ts +1 -1
  78. package/dist/runtime.js +3 -1
  79. package/dist/runtime.js.map +1 -1
  80. package/dist/self-upgrade.d.ts +77 -0
  81. package/dist/self-upgrade.js +499 -0
  82. package/dist/self-upgrade.js.map +1 -0
  83. package/dist/stable-release.d.ts +18 -0
  84. package/dist/stable-release.js +66 -0
  85. package/dist/stable-release.js.map +1 -0
  86. package/dist/standard-templates.js +28 -97
  87. package/dist/standard-templates.js.map +1 -1
  88. package/dist/supported-stack.d.ts +115 -0
  89. package/dist/supported-stack.js +439 -0
  90. package/dist/supported-stack.js.map +1 -0
  91. package/dist/telemetry/contract.d.ts +1 -1
  92. package/dist/telemetry/contract.js +1 -0
  93. package/dist/telemetry/contract.js.map +1 -1
  94. package/dist/templates.js +238 -127
  95. package/dist/templates.js.map +1 -1
  96. package/dist/types.d.ts +21 -1
  97. package/dist/workstation-catalog.js +15 -12
  98. package/dist/workstation-catalog.js.map +1 -1
  99. package/dist/workstation.js +16 -6
  100. package/dist/workstation.js.map +1 -1
  101. package/docs/cli-reference.md +72 -2
  102. package/docs/configuration-and-manifests.md +13 -5
  103. package/docs/existing-repositories.md +44 -8
  104. package/docs/getting-started.md +34 -9
  105. package/docs/prerequisites.md +47 -4
  106. package/docs/project-structure.md +27 -1
  107. package/docs/repository-governance.md +91 -0
  108. package/docs/safety-and-consent.md +50 -13
  109. package/docs/spec-workflows-and-agents.md +61 -9
  110. package/docs/supported-stack.md +89 -0
  111. package/docs/telemetry.md +6 -0
  112. package/docs/troubleshooting.md +115 -0
  113. package/docs/workloads.md +14 -5
  114. package/package.json +14 -6
@@ -5,6 +5,7 @@ Run `liftoff help` or command-specific help for the authoritative syntax:
5
5
  ```bash
6
6
  liftoff init --help
7
7
  liftoff migrate --help
8
+ liftoff upgrade --help
8
9
  liftoff update --help
9
10
  ```
10
11
 
@@ -14,7 +15,7 @@ duplicates, and extra positional arguments fail before generation.
14
15
  ## Lifecycle
15
16
 
16
17
  ```text
17
- plan -> init or migrate -> validate and doctor -> update -> dev and infra helpers
18
+ install -> upgrade CLI -> plan -> init or migrate -> validate and doctor -> update project -> dev and infra helpers
18
19
  ```
19
20
 
20
21
  | Command | Behavior |
@@ -24,6 +25,8 @@ plan -> init or migrate -> validate and doctor -> update -> dev and infra helper
24
25
  | `liftoff migrate <source>` | Creates a new sibling scaffold and filtered source copy without changing the source |
25
26
  | `liftoff validate [project]` | Validates manifest identity, durable files, workload metadata, and framework markers |
26
27
  | `liftoff doctor [project]` | Runs read-only workload-derived project and workstation diagnostics |
28
+ | `liftoff upgrade` | Replaces a verified global npm installation with the exact canonical stable release exposed by the configured registry |
29
+ | `liftoff upgrade --check` | Checks installation origin and registry parity without installing; exits 2 when an installable update exists |
27
30
  | `liftoff update [project]` | Applies safe managed drift immediately, preserves unforced conflicts and orphans, and records the resulting manifest |
28
31
  | `liftoff update --check` | Reports drift without preflight or mutation; exits 0 when clean and 2 when drift exists |
29
32
  | `liftoff update --force` | Applies safe changes and overwrites only the exact guarded conflicts reported by update |
@@ -38,6 +41,11 @@ plan -> init or migrate -> validate and doctor -> update -> dev and infra helper
38
41
  The former `liftoff create` command is intentionally rejected with guidance to
39
42
  use `liftoff init`; there is no compatibility alias.
40
43
 
44
+ Generation, validation, doctor, and update consume the packaged
45
+ [supported-stack baseline](supported-stack.md). The current contract uses
46
+ Node.js 24 LTS, Python 3.14, Go 1.27, OpenTofu 1.12, OpenSpec 1.11, and Spec Kit
47
+ 1.0 release lines; these commands never resolve mutable latest versions.
48
+
41
49
  ## Planning and initialization options
42
50
 
43
51
  Common noninteractive inputs include:
@@ -53,13 +61,65 @@ Common noninteractive inputs include:
53
61
  --spec openspec|spec-kit
54
62
  --agents copilot,claude
55
63
  --default-agent copilot|claude
64
+ --governance single-maintainer-gitflow|none
56
65
  --code-apps-plugin | --no-code-apps-plugin
66
+ --copilot-cloud | --no-copilot-cloud
67
+ --configure-openspec-profile
57
68
  ```
58
69
 
59
70
  Power Apps rejects API, pattern, cloud, region, frontend, and API environment
60
71
  options rather than ignoring them.
61
72
 
62
73
  Consent options are documented in [safety and consent](safety-and-consent.md).
74
+ Repository governance defaults to `single-maintainer-gitflow`. It generates a
75
+ local policy handoff only; `none` omits it. See
76
+ [repository governance](repository-governance.md).
77
+
78
+ OpenSpec projects use all 12 OpenSpec 1.11 workflows with both skills and
79
+ commands. `--copilot-cloud` opts into the GitHub-hosted coding-agent workflow and
80
+ agent definition; omission and `--no-copilot-cloud` keep it disabled.
81
+
82
+ OpenSpec stores workflow profile and delivery globally. If the observed profile
83
+ does not match Liftoff's complete contract, interactive runs request separate
84
+ consent. Noninteractive `init` and `migrate` require
85
+ `--configure-openspec-profile` to authorize the displayed
86
+ `openspec config set` commands. The flag has no effect during `plan`, which
87
+ never inspects or changes machine configuration.
88
+
89
+ ## CLI upgrade modes
90
+
91
+ ```bash
92
+ liftoff upgrade
93
+ liftoff upgrade --check
94
+ liftoff upgrade --json
95
+ liftoff upgrade --check --json
96
+ ```
97
+
98
+ `liftoff upgrade` is an imperative request to replace the supported global npm
99
+ installation of `@msn-control/liftoff`; it does not prompt or accept `--yes`,
100
+ `--force`, `--install-tools`, project paths, or project dependency flags.
101
+ Automatic replacement is refused for local dependencies, `npx` execution-cache
102
+ copies, linked checkouts, unknown package-manager stores, ambiguous roots, or
103
+ unsafe paths.
104
+
105
+ Canonical npm's stable `latest` metadata selects one exact target. The effective
106
+ configured npm registry remains the delivery path and must expose that exact
107
+ version. Liftoff never edits `.npmrc`, embeds registry credentials, forces a
108
+ canonical bypass around a stale mirror, invokes elevation, installs a
109
+ prerelease, or performs a downgrade.
110
+
111
+ `--check` performs the same origin, target, and parity checks without invoking
112
+ installation. Apply uses one shell-free exact npm command with lifecycle scripts,
113
+ audit, and funding prompts disabled, then verifies installed metadata, the
114
+ confined binary, and exact `Liftoff <version>` output. A failed install or
115
+ verification is not automatically rolled back; use the exact-version repair
116
+ command printed by Liftoff.
117
+
118
+ JSON results use schema version 1 and expose only `mode`, `status`,
119
+ `currentVersion`, applicable `targetVersion`, applicable `registryKind`, and a
120
+ stable `reasonCode`. Status is one of `current`, `update-available`, `upgraded`,
121
+ `blocked`, or `failed`. Child progress goes to stderr so stdout remains one JSON
122
+ object.
63
123
 
64
124
  ## Update modes
65
125
 
@@ -75,6 +135,9 @@ Plain `liftoff update` is imperative and prompt-free. It applies safe new,
75
135
  missing, untouched-upgrade, clean-move, and recorded-state changes in
76
136
  interactive terminals, redirected streams, and automation. Local or user-owned
77
137
  conflicts are skipped and reported. Orphans are reported without deletion.
138
+ During legacy governance adoption, preserved unrecorded conflicts remain
139
+ outside manifest ownership and set local state to `handoff-partial` until a
140
+ later update can write or byte-identically adopt every required artifact.
78
141
 
79
142
  Use `--check` whenever no project bytes may change. Human check mode prints each
80
143
  drift state and recommends plain update for safe changes or a reviewed
@@ -92,6 +155,10 @@ stack, GenAI pattern, framework, selected-agent, or user-supplied Power Apps
92
155
  starter identity changes, and it cannot bypass project-boundary, symlink,
93
156
  structural-collision, or manifest guards.
94
157
 
158
+ For a breaking supported-stack release, inspect `liftoff update --check` before
159
+ plain update. Restore an unwanted applied migration through version control;
160
+ running an older CLI is not a supported automatic downgrade.
161
+
95
162
  ### Migration from 0.6.x
96
163
 
97
164
  The `--apply` flag was removed in 0.7.0. These are historical 0.6.x commands,
@@ -113,6 +180,8 @@ Machine-readable maintenance contracts bypass decorative presentation:
113
180
  ```bash
114
181
  liftoff validate --json
115
182
  liftoff doctor --json
183
+ liftoff upgrade --json
184
+ liftoff upgrade --check --json
116
185
  liftoff update --json
117
186
  liftoff update --check --json
118
187
  ```
@@ -125,7 +194,8 @@ Exit codes:
125
194
 
126
195
  - `0`: success or a clean check.
127
196
  - `1`: invalid input, unsafe state, or command failure.
128
- - `2`: explicit update check mode found drift.
197
+ - `2`: an explicit update check found project drift, or upgrade check found an
198
+ installable CLI release.
129
199
 
130
200
  Raw installer, framework, and dependency child stdout and stderr are forwarded
131
201
  unchanged.
@@ -24,6 +24,7 @@ A Power Apps configuration contains only applicable fields:
24
24
  "projectType": "power-apps-code-app",
25
25
  "specWorkflow": "openspec",
26
26
  "agents": ["github-copilot"],
27
+ "governanceProfile": "single-maintainer-gitflow",
27
28
  "codeAppsPlugin": false
28
29
  }
29
30
  ```
@@ -33,7 +34,7 @@ workload rather than silently ignored.
33
34
 
34
35
  ## `liftoff.manifest.json`: CLI-owned compatibility record
35
36
 
36
- New projects use manifest schema v4. Its common project identity includes the
37
+ New projects use manifest schema v5. Its common project identity includes the
37
38
  name, spec workflow, selected agents, and applicable Spec Kit default. A
38
39
  discriminated `project.workload` object contains only fields valid for one
39
40
  workload:
@@ -50,6 +51,8 @@ The manifest also records:
50
51
  - Durable artifact logical names.
51
52
  - OS-neutral path-part arrays.
52
53
  - `sha256:` content hashes.
54
+ - Repository governance profile, policy version, and local
55
+ `handoff-generated`, `handoff-partial`, or disabled state.
53
56
 
54
57
  Power Apps source identity uses explicit repository, path, and 40-character
55
58
  commit fields. It is not inferred from mutable URLs or generated file paths.
@@ -60,16 +63,21 @@ paths, or hashes.
60
63
 
61
64
  ## Compatibility
62
65
 
63
- Readers support schemas v2, v3, and v4:
66
+ Readers support schemas v2, v3, v4, and v5:
64
67
 
65
68
  - V2 normalizes the legacy flat API identity and records framework state as
66
69
  uncertain without inventing agents.
67
70
  - V3 normalizes flat GenAI or API identity plus framework and agent metadata.
68
71
  - V4 represents the discriminated workload model, including Power Apps.
72
+ - V5 adds repository-governance handoff identity without claiming live
73
+ enforcement.
69
74
 
70
75
  `liftoff update --check`, including `--check --json`, leaves an old manifest
71
- byte-for-byte unchanged. A successful plain update writes v4 only after the
72
- file transaction succeeds. Skipped conflicts retain their recorded hashes.
76
+ byte-for-byte unchanged. A successful plain update writes v5 only after the
77
+ file transaction succeeds. Previously recorded skipped conflicts retain their
78
+ hashes. A preserved unrecorded governance conflict has no artifact entry and
79
+ sets the update-written manifest to `handoff-partial`; resolving every such
80
+ conflict promotes the next manifest to `handoff-generated`.
73
81
 
74
82
  ## Artifact ownership
75
83
 
@@ -88,7 +96,7 @@ can follow their own lifecycle.
88
96
 
89
97
  ## Contract conventions
90
98
 
91
- - Writers use `artifactVersion` 4; readers support v2, v3, and v4.
99
+ - Writers use `artifactVersion` 5; readers support v2, v3, v4, and v5.
92
100
  - Artifact logical names and catalog identifiers are append-only.
93
101
  - Rendering is deterministic and does not depend on timestamps, host versions,
94
102
  or network state.
@@ -42,12 +42,13 @@ from unexpectedly treating that subdirectory as the repository root.
42
42
  Liftoff never blindly replaces a target tree. It:
43
43
 
44
44
  1. Renders Liftoff-owned files in temporary staging.
45
- 2. Runs the official OpenSpec or Spec Kit initializer in staging.
46
- 3. Rejects unexpected roots, nested Git metadata, and unsafe paths.
47
- 4. Compares every destination before writing.
48
- 5. Lists different regular files as one replacement set.
49
- 6. Requires explicit overwrite permission before replacing that set.
50
- 7. Applies the authorized merge transactionally and rolls back handled
45
+ 2. Verifies or separately configures the required global OpenSpec profile.
46
+ 3. Runs the official OpenSpec or Spec Kit initializer in staging.
47
+ 4. Rejects unexpected roots, nested Git metadata, and unsafe paths.
48
+ 5. Compares every destination before writing.
49
+ 6. Lists different regular files as one replacement set.
50
+ 7. Requires explicit overwrite permission before replacing that set.
51
+ 8. Applies the authorized merge transactionally and rolls back handled
51
52
  failures.
52
53
 
53
54
  Unrelated existing files are preserved. Structural collisions, symlinks,
@@ -74,6 +75,40 @@ automation, while preserving conflicts and orphans. Review every reported
74
75
  conflict and commit or copy local work before choosing `liftoff update --force`.
75
76
  For CI drift gates, use `liftoff update --check --json`.
76
77
 
78
+ OpenSpec skills and commands remain framework-owned. To give an existing
79
+ project all 12 workflows as both skills and commands, run:
80
+
81
+ ```bash
82
+ openspec config profile
83
+ openspec update
84
+ ```
85
+
86
+ Select both delivery modes and every workflow in the profile picker. Plain
87
+ `liftoff update` does not regenerate OpenSpec integrations. To change the
88
+ hosted Copilot agent later, update `githubCopilot.cloudAgent` through OpenSpec
89
+ and run `openspec update`.
90
+
91
+ Projects created before manifest schema v5 automatically preview the default
92
+ repository-governance handoff as new named drift. Plain update safely adopts
93
+ collision-free policy, context, guide, and selected-agent launchers without
94
+ rewriting a configuration that omitted `governanceProfile`. Existing different
95
+ files remain unowned conflicts and the v5 manifest records `handoff-partial`.
96
+ Resolving every conflict promotes a later update to `handoff-generated`.
97
+ Selecting `none` leaves previously managed handoff files as undeleted orphans
98
+ while unrecorded conflicts remain user-owned. No update mode runs an agent or
99
+ activates GitHub settings.
100
+
101
+ Major supported-stack releases can report many runtime, lock, Docker, provider,
102
+ and framework artifact changes at once. Treat those releases as breaking:
103
+ commit or copy local work, inspect `liftoff update --check`, and apply only after
104
+ reviewing all upgrades and conflicts. Plain update preserves conflicting local
105
+ bytes and never requires `--force` as the default migration path.
106
+
107
+ If an applied baseline migration must be reversed, restore the project and
108
+ manifest through version control and reinstall from the restored locks. Liftoff
109
+ does not automatically downgrade generated dependencies and retains no backup
110
+ after a successful update.
111
+
77
112
  ## Existing non-Liftoff application
78
113
 
79
114
  Use migration when you want a fresh governed scaffold and a filtered source
@@ -84,8 +119,9 @@ liftoff migrate ../legacy-app --region eastus --agents copilot,claude --yes
84
119
  ```
85
120
 
86
121
  Migration requires a new or empty sibling target, runs the same readiness and
87
- framework pipeline, and leaves the source byte-for-byte unchanged. `--force`
88
- does not permit a non-empty migration target.
122
+ framework pipeline, including separate global OpenSpec profile authorization,
123
+ and leaves the source byte-for-byte unchanged. `--force` does not permit a
124
+ non-empty migration target.
89
125
 
90
126
  Arbitrary existing Power Apps application migration is not currently
91
127
  supported.
@@ -5,8 +5,8 @@ standard APIs, and Power Apps code apps.
5
5
 
6
6
  ## 1. Install the CLI
7
7
 
8
- Liftoff requires Node.js 20.19 or newer. Power Apps code app projects require
9
- Node.js 22.12 or newer for their generated framework.
8
+ Liftoff and generated Node.js workloads require Node.js 24.20 or newer.
9
+ Python workloads use Python 3.14 with frozen `uv` dependency locks.
10
10
 
11
11
  The canonical release registry is `https://registry.npmjs.org`:
12
12
 
@@ -23,6 +23,18 @@ canonical npm. Stop if the mirror is older or rejects the explicit current
23
23
  version; ask the mirror owner to synchronize or approve the release. Liftoff
24
24
  does not modify `.npmrc` or bypass registry policy.
25
25
 
26
+ Versions predating the self-upgrade command require that manual global install
27
+ once. After a capable version is installed globally with npm, use:
28
+
29
+ ```bash
30
+ liftoff upgrade --check
31
+ liftoff upgrade
32
+ ```
33
+
34
+ `upgrade` replaces only the supported global CLI installation. It does not read
35
+ or update a generated project; inspect project template changes separately with
36
+ `liftoff update --check`.
37
+
26
38
  See [prerequisites](prerequisites.md) for the complete plan-derived tool model.
27
39
 
28
40
  ## 2. Start interactive initialization
@@ -37,16 +49,25 @@ The guided flow asks for:
37
49
 
38
50
  1. Project identity and workload: GenAI, API, or Power Apps code app.
39
51
  2. Only the architecture choices applicable to that workload.
40
- 3. OpenSpec or Spec Kit.
41
- 4. One or both coding agents. On a real TTY, Space toggles agents and Enter
52
+ 3. Whether to generate the default single-maintainer GitFlow repository-
53
+ governance handoff. Accepting it creates local files only.
54
+ 4. OpenSpec or Spec Kit.
55
+ 5. One or both coding agents. On a real TTY, Space toggles agents and Enter
42
56
  confirms the selection.
43
- 5. A Spec Kit default agent when both agents are selected.
44
- 6. The optional Preview Code Apps plugin preference for Power Apps projects.
45
- 7. Plan confirmation, workstation readiness, and any separate install or
57
+ 6. Whether to configure the default-off GitHub-hosted Copilot coding agent when
58
+ OpenSpec and GitHub Copilot are selected.
59
+ 7. A Spec Kit default agent when both agents are selected.
60
+ 8. The optional Preview Code Apps plugin preference for Power Apps projects.
61
+ 9. Plan confirmation, workstation readiness, and any separate install or
46
62
  overwrite permissions that are needed.
47
63
 
48
64
  Liftoff renders into temporary staging, runs the official framework initializer
49
65
  there, validates the complete result, and only then merges it into the target.
66
+ OpenSpec projects use all 12 OpenSpec 1.11 workflows as both skills and commands.
67
+ If the global OpenSpec profile differs, Liftoff displays the exact global change
68
+ and asks separately before staging.
69
+ Governance activation is a later selected-agent action after commit and push;
70
+ see [repository governance](repository-governance.md).
50
71
 
51
72
  ## 3. Understand the target
52
73
 
@@ -94,8 +115,12 @@ liftoff plan --type power-apps-code-app --spec openspec --agents copilot
94
115
 
95
116
  Automation can pass the same options to `liftoff init`. Use `--yes` for project
96
117
  defaults and confirmation only. It does not authorize file replacement,
97
- machine-level tools, or project dependency installation. Those permissions
98
- remain independent.
118
+ machine-level tools, global OpenSpec profile changes, Copilot cloud opt-in, or
119
+ project dependency installation. Those permissions remain independent.
120
+
121
+ Use `--configure-openspec-profile` only after reviewing the machine-wide change.
122
+ Use `--copilot-cloud` to opt into the hosted agent or `--no-copilot-cloud` to
123
+ record the safe default explicitly.
99
124
 
100
125
  See the [CLI reference](cli-reference.md) and
101
126
  [safety and consent](safety-and-consent.md) before automating initialization.
@@ -6,13 +6,21 @@ and a Go API is not asked to install Python.
6
6
 
7
7
  ## Baseline
8
8
 
9
- - Liftoff CLI: Node.js 20.19 or newer.
10
- - Power Apps code app: Node.js 22.12 or newer.
11
- - Selected framework: the Liftoff-tested OpenSpec or Spec Kit contract.
9
+ - Liftoff CLI and generated Node.js workloads: Node.js 24.20 or newer.
10
+ - Python projects: Python 3.14 and `uv` 0.12.7 or newer.
11
+ - Go projects: Go 1.27 or newer.
12
+ - Generated Azure infrastructure: OpenTofu 1.12.6 or newer.
13
+ - Selected framework: OpenSpec 1.11.0 or Spec Kit 1.0.1 exactly.
12
14
  - Selected agents: GitHub Copilot, Claude Code, or both.
13
15
 
16
+ Automatic `liftoff upgrade` additionally requires that the running canonical
17
+ `@msn-control/liftoff` package is a normal global npm installation beneath
18
+ `npm root --global`. Local dependencies, `npx` cache copies, linked checkouts,
19
+ and other package-manager stores use the documented manual global npm command
20
+ instead. Liftoff never requests elevation.
21
+
14
22
  API workloads additionally require their selected Python, Node.js, or Go
15
- runtime. GenAI uses Python 3.12 and the Python/FastAPI/PydanticAI stack.
23
+ runtime. GenAI uses Python 3.14 and the Python/FastAPI/PydanticAI stack.
16
24
 
17
25
  ## Blocking and advisory checks
18
26
 
@@ -21,6 +29,7 @@ Blocking checks must be ready before initialization can safely complete:
21
29
  - Required runtime and minimum version.
22
30
  - Selected spec framework CLI.
23
31
  - Every selected coding agent.
32
+ - For OpenSpec, global profile `custom`, delivery `both`, and all 12 workflows.
24
33
 
25
34
  Advisory checks describe useful but deferrable capabilities:
26
35
 
@@ -32,6 +41,11 @@ Advisory checks describe useful but deferrable capabilities:
32
41
  Authentication checks are read-only. Liftoff never stores credentials or signs
33
42
  in to a cloud or agent on your behalf.
34
43
 
44
+ The default repository-governance handoff has no additional initialization
45
+ prerequisite. `gh`, a remote, licensed GitHub security features, private runners,
46
+ Slack, and deployment access are discovered only during post-push Phase 0 and
47
+ may be reported as gaps; they do not block local generation.
48
+
35
49
  ## Preview requirements without writes
36
50
 
37
51
  `liftoff plan` shows both generated artifacts and workstation requirements
@@ -56,6 +70,22 @@ An install that changes `PATH` is re-probed when possible and may require a new
56
70
  terminal. Do not treat installer success as readiness until the corresponding
57
71
  probe passes.
58
72
 
73
+ ## OpenSpec global profile consent
74
+
75
+ OpenSpec 1.11 stores workflow selection and delivery globally rather than in a
76
+ project. Liftoff requires all workflows with both skills and commands so a fresh
77
+ project does not immediately drift when OpenSpec is rerun.
78
+
79
+ Profile inspection is read-only. When the profile differs, interactive runs
80
+ show the observed values, required values, and exact `openspec config set`
81
+ commands before asking. Noninteractive runs stop unless
82
+ `--configure-openspec-profile` is present. This authorization is independent of
83
+ `--yes`, `--force`, and tool or dependency installation.
84
+
85
+ The authorized change is verified before project staging. Because it is a
86
+ machine-wide user preference, Liftoff reports it separately and does not restore
87
+ an older profile if a later project phase fails.
88
+
59
89
  ## Project dependency consent
60
90
 
61
91
  Project-local dependency setup is separate from workstation tools and requires
@@ -76,6 +106,19 @@ the project is ready.
76
106
  GenAI and API projects use their generated stack-native locked dependency
77
107
  commands.
78
108
 
109
+ Python projects use the generated lock without resolving new versions:
110
+
111
+ ```bash
112
+ uv sync --frozen --project backend --extra test
113
+ ```
114
+
115
+ Worker-enabled GenAI projects add `--extra functions`. Node.js projects use
116
+ `npm ci`, and Go projects use `go mod download`.
117
+
118
+ Liftoff's npm locks are generated with npm 12.0.2 and verified in the supported
119
+ compatibility lanes. Do not replace a committed lock with an install from
120
+ open-ended manifest ranges.
121
+
79
122
  ## Power Apps local CLI
80
123
 
81
124
  The Power Apps CLI is supplied by the generated project dependency graph.
@@ -14,7 +14,13 @@ project/
14
14
  |-- .env.example
15
15
  |-- Dockerfile
16
16
  |-- docker-compose.yml
17
+ |-- .liftoff/
18
+ | `-- governance/ # durable local handoff when enabled
19
+ | |-- policy.md
20
+ | |-- context.json
21
+ | `-- README.md
17
22
  |-- backend/
23
+ | `-- uv.lock # Python stacks only
18
24
  |-- database/
19
25
  | |-- alembic.ini or stack-native migration config
20
26
  | |-- migrations/
@@ -26,7 +32,14 @@ project/
26
32
  |-- infrastructure/
27
33
  | `-- opentofu/
28
34
  | `-- azure/
35
+ | `-- .terraform.lock.hcl
29
36
  |-- openspec/ or .specify/
37
+ |-- .github/skills/openspec-*/ and .github/prompts/opsx-* # OpenSpec + Copilot
38
+ |-- .claude/skills/openspec-*/ and .claude/commands/opsx/ # OpenSpec + Claude
39
+ |-- .github/workflows/copilot-setup-steps.yml # optional hosted agent
40
+ |-- .github/agents/openspec.agent.md # optional hosted agent
41
+ |-- .github/prompts/liftoff-repository-governance.prompt.md
42
+ | or .claude/commands/liftoff-repository-governance.md
30
43
  |-- frontend/ # only when selected
31
44
  |-- functions/<worker-name>/ # only for worker-enabled GenAI patterns
32
45
  `-- migration/legacy/ # only after liftoff migrate
@@ -45,11 +58,18 @@ project/
45
58
  Functions settings when a worker is generated.
46
59
  - `docker-compose.yml` starts the selected backend, PostgreSQL, Redis,
47
60
  Azurite, and Mailpit. GenAI projects use pgvector where needed and include an
48
- optional Langfuse profile.
61
+ optional Langfuse v4 web/worker profile backed by ClickHouse, dedicated Redis,
62
+ and MinIO.
63
+ - Python Docker builds export the committed `uv.lock` in frozen mode and install
64
+ only hash-verified requirements. `UV_DEFAULT_INDEX` can select a
65
+ credential-free managed mirror without changing the lock.
49
66
  - `infrastructure/opentofu/azure` contains modules, environment tfvars, local
50
67
  state configuration, and a remote-state example.
51
68
  - `openspec` is created for OpenSpec. `.specify` and `specs` are created for
52
69
  Spec Kit.
70
+ - OpenSpec projects receive all 12 pinned workflows as both skills and commands
71
+ for supported selected-agent surfaces. The two hosted Copilot agent files are
72
+ generated only after explicit opt-in.
53
73
 
54
74
  ### Conditional areas
55
75
 
@@ -87,6 +107,12 @@ project/
87
107
  `-- openspec/ or .specify/
88
108
  ```
89
109
 
110
+ The exact selected-agent governance launcher is generated only when the
111
+ repository-governance profile is enabled. It is Liftoff-owned; neighboring
112
+ framework files remain framework-owned. Agent-created governance changes and
113
+ `governance/activation-baseline.json` remain user-owned and are not listed in
114
+ the manifest.
115
+
90
116
  This root follows the pinned official Microsoft starter. It includes the
91
117
  Power Apps SDK, Vite plugin, and project-local CLI through locked npm
92
118
  dependencies.
@@ -0,0 +1,91 @@
1
+ # Repository governance handoff
2
+
3
+ Repository governance is a common Liftoff project choice. The default
4
+ `single-maintainer-gitflow` profile generates a deterministic local handoff;
5
+ `none` opts out:
6
+
7
+ **Local handoff generated; live enforcement is not active.**
8
+
9
+ ```bash
10
+ liftoff plan --governance single-maintainer-gitflow
11
+ liftoff init --governance none
12
+ ```
13
+
14
+ Accepting the default or passing `--yes` authorizes only local project files. It
15
+ does not run an agent, mutate Git, contact GitHub, configure security, install a
16
+ ruleset, deploy, or create monitoring.
17
+
18
+ ## Generated files
19
+
20
+ An enabled profile adds durable, hash-managed artifacts:
21
+
22
+ ```text
23
+ .liftoff/governance/policy.md
24
+ .liftoff/governance/context.json
25
+ .liftoff/governance/README.md
26
+ .github/prompts/liftoff-repository-governance.prompt.md # Copilot selected
27
+ .claude/commands/liftoff-repository-governance.md # Claude selected
28
+ ```
29
+
30
+ The complete canonical policy is also packaged with Liftoff at
31
+ [`assets/governance/single-maintainer-gitflow/policy.md`](../assets/governance/single-maintainer-gitflow/policy.md).
32
+ It covers GitFlow, zero-human-approval repository rules, designated security
33
+ tools, fail-closed checks, immutable release evidence, build-once promotion,
34
+ deployment and rollback, monitoring and health, DORA metrics, ruleset
35
+ sequencing, negative tests, documentation, and workload adaptation.
36
+
37
+ `context.json` contains generated project facts only. GitHub repository state,
38
+ runner access, licensed features, deployments, monitoring, alert routes,
39
+ traffic, and rollout capabilities remain `undiscovered`. Power Apps context
40
+ explicitly marks Liftoff backend, Docker, OpenTofu, custom container promotion,
41
+ and API DAST as inapplicable.
42
+
43
+ ## Activate after commit and push
44
+
45
+ 1. Review the policy and context.
46
+ 2. Commit the project and push it to the intended GitHub repository.
47
+ 3. Run `/liftoff-repository-governance` with a selected agent.
48
+ 4. The agent performs read-only Phase 0 and reports repository identity,
49
+ artifacts, working commands, refs, workflows and exact checks, rulesets,
50
+ releases, environments, security, runners, deployments, monitoring, alerts,
51
+ health depth, platform capabilities, gaps, and inapplicable controls.
52
+ 5. The agent proposes the current `main` SHA as the activation baseline,
53
+ presents an ordered plan, and stops.
54
+ 6. Explicitly approve or revise the conversational plan. This is not a human
55
+ merge or deployment approval gate.
56
+ 7. After approval, the agent creates a new OpenSpec or Spec Kit governance
57
+ change, proves required contexts green and deliberately red, applies
58
+ repository-scoped rulesets last, and reads live enforcement back.
59
+
60
+ The user-owned `governance/activation-baseline.json` is created only after
61
+ approval. Liftoff never owns or recreates it or the agent-created governance
62
+ change. Complete local handoffs say `handoff-generated`, partial adoptions say
63
+ `handoff-partial`, and neither state means `active`.
64
+
65
+ ## Existing projects
66
+
67
+ Configurations without `governanceProfile` normalize to the enabled default
68
+ without rewriting `liftoff.config.json`:
69
+
70
+ ```bash
71
+ liftoff update --check
72
+ liftoff update
73
+ ```
74
+
75
+ Check mode previews the schema-v5 manifest and new named artifacts without
76
+ writing. Plain update applies collision-free files; differing existing files
77
+ remain conflicts unless individually reviewed with `--force`. An unrecorded
78
+ conflict remains outside Liftoff ownership and produces `handoff-partial`.
79
+ After every conflict is removed or matches the current artifact, the next
80
+ update records the full artifact set as `handoff-generated`.
81
+
82
+ Setting `"governanceProfile": "none"` stops future rendering. Previously managed
83
+ handoff files are reported once as orphans and left on disk; Liftoff never
84
+ deletes them automatically or changes live repository settings.
85
+
86
+ ## Capability gaps
87
+
88
+ Phase 0 must report missing GitHub licenses, private runners, staging access,
89
+ monitoring routes, parallel-version mechanisms, or statistically meaningful
90
+ canary traffic. It must mark controls inapplicable or blocked rather than
91
+ creating a skipped, hanging, duplicate, or success-shaped placeholder.