@msn-control/liftoff 0.8.0 → 0.9.1

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 (55) hide show
  1. package/README.md +11 -5
  2. package/assets/locks/frontend/package-lock.json +51 -51
  3. package/assets/locks/frontend/package.json +1 -1
  4. package/assets/locks/node-backend/package-lock.json +353 -12
  5. package/assets/locks/node-backend/package.json +3 -3
  6. package/assets/supported-stack.json +9 -9
  7. package/dist/args.js +7 -5
  8. package/dist/args.js.map +1 -1
  9. package/dist/artifact-lifecycle.d.ts +4 -0
  10. package/dist/artifact-lifecycle.js +38 -0
  11. package/dist/artifact-lifecycle.js.map +1 -0
  12. package/dist/commands.js +415 -77
  13. package/dist/commands.js.map +1 -1
  14. package/dist/file-system.d.ts +1 -1
  15. package/dist/file-system.js +171 -29
  16. package/dist/file-system.js.map +1 -1
  17. package/dist/framework-adapters.d.ts +1 -1
  18. package/dist/framework-adapters.js +9 -3
  19. package/dist/framework-adapters.js.map +1 -1
  20. package/dist/framework-validation.d.ts +1 -0
  21. package/dist/framework-validation.js +26 -0
  22. package/dist/framework-validation.js.map +1 -1
  23. package/dist/init-filesystem.js +2 -2
  24. package/dist/init-filesystem.js.map +1 -1
  25. package/dist/interactive.d.ts +13 -0
  26. package/dist/interactive.js +14 -0
  27. package/dist/interactive.js.map +1 -1
  28. package/dist/openspec-profile.d.ts +28 -0
  29. package/dist/openspec-profile.js +172 -0
  30. package/dist/openspec-profile.js.map +1 -0
  31. package/dist/planner.js +19 -1
  32. package/dist/planner.js.map +1 -1
  33. package/dist/power-apps-templates.js +15 -1
  34. package/dist/power-apps-templates.js.map +1 -1
  35. package/dist/reconcile.js +4 -10
  36. package/dist/reconcile.js.map +1 -1
  37. package/dist/repository-governance.js +4 -0
  38. package/dist/repository-governance.js.map +1 -1
  39. package/dist/templates.d.ts +5 -1
  40. package/dist/templates.js +126 -60
  41. package/dist/templates.js.map +1 -1
  42. package/dist/types.d.ts +27 -4
  43. package/docs/cli-reference.md +52 -25
  44. package/docs/configuration-and-manifests.md +39 -24
  45. package/docs/existing-repositories.md +38 -23
  46. package/docs/getting-started.md +17 -7
  47. package/docs/prerequisites.md +17 -0
  48. package/docs/project-structure.md +13 -1
  49. package/docs/repository-governance.md +2 -2
  50. package/docs/safety-and-consent.md +47 -30
  51. package/docs/spec-workflows-and-agents.md +47 -7
  52. package/docs/supported-stack.md +14 -17
  53. package/docs/troubleshooting.md +53 -8
  54. package/docs/workloads.md +9 -8
  55. package/package.json +1 -1
package/dist/types.d.ts CHANGED
@@ -115,6 +115,8 @@ export interface ProjectOptions {
115
115
  agents?: string[];
116
116
  defaultAgent?: string;
117
117
  codeAppsPlugin?: boolean;
118
+ copilotCloud?: boolean;
119
+ configureOpenSpecProfile?: boolean;
118
120
  governanceProfile?: string;
119
121
  configPath?: string;
120
122
  yes?: boolean;
@@ -156,6 +158,7 @@ export interface ProjectPlanBase {
156
158
  specWorkflow: SpecWorkflowDefinition;
157
159
  agents: CodingAgentDefinition[];
158
160
  defaultAgent?: CodingAgentDefinition;
161
+ copilotCloud: boolean;
159
162
  framework: FrameworkDefinition;
160
163
  governanceProfile: GovernanceProfileDefinition;
161
164
  approvedStack: string[];
@@ -165,18 +168,36 @@ export type GenAiProjectPlan = ProjectPlanBase & GenAiWorkloadPlan;
165
168
  export type StandardApiProjectPlan = ProjectPlanBase & StandardApiWorkloadPlan;
166
169
  export type ApiProjectPlan = GenAiProjectPlan | StandardApiProjectPlan;
167
170
  export type PowerAppsCodeAppProjectPlan = ProjectPlanBase & PowerAppsCodeAppWorkloadPlan;
168
- export interface GeneratedArtifact {
171
+ export type ArtifactLifecycle = 'managed-core' | 'project' | 'desired-state' | 'framework' | 'seed' | 'manifest';
172
+ export type ProjectProvisioningGroup = 'base' | 'frontend' | `environment:${EnvironmentId}` | 'power-apps-starter';
173
+ interface GeneratedArtifactBase {
169
174
  logicalName: string;
170
175
  category: string;
171
176
  pathParts: string[];
172
177
  content: string;
173
178
  }
174
- export interface ManifestArtifact {
179
+ export type GeneratedArtifact = (GeneratedArtifactBase & {
180
+ lifecycle: 'project';
181
+ provisioningGroup: ProjectProvisioningGroup;
182
+ }) | (GeneratedArtifactBase & {
183
+ lifecycle: Exclude<ArtifactLifecycle, 'project'>;
184
+ provisioningGroup?: never;
185
+ });
186
+ export interface ManifestManagedArtifact {
175
187
  logicalName: string;
176
188
  category: string;
177
189
  pathParts: string[];
178
190
  contentHash: string;
179
191
  }
192
+ export interface ManifestProjectArtifact {
193
+ logicalName: string;
194
+ category: string;
195
+ pathParts: string[];
196
+ generatedBy: string;
197
+ generationHash: string;
198
+ provisioningGroup: ProjectProvisioningGroup;
199
+ }
200
+ export type ManifestArtifact = ManifestManagedArtifact;
180
201
  export interface ManifestGenAiWorkload {
181
202
  kind: 'genai';
182
203
  apiStack: ApiStackId;
@@ -206,7 +227,7 @@ export interface ManifestGovernance {
206
227
  policyVersion?: string;
207
228
  }
208
229
  export interface LiftoffManifest {
209
- artifactVersion: 2 | 3 | 4 | 5;
230
+ artifactVersion: 2 | 3 | 4 | 5 | 6;
210
231
  generatedBy: 'Mission Control Liftoff';
211
232
  liftoffVersion: string;
212
233
  project: {
@@ -222,7 +243,8 @@ export interface LiftoffManifest {
222
243
  contractVersion?: string;
223
244
  };
224
245
  governance: ManifestGovernance;
225
- artifacts: ManifestArtifact[];
246
+ managedArtifacts: ManifestManagedArtifact[];
247
+ projectArtifacts: ManifestProjectArtifact[];
226
248
  }
227
249
  export interface ParsedArgs {
228
250
  command?: string;
@@ -230,3 +252,4 @@ export interface ParsedArgs {
230
252
  positional: string[];
231
253
  flags: Record<string, string | boolean | string[]>;
232
254
  }
255
+ export {};
@@ -23,13 +23,13 @@ install -> upgrade CLI -> plan -> init or migrate -> validate and doctor -> upda
23
23
  | `liftoff plan` | Resolves decisions and previews artifacts and requirements without side effects |
24
24
  | `liftoff init [project-name]` | Initializes a named child or the exact current Git root through staged readiness and framework setup |
25
25
  | `liftoff migrate <source>` | Creates a new sibling scaffold and filtered source copy without changing the source |
26
- | `liftoff validate [project]` | Validates manifest identity, durable files, workload metadata, and framework markers |
26
+ | `liftoff validate [project]` | Validates manifest identity, managed-core hashes, project provenance, workload metadata, and framework markers |
27
27
  | `liftoff doctor [project]` | Runs read-only workload-derived project and workstation diagnostics |
28
28
  | `liftoff upgrade` | Replaces a verified global npm installation with the exact canonical stable release exposed by the configured registry |
29
29
  | `liftoff upgrade --check` | Checks installation origin and registry parity without installing; exits 2 when an installable update exists |
30
- | `liftoff update [project]` | Applies safe managed drift immediately, preserves unforced conflicts and orphans, and records the resulting manifest |
31
- | `liftoff update --check` | Reports drift without preflight or mutation; exits 0 when clean and 2 when drift exists |
32
- | `liftoff update --force` | Applies safe changes and overwrites only the exact guarded conflicts reported by update |
30
+ | `liftoff update [project]` | Applies safe managed-core maintenance and authorized create-only component provisioning |
31
+ | `liftoff update --check` | Reports core maintenance and provisioning without mutation; exits 0 when clean and 2 when actionable |
32
+ | `liftoff update --force` | Overwrites only exact guarded managed-core conflicts; project-owned files remain unreachable |
33
33
  | `liftoff dev` | Prints workload-appropriate local development commands; it does not execute them |
34
34
  | `liftoff infra` | Prints OpenTofu guidance for API workloads and reports infrastructure as not applicable for Power Apps |
35
35
  | `liftoff patterns` | Lists GenAI patterns |
@@ -63,6 +63,8 @@ Common noninteractive inputs include:
63
63
  --default-agent copilot|claude
64
64
  --governance single-maintainer-gitflow|none
65
65
  --code-apps-plugin | --no-code-apps-plugin
66
+ --copilot-cloud | --no-copilot-cloud
67
+ --configure-openspec-profile
66
68
  ```
67
69
 
68
70
  Power Apps rejects API, pattern, cloud, region, frontend, and API environment
@@ -73,6 +75,17 @@ Repository governance defaults to `single-maintainer-gitflow`. It generates a
73
75
  local policy handoff only; `none` omits it. See
74
76
  [repository governance](repository-governance.md).
75
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
+
76
89
  ## CLI upgrade modes
77
90
 
78
91
  ```bash
@@ -119,32 +132,44 @@ liftoff update --check --json
119
132
  ```
120
133
 
121
134
  Plain `liftoff update` is imperative and prompt-free. It applies safe new,
122
- missing, untouched-upgrade, clean-move, and recorded-state changes in
123
- interactive terminals, redirected streams, and automation. Local or user-owned
124
- conflicts are skipped and reported. Orphans are reported without deletion.
125
- During legacy governance adoption, preserved unrecorded conflicts remain
126
- outside manifest ownership and set local state to `handoff-partial` until a
127
- later update can write or byte-identically adopt every required artifact.
128
-
129
- Use `--check` whenever no project bytes may change. Human check mode prints each
130
- drift state and recommends plain update for safe changes or a reviewed
131
- `--force` invocation for conflicts. `--check --force` is invalid because check
132
- mode never authorizes writes.
135
+ missing, untouched-upgrade, clean-move, and recorded-state changes only for
136
+ explicit `managed-core` artifacts. Core conflicts are skipped and core orphans
137
+ are reported without deletion. During legacy governance adoption, preserved
138
+ unrecorded conflicts remain outside managed ownership and set local state to
139
+ `handoff-partial`.
140
+
141
+ Application source, tests, dependencies and locks, database assets, Docker and
142
+ Compose files, environment files, documentation, Power Apps starter files, and
143
+ OpenTofu topology are `project` artifacts after generation. Update does not
144
+ compare them with newer templates, restore deleted paths, or overwrite them
145
+ under `--force`.
146
+
147
+ Changing desired state from no frontend to frontend, or adding an environment,
148
+ can authorize one create-only provisioning group. All destinations are
149
+ preflighted together. Absent files are created and byte-identical files are
150
+ adopted as provenance; any differing destination blocks the group even with
151
+ `--force`. Disabling or re-enabling a previously provisioned group never
152
+ recreates or deletes project files.
153
+
154
+ Use `--check` whenever no project bytes may change. Human check mode prints
155
+ managed-core drift, ownership-only manifest migration, and authorized
156
+ provisioning. It recommends `--force` only for core conflicts. `--check
157
+ --force` is invalid because check mode never authorizes writes.
133
158
 
134
159
  `--json` selects output format, not safety. `liftoff update --json` applies safe
135
160
  changes and emits the versioned apply result. `liftoff update --check --json`
136
161
  is the read-only automation gate.
137
162
 
138
163
  Update never installs dependencies. Transaction snapshots restore a failed
139
- update, but Liftoff retains no backup after a successful overwrite; commit or
140
- copy local work before using `--force`. Force does not permit workload, API
141
- stack, GenAI pattern, framework, selected-agent, or user-supplied Power Apps
142
- starter identity changes, and it cannot bypass project-boundary, symlink,
143
- structural-collision, or manifest guards.
164
+ core update, but Liftoff retains no backup after a successful core overwrite.
165
+ Force cannot bypass the ownership, project-boundary, symlink, structural,
166
+ identity, or manifest guards.
144
167
 
145
- For a breaking supported-stack release, inspect `liftoff update --check` before
146
- plain update. Restore an unwanted applied migration through version control;
147
- running an older CLI is not a supported automatic downgrade.
168
+ New dependency, runtime, container, database, application, Power Apps starter,
169
+ and infrastructure templates apply to newly generated projects. Existing
170
+ production projects adopt them through a separately reviewed project change.
171
+ The existing `liftoff migrate` command only adopts a non-Liftoff source into a
172
+ fresh target; it is not an in-place template upgrade.
148
173
 
149
174
  ### Migration from 0.6.x
150
175
 
@@ -173,7 +198,9 @@ liftoff update --json
173
198
  liftoff update --check --json
174
199
  ```
175
200
 
176
- Each JSON object has a top-level numeric `schemaVersion`.
201
+ Each JSON object has a top-level numeric `schemaVersion`. Update JSON uses
202
+ schema version 2 and includes `scope: "managed-core"`, ownership-migration
203
+ state, and a separate provisioning collection.
177
204
  Operational warnings, such as a dirty-worktree warning before JSON apply, are
178
205
  written to stderr so stdout remains one parseable JSON object.
179
206
 
@@ -181,7 +208,7 @@ Exit codes:
181
208
 
182
209
  - `0`: success or a clean check.
183
210
  - `1`: invalid input, unsafe state, or command failure.
184
- - `2`: an explicit update check found project drift, or upgrade check found an
211
+ - `2`: an explicit update check found core maintenance or provisioning, or upgrade check found an
185
212
  installable CLI release.
186
213
 
187
214
  Raw installer, framework, and dependency child stdout and stderr are forwarded
@@ -9,9 +9,14 @@ machine-rewrite it afterward.
9
9
 
10
10
  Supported edits are reconciled by `liftoff update`:
11
11
 
12
- - API workloads can add or remove environments and enable applicable generated
13
- areas such as the frontend.
14
- - Power Apps can change the optional Code Apps plugin preference.
12
+ - API workloads can select a previously absent environment or frontend. Update
13
+ provisions that component once only when its destinations are absent or
14
+ byte-identical; a differing destination blocks the complete component and
15
+ cannot be forced.
16
+ - Removing or re-enabling a previously provisioned component never deletes,
17
+ restores, or overwrites its project-owned files.
18
+ - Power Apps can change the optional Code Apps plugin preference; only manifest
19
+ intent and applicable managed-core context change.
15
20
 
16
21
  Workload kind, API stack, GenAI pattern, spec workflow, selected agents, and a
17
22
  user-supplied Power Apps starter source change are not ordinary updates.
@@ -34,7 +39,7 @@ workload rather than silently ignored.
34
39
 
35
40
  ## `liftoff.manifest.json`: CLI-owned compatibility record
36
41
 
37
- New projects use manifest schema v5. Its common project identity includes the
42
+ New projects use manifest schema v6. Its common project identity includes the
38
43
  name, spec workflow, selected agents, and applicable Spec Kit default. A
39
44
  discriminated `project.workload` object contains only fields valid for one
40
45
  workload:
@@ -46,11 +51,14 @@ workload:
46
51
 
47
52
  The manifest also records:
48
53
 
49
- - Generating Liftoff version.
54
+ - Last manifest-writing Liftoff version.
50
55
  - Official framework adapter, state, and tested contract version when known.
51
- - Durable artifact logical names.
56
+ - `managedArtifacts`: exact Liftoff core logical names, paths, and
57
+ reconciliation `contentHash` values.
58
+ - `projectArtifacts`: starter provenance with the original path, generating
59
+ Liftoff version, `generationHash`, and provisioning group. These hashes never
60
+ authorize update writes.
52
61
  - OS-neutral path-part arrays.
53
- - `sha256:` content hashes.
54
62
  - Repository governance profile, policy version, and local
55
63
  `handoff-generated`, `handoff-partial`, or disabled state.
56
64
 
@@ -63,7 +71,7 @@ paths, or hashes.
63
71
 
64
72
  ## Compatibility
65
73
 
66
- Readers support schemas v2, v3, v4, and v5:
74
+ Readers support schemas v2, v3, v4, v5, and v6:
67
75
 
68
76
  - V2 normalizes the legacy flat API identity and records framework state as
69
77
  uncertain without inventing agents.
@@ -71,32 +79,39 @@ Readers support schemas v2, v3, v4, and v5:
71
79
  - V4 represents the discriminated workload model, including Power Apps.
72
80
  - V5 adds repository-governance handoff identity without claiming live
73
81
  enforcement.
82
+ - V6 separates managed-core update authority from project generation
83
+ provenance.
74
84
 
75
85
  `liftoff update --check`, including `--check --json`, leaves an old manifest
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`.
86
+ byte-for-byte unchanged. A successful plain update writes v6 only after the
87
+ transaction succeeds. V2-v5 backend, frontend, database, dependency, container,
88
+ environment, documentation, Power Apps, and infrastructure entries become
89
+ project provenance without reading or changing current production bytes.
90
+ Intentionally deleted files remain absent. Only exact current core logical
91
+ names retain write authority.
81
92
 
82
93
  ## Artifact ownership
83
94
 
84
- Durable Liftoff artifacts carry logical names and hashes. That lets validate,
85
- doctor, and update distinguish:
95
+ Every generated artifact has an explicit lifecycle independent from its
96
+ category or filename:
86
97
 
87
- - Current template bytes.
88
- - An untouched file with a template upgrade.
89
- - A developer edit that conflicts with a template change.
90
- - A named artifact moved by the template.
91
- - Missing, new, and orphaned artifacts.
98
+ | Lifecycle | Owner after initialization | Update behavior |
99
+ | --- | --- | --- |
100
+ | `managed-core` | Liftoff | Safe reconciliation; reviewed core conflicts may use `--force` |
101
+ | `project` | Developer/project | Provenance only; never compared, restored, moved, or overwritten |
102
+ | `desired-state` | Developer | Read as input and never machine-rewritten |
103
+ | `framework` | Official framework | Validated through framework markers and maintained by that framework |
104
+ | `seed` | Developer/project | Written once and never reconciled |
92
105
 
93
- Framework-owned OpenSpec and Spec Kit files are validated separately and are
94
- not claimed in durable hashes. One-time seed files are also excluded so they
95
- can follow their own lifecycle.
106
+ The manifest is a CLI-owned transaction record rather than an ordinary
107
+ template artifact. Current managed core is limited to the exact repository
108
+ governance policy, context, guide, and selected-agent launchers. A name such as
109
+ `config.go`, a `configuration` category, or a path under `.github` does not
110
+ grant update authority.
96
111
 
97
112
  ## Contract conventions
98
113
 
99
- - Writers use `artifactVersion` 5; readers support v2, v3, v4, and v5.
114
+ - Writers use `artifactVersion` 6; readers support v2, v3, v4, v5, and v6.
100
115
  - Artifact logical names and catalog identifiers are append-only.
101
116
  - Rendering is deterministic and does not depend on timestamps, host versions,
102
117
  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,
@@ -69,31 +70,44 @@ liftoff update
69
70
  ```
70
71
 
71
72
  Use `--check` first when the invocation must be read-only. Plain update applies
72
- safe managed changes immediately and without prompting in terminals and
73
- automation, while preserving conflicts and orphans. Review every reported
74
- conflict and commit or copy local work before choosing `liftoff update --force`.
75
- For CI drift gates, use `liftoff update --check --json`.
73
+ safe managed-core changes immediately and preserves core conflicts and orphans.
74
+ `--force` can replace only listed core conflicts. Project-owned production
75
+ files are not compared and remain unreachable from every update mode. For CI
76
+ core-maintenance gates, use `liftoff update --check --json`.
76
77
 
77
- Projects created before manifest schema v5 automatically preview the default
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 v6 automatically preview the default
78
92
  repository-governance handoff as new named drift. Plain update safely adopts
79
93
  collision-free policy, context, guide, and selected-agent launchers without
80
94
  rewriting a configuration that omitted `governanceProfile`. Existing different
81
- files remain unowned conflicts and the v5 manifest records `handoff-partial`.
95
+ files remain unowned conflicts and the v6 manifest records `handoff-partial`.
82
96
  Resolving every conflict promotes a later update to `handoff-generated`.
83
97
  Selecting `none` leaves previously managed handoff files as undeleted orphans
84
98
  while unrecorded conflicts remain user-owned. No update mode runs an agent or
85
99
  activates GitHub settings.
86
100
 
87
- Major supported-stack releases can report many runtime, lock, Docker, provider,
88
- and framework artifact changes at once. Treat those releases as breaking:
89
- commit or copy local work, inspect `liftoff update --check`, and apply only after
90
- reviewing all upgrades and conflicts. Plain update preserves conflicting local
91
- bytes and never requires `--force` as the default migration path.
101
+ The schema-v6 transition releases every legacy non-core artifact into project
102
+ provenance without writing, restoring, moving, or deleting its path.
103
+ Intentionally removed infrastructure stays absent and production source stays
104
+ byte-for-byte unchanged.
92
105
 
93
- If an applied baseline migration must be reversed, restore the project and
94
- manifest through version control and reinstall from the restored locks. Liftoff
95
- does not automatically downgrade generated dependencies and retains no backup
96
- after a successful update.
106
+ Major supported-stack releases apply to new scaffolds. Existing projects adopt
107
+ runtime, lock, Docker, provider, framework, and application changes through a
108
+ normal reviewed project change. Ordinary update and force cannot perform that
109
+ migration, and the existing `liftoff migrate` command remains a fresh-target
110
+ workflow for non-Liftoff sources.
97
111
 
98
112
  ## Existing non-Liftoff application
99
113
 
@@ -105,8 +119,9 @@ liftoff migrate ../legacy-app --region eastus --agents copilot,claude --yes
105
119
  ```
106
120
 
107
121
  Migration requires a new or empty sibling target, runs the same readiness and
108
- framework pipeline, and leaves the source byte-for-byte unchanged. `--force`
109
- 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.
110
125
 
111
126
  Arbitrary existing Power Apps application migration is not currently
112
127
  supported.
@@ -32,8 +32,9 @@ liftoff upgrade
32
32
  ```
33
33
 
34
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`.
35
+ or update a generated project. Inspect Liftoff-managed core maintenance
36
+ separately with `liftoff update --check`; production template modernization is
37
+ a reviewed project change.
37
38
 
38
39
  See [prerequisites](prerequisites.md) for the complete plan-derived tool model.
39
40
 
@@ -54,13 +55,18 @@ The guided flow asks for:
54
55
  4. OpenSpec or Spec Kit.
55
56
  5. One or both coding agents. On a real TTY, Space toggles agents and Enter
56
57
  confirms the selection.
57
- 6. A Spec Kit default agent when both agents are selected.
58
- 7. The optional Preview Code Apps plugin preference for Power Apps projects.
59
- 8. Plan confirmation, workstation readiness, and any separate install or
58
+ 6. Whether to configure the default-off GitHub-hosted Copilot coding agent when
59
+ OpenSpec and GitHub Copilot are selected.
60
+ 7. A Spec Kit default agent when both agents are selected.
61
+ 8. The optional Preview Code Apps plugin preference for Power Apps projects.
62
+ 9. Plan confirmation, workstation readiness, and any separate install or
60
63
  overwrite permissions that are needed.
61
64
 
62
65
  Liftoff renders into temporary staging, runs the official framework initializer
63
66
  there, validates the complete result, and only then merges it into the target.
67
+ OpenSpec projects use all 12 OpenSpec 1.11 workflows as both skills and commands.
68
+ If the global OpenSpec profile differs, Liftoff displays the exact global change
69
+ and asks separately before staging.
64
70
  Governance activation is a later selected-agent action after commit and push;
65
71
  see [repository governance](repository-governance.md).
66
72
 
@@ -110,8 +116,12 @@ liftoff plan --type power-apps-code-app --spec openspec --agents copilot
110
116
 
111
117
  Automation can pass the same options to `liftoff init`. Use `--yes` for project
112
118
  defaults and confirmation only. It does not authorize file replacement,
113
- machine-level tools, or project dependency installation. Those permissions
114
- remain independent.
119
+ machine-level tools, global OpenSpec profile changes, Copilot cloud opt-in, or
120
+ project dependency installation. Those permissions remain independent.
121
+
122
+ Use `--configure-openspec-profile` only after reviewing the machine-wide change.
123
+ Use `--copilot-cloud` to opt into the hosted agent or `--no-copilot-cloud` to
124
+ record the safe default explicitly.
115
125
 
116
126
  See the [CLI reference](cli-reference.md) and
117
127
  [safety and consent](safety-and-consent.md) before automating initialization.
@@ -29,6 +29,7 @@ Blocking checks must be ready before initialization can safely complete:
29
29
  - Required runtime and minimum version.
30
30
  - Selected spec framework CLI.
31
31
  - Every selected coding agent.
32
+ - For OpenSpec, global profile `custom`, delivery `both`, and all 12 workflows.
32
33
 
33
34
  Advisory checks describe useful but deferrable capabilities:
34
35
 
@@ -69,6 +70,22 @@ An install that changes `PATH` is re-probed when possible and may require a new
69
70
  terminal. Do not treat installer success as readiness until the corresponding
70
71
  probe passes.
71
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
+
72
89
  ## Project dependency consent
73
90
 
74
91
  Project-local dependency setup is separate from workstation tools and requires
@@ -4,6 +4,11 @@ Generated paths are logical examples. Liftoff uses platform-correct filesystem
4
4
  handling on Windows, macOS, and Linux, and manifests store path-part arrays
5
5
  instead of joined strings.
6
6
 
7
+ After initialization, workload paths shown below are project-owned production
8
+ assets. Their manifest entries preserve generation provenance but
9
+ `liftoff update`, including `--force`, cannot compare, restore, move, or replace
10
+ them. Only exact files labeled as managed core retain Liftoff write authority.
11
+
7
12
  ## GenAI and API projects
8
13
 
9
14
  ```text
@@ -15,7 +20,7 @@ project/
15
20
  |-- Dockerfile
16
21
  |-- docker-compose.yml
17
22
  |-- .liftoff/
18
- | `-- governance/ # durable local handoff when enabled
23
+ | `-- governance/ # managed-core local handoff when enabled
19
24
  | |-- policy.md
20
25
  | |-- context.json
21
26
  | `-- README.md
@@ -34,6 +39,10 @@ project/
34
39
  | `-- azure/
35
40
  | `-- .terraform.lock.hcl
36
41
  |-- openspec/ or .specify/
42
+ |-- .github/skills/openspec-*/ and .github/prompts/opsx-* # OpenSpec + Copilot
43
+ |-- .claude/skills/openspec-*/ and .claude/commands/opsx/ # OpenSpec + Claude
44
+ |-- .github/workflows/copilot-setup-steps.yml # optional hosted agent
45
+ |-- .github/agents/openspec.agent.md # optional hosted agent
37
46
  |-- .github/prompts/liftoff-repository-governance.prompt.md
38
47
  | or .claude/commands/liftoff-repository-governance.md
39
48
  |-- frontend/ # only when selected
@@ -63,6 +72,9 @@ project/
63
72
  state configuration, and a remote-state example.
64
73
  - `openspec` is created for OpenSpec. `.specify` and `specs` are created for
65
74
  Spec Kit.
75
+ - OpenSpec projects receive all 12 pinned workflows as both skills and commands
76
+ for supported selected-agent surfaces. The two hosted Copilot agent files are
77
+ generated only after explicit opt-in.
66
78
 
67
79
  ### Conditional areas
68
80
 
@@ -72,9 +72,9 @@ liftoff update --check
72
72
  liftoff update
73
73
  ```
74
74
 
75
- Check mode previews the schema-v5 manifest and new named artifacts without
75
+ Check mode previews the schema-v6 manifest and new named core artifacts without
76
76
  writing. Plain update applies collision-free files; differing existing files
77
- remain conflicts unless individually reviewed with `--force`. An unrecorded
77
+ remain managed-core conflicts unless individually reviewed with `--force`. An unrecorded
78
78
  conflict remains outside Liftoff ownership and produces `handoff-partial`.
79
79
  After every conflict is removed or matches the current artifact, the next
80
80
  update records the full artifact set as `handoff-generated`.