@6reduk/workspace-pipeline 0.1.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 (157) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +78 -0
  3. package/docs/collaboration.md +59 -0
  4. package/docs/config-fields.md +65 -0
  5. package/docs/contracts.md +149 -0
  6. package/docs/doctor.md +165 -0
  7. package/docs/launch.md +50 -0
  8. package/docs/lifecycle-cli.md +141 -0
  9. package/docs/lifecycle.md +42 -0
  10. package/docs/migrations/unity.md +288 -0
  11. package/docs/native-provider-format.md +149 -0
  12. package/docs/provider-bundles.md +81 -0
  13. package/docs/provider-resources.md +37 -0
  14. package/docs/release.md +25 -0
  15. package/docs/remove.md +70 -0
  16. package/docs/repair.md +80 -0
  17. package/docs/repositories.md +209 -0
  18. package/docs/repository-manual-recovery.md +102 -0
  19. package/docs/repository-observations.md +29 -0
  20. package/docs/repository-recovery.md +204 -0
  21. package/docs/repository-retention.md +46 -0
  22. package/docs/repository-transport-budgets.md +26 -0
  23. package/docs/retention.md +237 -0
  24. package/docs/source.md +50 -0
  25. package/docs/switch.md +412 -0
  26. package/package.json +39 -0
  27. package/schemas/common.schema.json +251 -0
  28. package/schemas/inventory.schema.json +15 -0
  29. package/schemas/operation.schema.json +286 -0
  30. package/schemas/pipeline.schema.json +317 -0
  31. package/schemas/state.schema.json +302 -0
  32. package/schemas/workspace.schema.json +67 -0
  33. package/src/cli.js +7 -0
  34. package/src/commands/adopt.js +2 -0
  35. package/src/commands/bootstrap-recovery.js +90 -0
  36. package/src/commands/dispatch.js +394 -0
  37. package/src/commands/init.js +84 -0
  38. package/src/commands/launch.js +69 -0
  39. package/src/commands/migration-apply.js +53 -0
  40. package/src/commands/migration.js +50 -0
  41. package/src/commands/repositories.js +61 -0
  42. package/src/commands/repository-abandon.js +16 -0
  43. package/src/commands/repository-ancestors.js +21 -0
  44. package/src/commands/repository-locks.js +77 -0
  45. package/src/contracts/parse.js +57 -0
  46. package/src/contracts/semantic.js +240 -0
  47. package/src/contracts/validate.js +21 -0
  48. package/src/launch/grok.js +20 -0
  49. package/src/migrations/legacy-unity-begin.js +35 -0
  50. package/src/migrations/legacy-unity-compensate.js +82 -0
  51. package/src/migrations/legacy-unity-deactivate.js +60 -0
  52. package/src/migrations/legacy-unity-deactivation-resume-apply.js +62 -0
  53. package/src/migrations/legacy-unity-deactivation-resume.js +81 -0
  54. package/src/migrations/legacy-unity-finalize.js +88 -0
  55. package/src/migrations/legacy-unity-install-recovery.js +76 -0
  56. package/src/migrations/legacy-unity-install-resume.js +60 -0
  57. package/src/migrations/legacy-unity-install.js +88 -0
  58. package/src/migrations/legacy-unity-lease.js +136 -0
  59. package/src/migrations/legacy-unity-preflight.js +67 -0
  60. package/src/migrations/legacy-unity-preview.js +91 -0
  61. package/src/migrations/legacy-unity-resume-apply.js +39 -0
  62. package/src/migrations/legacy-unity-resume.js +41 -0
  63. package/src/migrations/legacy-unity-resumed-evidence.js +88 -0
  64. package/src/migrations/legacy-unity.js +99 -0
  65. package/src/operations/apply.js +576 -0
  66. package/src/operations/backup.js +94 -0
  67. package/src/operations/bootstrap-lock.js +87 -0
  68. package/src/operations/bootstrap-owner-retirement.js +121 -0
  69. package/src/operations/bundle-update.js +54 -0
  70. package/src/operations/config-fields.js +24 -0
  71. package/src/operations/continuation-lifecycle.js +77 -0
  72. package/src/operations/doctor.js +214 -0
  73. package/src/operations/history.js +170 -0
  74. package/src/operations/installer-identity.js +49 -0
  75. package/src/operations/journal.js +142 -0
  76. package/src/operations/lifecycle.js +133 -0
  77. package/src/operations/lineage-guard.js +20 -0
  78. package/src/operations/lock.js +109 -0
  79. package/src/operations/maintenance.js +62 -0
  80. package/src/operations/migration-pending.js +22 -0
  81. package/src/operations/ownership.js +122 -0
  82. package/src/operations/plan.js +278 -0
  83. package/src/operations/reconciliation.js +112 -0
  84. package/src/operations/recovery-lease.js +66 -0
  85. package/src/operations/remove.js +140 -0
  86. package/src/operations/repair.js +188 -0
  87. package/src/operations/repository-abandon.js +192 -0
  88. package/src/operations/repository-ancestors.js +158 -0
  89. package/src/operations/repository-apply.js +122 -0
  90. package/src/operations/repository-authorization.js +48 -0
  91. package/src/operations/repository-bootstrap-continuation.js +190 -0
  92. package/src/operations/repository-bootstrap-reconcile.js +106 -0
  93. package/src/operations/repository-bootstrap-recover.js +114 -0
  94. package/src/operations/repository-bootstrap.js +82 -0
  95. package/src/operations/repository-clone.js +63 -0
  96. package/src/operations/repository-history.js +108 -0
  97. package/src/operations/repository-inputs.js +41 -0
  98. package/src/operations/repository-journal.js +127 -0
  99. package/src/operations/repository-lock-reconcile.js +401 -0
  100. package/src/operations/repository-pending.js +29 -0
  101. package/src/operations/repository-reconcile.js +182 -0
  102. package/src/operations/repository-resumption-approvals.js +77 -0
  103. package/src/operations/repository-retention-apply.js +75 -0
  104. package/src/operations/repository-retention.js +137 -0
  105. package/src/operations/repository-workspace.js +78 -0
  106. package/src/operations/retention-apply.js +133 -0
  107. package/src/operations/retention-combined-scan.js +30 -0
  108. package/src/operations/retention-combined.js +41 -0
  109. package/src/operations/retention-policy.js +65 -0
  110. package/src/operations/retention-receipts.js +126 -0
  111. package/src/operations/retention-scan.js +86 -0
  112. package/src/operations/retention.js +56 -0
  113. package/src/operations/state.js +210 -0
  114. package/src/operations/switch-activate.js +64 -0
  115. package/src/operations/switch-backups.js +29 -0
  116. package/src/operations/switch-continuation-journal.js +94 -0
  117. package/src/operations/switch-continuation-pending.js +60 -0
  118. package/src/operations/switch-continuation-records.js +109 -0
  119. package/src/operations/switch-continuation-recovery.js +91 -0
  120. package/src/operations/switch-continuation-runtime.js +135 -0
  121. package/src/operations/switch-continuation-store.js +120 -0
  122. package/src/operations/switch-continuation.js +76 -0
  123. package/src/operations/switch-execute.js +68 -0
  124. package/src/operations/switch-inspect.js +45 -0
  125. package/src/operations/switch-journal-store.js +109 -0
  126. package/src/operations/switch-journal.js +71 -0
  127. package/src/operations/switch-lifecycle.js +72 -0
  128. package/src/operations/switch-pending.js +43 -0
  129. package/src/operations/switch-preflight.js +73 -0
  130. package/src/operations/switch-prepare.js +75 -0
  131. package/src/operations/switch-records.js +60 -0
  132. package/src/operations/switch-recovery-store.js +74 -0
  133. package/src/operations/switch.js +52 -0
  134. package/src/operations/toml-fields.js +133 -0
  135. package/src/providers/bundles.js +42 -0
  136. package/src/providers/common-entry.js +16 -0
  137. package/src/providers/grok.js +26 -0
  138. package/src/providers/interface.js +25 -0
  139. package/src/providers/kimi.js +26 -0
  140. package/src/providers/native.js +155 -0
  141. package/src/providers/registry.js +10 -0
  142. package/src/providers/shared.js +51 -0
  143. package/src/providers/source.js +30 -0
  144. package/src/source/git.js +303 -0
  145. package/src/source/inventory.js +87 -0
  146. package/src/source/repository-budget.js +18 -0
  147. package/src/source/snapshot.js +37 -0
  148. package/src/workspace/paths.js +54 -0
  149. package/src/workspace/profiles.js +8 -0
  150. package/src/workspace/repositories.js +57 -0
  151. package/src/workspace/repository-inventory.js +77 -0
  152. package/src/workspace/repository-observation.js +38 -0
  153. package/src/workspace/repository-preflight.js +129 -0
  154. package/src/workspace/repository-preview.js +196 -0
  155. package/src/workspace/repository-tree.js +57 -0
  156. package/src/workspace/reserved.js +11 -0
  157. package/src/workspace/resolve.js +53 -0
@@ -0,0 +1,81 @@
1
+ # Provider bundles (development)
2
+
3
+ A bundle installs a declared set of native configurations together. It does not
4
+ install the harnesses, log in, translate missing configurations or enable a
5
+ native plugin. The initial bundle entry format supports Claude/Grok with a single
6
+ full CLAUDE.md. The two harnesses keep separate skill, agent and MCP destinations.
7
+
8
+ ## Pipeline source
9
+
10
+ Declare components under the existing `providers` map, then name the delivered
11
+ set. Every listed member must have its own provider declaration:
12
+
13
+ ```yaml
14
+ bundles:
15
+ claude-grok:
16
+ providers: [claude, grok]
17
+ entry:
18
+ source: instructions/CLAUDE.md
19
+ target: CLAUDE.md
20
+ ```
21
+
22
+ Only Claude supplied? Use `[claude]`. Only Grok? Use `[grok]`. Both are valid.
23
+ There is no full/partial flag: doctor shows the exact supplied/installed set.
24
+ An absent provider is not configured merely because it can read CLAUDE.md.
25
+ No second GROK.md is generated. The bundle entry is required in either case.
26
+
27
+ The source entry is an inventory-bound UTF-8 workspace template. Existing
28
+ `{{documentation}}` and `{{repository.name}}` substitutions refer to the wrapper
29
+ layout. Its deployed Markdown links must be wrapper-relative, not source-folder
30
+ relative. Unknown substitutions fail. Full rules and provider-specific sections
31
+ are allowed; make those sections explicitly conditional on the current harness.
32
+ Skills retain their existing canonical snapshot-relative routing.
33
+
34
+ One bundle is supported initially because there is one allowed bundle entry
35
+ destination. Nested bundles, arbitrary destinations and unknown native renderers
36
+ are rejected. Source data cannot introduce executable CLI adapters. Composition
37
+ changes among supported providers do not require new package-specific CLI code.
38
+
39
+ ## Workspace selection
40
+
41
+ Select the bundle, not its individual members. For example, alongside Codex:
42
+
43
+ ```yaml
44
+ providers: [codex]
45
+ bundles: [claude-grok]
46
+ ```
47
+
48
+ The ordinary Git source and layout/profile fields are still required. A workspace
49
+ with only a bundle may omit `providers`. Setup/update use the usual saved preview
50
+ and explicit apply; the preview includes all supplied members and the entry.
51
+ It is not necessary to install both harness executables to configure the bundle.
52
+
53
+ ## Lifecycle
54
+
55
+ - Update adds or retires members according to the new verified source, with exact
56
+ target changes visible before approval. User-modified owned files block writes.
57
+ - Repair restores the installed snapshot and membership, not the latest source.
58
+ - Remove the bundle together. Member-only removal is refused with
59
+ `remove.bundle-required`, rather than silently deleting the other harness.
60
+ - Existing foreign files are not overwritten. Historical backups are retained
61
+ during a managed migration and restored when their owner is finally removed.
62
+ - Old source manifests without bundles retain standalone behavior. To migrate,
63
+ explicitly select the source's bundle and approve the resulting update preview.
64
+
65
+ Removal preview example (replace path/id):
66
+
67
+ ```powershell
68
+ workspace-pipeline remove --workspace "C:\Work\example" --bundles claude-grok
69
+ ```
70
+
71
+ Save the complete preview using the existing documented workflow, review it, then
72
+ apply with `--apply --preview <absolute-file>`. Apply accepts no changed selectors.
73
+ Preview files may contain private configuration bytes; keep them local.
74
+
75
+ ## Runtime is a separate check
76
+
77
+ Grok's observed loading of root CLAUDE.md is intentionally accommodated. Use the
78
+ [scoped launcher](launch.md) for the tested compatibility switches. Full native
79
+ entry behavior and suppression of duplicate agents/hooks/plugin MCP are still
80
+ not certified. Bundle installation is not a claim of full Claude compatibility,
81
+ runtime readiness or approval of a pipeline stage.
@@ -0,0 +1,37 @@
1
+ # Shared entry and local resources (S8)
2
+
3
+ The trusted shared adapter produces one wrapper `AGENTS.md` for all selected
4
+ providers. It does not write into code/documentation repositories or global
5
+ harness configuration. An existing foreign entry is still subject to normal
6
+ ownership/conflict checks; choosing a template is not permission to overwrite it.
7
+
8
+ `agentsDocument.mode: default` selects the small CLI entry. `mode: source` reads
9
+ the specified file exclusively from the verified Git snapshot. The workspace
10
+ selection overrides the pipeline default. The existing bounded substitutions
11
+ `{{documentation}}` and `{{repository.ID}}` resolve to wrapper-relative paths;
12
+ unknown substitutions fail. No expressions, includes or source code execute.
13
+
14
+ Both modes append the resolved repository/documentation/project-root map and
15
+ the installed resource location. Paths are relative to the wrapper. Pipeline
16
+ resources stay at `.pipeline/snapshots/<digest>/<resources>` in the already
17
+ verified local snapshot, not in a mutable global cache. A later source move or
18
+ network outage does not change this location. The digest is installation metadata,
19
+ not a workflow gate or a requirement to update project documentation versions.
20
+
21
+ Trusted adapter contexts now carry `snapshot` alongside pipeline/workspace/layout
22
+ and copied source bytes. Setup, locked preflight, switch and repair provide the
23
+ same binding. Adapters must not treat an arbitrary source path as a filesystem
24
+ grant. `sourceBytes`/`sourceText` have no filesystem fallback; resource routing
25
+ checks the snapshot path against its digest.
26
+
27
+ New deployments retain the resolved `agentsDocument` selection. Repair can thus
28
+ reproduce a custom entry even if the workspace manifest is unavailable. The field
29
+ is optional when reading earlier state; absent selection uses the package default,
30
+ and repair's existing hash comparison still rejects mismatched reconstruction.
31
+ Resources and old snapshots remain subject to the existing retention policy, not
32
+ implicit deletion when an entry is removed.
33
+
34
+ The public registry pairs this shared adapter with Codex/Claude renderers. Native
35
+ discovery, packaged lifecycle and independent review are separate S8 checks.
36
+ File/config checks do not certify model-visible instructions, trust,
37
+ MCP execution or semantic approval.
@@ -0,0 +1,25 @@
1
+ # Release procedure
2
+
3
+ This package is @6reduk/workspace-pipeline, separate from the legacy unity-sdd
4
+ installer. Node.js 22+ is required. No native plugin installation is used.
5
+
6
+ 1. Review the exact public source, bump package.json and package-lock.json
7
+ together, run targeted tests and the packed provider lifecycle.
8
+ 2. Commit/push the approved source. Dispatch release.yml on main. It runs the
9
+ full test suite and packed provider lifecycle, then uploads a tarball.
10
+ 3. First publication requires the maintainer's normal npm authentication/2FA.
11
+ Download the successful workflow's artifact; publish that exact tarball:
12
+ `npm publish <tarball> --access public --provenance=false`.
13
+ 4. Once the package exists, configure npm trusted publishing for GitHub repository
14
+ 6reduk/workspace-pipeline-cli, workflow release.yml, environment npm-release.
15
+ No npm token belongs in source. Set repository variable NPM_PUBLISH_ENABLED=true
16
+ only after trust is established. Subsequent explicit workflow dispatches can
17
+ publish through OIDC. Existing version bytes must match; never overwrite tags
18
+ or republish different bytes under the same version.
19
+ 5. Verify registry version/integrity against the uploaded tarball. A successful
20
+ build or uploaded artifact alone is not publication success.
21
+
22
+ Release workflow does not move a workspace, grant trust or upgrade installed
23
+ pipeline snapshots. Publish a pipeline's Git source separately, then use the
24
+ ordinary reviewed setup/update preview for each workspace. Kimi native behavior
25
+ remains deferred; scoped Grok launch and import-surface limits remain applicable.
package/docs/remove.md ADDED
@@ -0,0 +1,70 @@
1
+ # Removal preview and apply
2
+
3
+ The public CLI prepares removal without executing it:
4
+
5
+ ```text
6
+ workspace-pipeline remove --workspace <absolute-wrapper> [--providers codex] [--bundles claude-grok]
7
+ workspace-pipeline remove --workspace <absolute-wrapper> --apply --preview <absolute-json-file>
8
+ ```
9
+
10
+ Use installed bundle IDs, not necessarily the example `claude-grok`. Save the
11
+ preview privately, inspect it, then apply that exact preview without selectors.
12
+ Omit both selectors to remove all installed providers and bundles. Explicit
13
+ selection must be nonempty, unique and installed. A bundle member cannot be
14
+ selected independently: `remove.bundle-required` requires selecting its bundle.
15
+ The internal API is `prepareRemoval(workspace, registry, {providers, bundles})`.
16
+ See [bundle delivery](provider-bundles.md) and [CLI lifecycle](lifecycle-cli.md).
17
+
18
+ Shared AGENTS.md stays while any provider remains; shared CLAUDE.md stays while
19
+ Claude or Grok remains. Full removal has desired=null;
20
+ partial removal retains source/version/layout and the remaining ownership.
21
+
22
+ The installed snapshot is replayed through trusted adapters. Every managed value
23
+ must still match; missing or user-edited owned values block the whole preview.
24
+ No original Git lookup or latest-version selection occurs.
25
+
26
+ - Created owned files are proposed for deletion, never directories/repositories.
27
+ - Taken-over files are restored to exact original backup bytes.
28
+ - JSON fields are removed or restored individually; current foreign siblings stay.
29
+ - JSON containers are kept, even if empty. No guessed directory/file cleanup.
30
+ - Historical backup files and evidence are retained, not removal targets.
31
+
32
+ State, managed observations, snapshot replay and used backups are rechecked.
33
+ The envelope contains private before/output bytes and may contain secrets. Do not
34
+ publish it as a diagnostic. applySupported=true refers only to the internal
35
+ executor; fresh approval of the saved preview is required for public CLI apply.
36
+ `verifyRemovalApproval(lock, prepared, approval, registry)` requires a fresh exact
37
+ digest approval and a live lock, then reconstructs the whole preview from installed
38
+ state. Changed targets, foreign siblings, retained-provider files, backups or
39
+ prepared payload invalidate the preview. This is read-only preflight, not execution.
40
+
41
+ ## Internal execution
42
+
43
+ `applyRemoval(lock, prepared, approval, registry)` repeats installed replay under
44
+ the live lock. It preserves and verifies all original backup files, including
45
+ those belonging to retained providers. Exact file unlink is allowed only for
46
+ created managed files whose bytes still match immediately before deletion.
47
+ Directories, repositories, history and backups are never deleted. Portable Node
48
+ APIs cannot exclude hostile same-user races after the last filesystem check.
49
+
50
+ A new journal and recovery record precede pending state and target writes. Full
51
+ removal ends in `not-installed`, partial removal in `ready` with remaining/shared
52
+ ownership. `inspectRecovery` checks either result and interrupted deletion without
53
+ clearing pending state or inventing missing readbacks. Failures after unlink stay
54
+ uncertain even when the file is absent. Original journal outcomes are retained.
55
+
56
+ Internal continuation retains command remove and original backup/snapshot lineage.
57
+ An already absent target becomes `verify-absent` (both hashes null, no payload or
58
+ fields): a fresh readback, never a repeated unlink. Untouched files retain delete
59
+ or restore work. A new exact approval and journal are required; original outcomes
60
+ are preserved. Repeated interruptions use the bounded existing lineage mechanism.
61
+ `verify-absent` is a validated continuation readback, not general target-deletion
62
+ authority. It is also supported for the narrowly scoped retirement of an owned
63
+ member file when updating a still-selected bundle; see [bundle delivery](provider-bundles.md).
64
+
65
+ Doctor recognizes a
66
+ completed removal with retained history only after validating matching removal
67
+ evidence and current results; it reports not-installed, never ready. Public switch
68
+ routing is described in [CLI lifecycle](lifecycle-cli.md). These operations do
69
+ not certify live-provider behavior. An operational
70
+ version tag never requires document reapproval.
package/docs/repair.md ADDED
@@ -0,0 +1,80 @@
1
+ # Repair and reconciliation previews (S6 in progress)
2
+
3
+ Internal APIs only. No public repair command yet.
4
+
5
+ `inspectRepair(workspace, registry)` replays installed snapshot bytes through
6
+ trusted adapters and checks that generated owned values match recorded hashes.
7
+ Missing source Git/manifest does not trigger a fetch or latest-version lookup.
8
+ Changed adapter output is rejected. Current user edits remain conflicts.
9
+
10
+ `prepareRepairPreview(workspace, registry)` produces exact payloads for missing
11
+ owned files/fields, preserving foreign JSON siblings. Any conflict blocks ALL
12
+ targets in the preview. It does not silently take over changed files or approve
13
+ itself. Outputs can contain configuration secrets from preserved siblings: keep
14
+ this envelope local, never print it as diagnostic output or publish it.
15
+
16
+ `previewReconciliation(workspace, exactRecoveryPath)` binds the current state and
17
+ selected recovery/journal evidence. It preserves uncertain writes even where
18
+ current bytes equal desired bytes. It does not replay, roll back, clear pending
19
+ state or release an abandoned lock.
20
+
21
+ Inspection/preview results have applySupported=false, automaticActions=false,
22
+ runtime=not-run and require fresh approval. They are not executable envelopes.
23
+
24
+ `prepareRepairPlan(workspace, registry)` binds a native operation with command
25
+ `repair` to the exact current state, all owned dependencies and missing-target
26
+ payloads. Its `prepared-repair` envelope preserves the entire active deployment,
27
+ including version, identity, ownership and original backup lineage. It rejects
28
+ conflicts; it does not select a new source/version or manufacture an approval.
29
+ Absent JSON files use create with no field-edit operations; existing JSON files
30
+ use edit-fields with exact absent-field preconditions and preserved siblings.
31
+
32
+ `verifyRepairApproval(lock, prepared, approval, registry)` is read-only preflight:
33
+ it requires the fresh exact digest approval, verifies a live workspace lock and
34
+ rebuilds the complete plan from installed bytes. Changed state, payloads, foreign
35
+ siblings, unchanged managed dependencies or adapter output invalidate the plan.
36
+
37
+ `prepared-repair` now has applySupported=true for the internal `applyRepair`
38
+ entrypoint only; setup/update apply still rejects it. `applyRepair` replays under
39
+ lock, verifies existing backup lineage, and uses the shared journal/write/readback
40
+ transaction engine. It rechecks the fresh plan after recovery metadata is staged
41
+ and before pending state or provider targets are written. No Git source is needed.
42
+
43
+ `inspectRecovery` understands repair records, requires an unchanged deployment
44
+ and preserves uncertainty after interruption. This is inspection, not automatic
45
+ retry/rollback. Internal continuation execution is described below; public CLI
46
+ routing remains unimplemented. Doctor checks all matching records and explicitly distinguishes
47
+ owned JSON fields from foreign siblings in completed historical transactions;
48
+ exact-byte recovery inspection remains the default. Full regression still needs
49
+ checking before S6 completion. All envelopes with bytes remain private and potentially
50
+ secret-bearing.
51
+
52
+ `prepareContinuation(workspace, recoveryPath)` creates a separate
53
+ proposal for an exact pending transaction. It binds state, recovery bytes and the
54
+ journal head (sequence/hash). Desired targets require new `verify-readback` actions;
55
+ untouched targets get `write-desired` actions. Other bytes or invalid evidence
56
+ block the whole proposal. Unchanged dependencies and exact stored output bytes
57
+ are included. No old outcome is rewritten or presumed successful.
58
+
59
+ `verifyContinuationApproval` reobserves the proposal under a live caller-owned
60
+ lock and requires its fresh digest approval. Changes to journal head, state,
61
+ targets or payload invalidate it.
62
+
63
+ Internal `applyContinuation` executes that exact approval in a NEW transaction.
64
+ Already-desired targets receive a new journaled readback without file writes;
65
+ remaining writes use immediate before-hash checks. Existing backups are verified,
66
+ not replaced. Before activation, original recovery bytes/journal head and the
67
+ exact original target/payload/dependency relationship are rechecked. Historical
68
+ uncertainty is never rewritten as a successful original outcome.
69
+
70
+ Doctor/history validate completed continuation evidence and mark the exact old
71
+ entry as resolved by that continuation, preserving its original status and bytes.
72
+ Historical completion is distinct from activation/current configuration readiness.
73
+ Nested continuation (continuing a failed continuation) verifies the complete
74
+ ancestry iteratively, preserving every ancestor's bytes and approval. Repeated
75
+ paths are rejected as cycles. The maximum is 32 continuation links; preparing
76
+ another beyond that bound fails before execution and retains pending evidence.
77
+ History resolves all verified ancestors only through completed descendant evidence.
78
+ Public CLI routing,
79
+ compensation and abandoned-lock removal are not implemented. This is an internal
80
+ executor with applySupported=true, not a complete user-facing recovery workflow.
@@ -0,0 +1,209 @@
1
+ # Repository workspace commands
2
+
3
+ These commands prepare repository layout only. They do not install a pipeline,
4
+ start an LLM harness or MCP server, approve project trust, or modify Git remotes.
5
+ Provider configuration requires a separate `setup` plan. `wrap` is an alias for
6
+ `adopt`, not a destructive in-place conversion command.
7
+
8
+ ## Inputs and preview
9
+
10
+ Use absolute paths for command-line paths. A workspace manifest selects the Git
11
+ pipeline source, provider names, repository destinations and documentation owner.
12
+ See [contracts](contracts.md) for the manifest contract and [source](source.md)
13
+ for source acquisition. A separate JSON file makes each repository action explicit:
14
+
15
+ ```json
16
+ {"game":{"action":"move","from":"C:\\Projects\\ExistingGame"}}
17
+ ```
18
+
19
+ The key must match the manifest repository ID. Supported actions are `keep`,
20
+ `directory`, `init`, `clone`, and `move`; their validity depends on the observed
21
+ source/destination and manifest. `directory` creates an empty directory, not a
22
+ Git repository. `move` preserves the existing repository, including dirty and
23
+ untracked files, and does not change origin. Clone materializes the selected
24
+ commit, not uncommitted files of its source.
25
+
26
+ ```powershell
27
+ workspace-pipeline wrap --workspace "C:\Work\GameWorkspace" --manifest "C:\Work\workspace.json" --choices "C:\Work\choices.json"
28
+ ```
29
+
30
+ Save the exact JSON stdout as UTF-8 `preview.json` outside the affected repository
31
+ and wrapper. Read its operations and blockers. Preview may acquire a temporary
32
+ Git snapshot, but does not perform repository effects. Remote access is explicit
33
+ with `--network`; local Git does not need that flag. Do not put credentials into
34
+ source URLs or retained preview files.
35
+
36
+ ```powershell
37
+ workspace-pipeline wrap --workspace "C:\Work\GameWorkspace" --apply --preview "C:\Work\preview.json"
38
+ ```
39
+
40
+ Apply accepts only the saved preview, not fresh choices or a different manifest.
41
+ It rechecks exact inputs and observed filesystem state. A destination collision,
42
+ source drift or missing required prepared snapshot causes refusal, not overwrite.
43
+ Apply still resolves the manifest's source identity: an unavailable local Git
44
+ pipeline source is refused, even when its acquired snapshot is retained. Restore
45
+ that source before retrying. Recovery after recorded repository effects instead
46
+ uses retained operation inputs, independently of that source and user preview.
47
+ Repository clone inputs have their own retained bindings.
48
+
49
+ `init` uses the same preview/apply shape for a new layout; `adopt` for an existing
50
+ one. Inspect `--help` for the installed command surface. Do not treat successful
51
+ repository setup as proof that a provider is configured or usable.
52
+
53
+ ## Interruptions and recovery
54
+
55
+ Do not delete lock directories or replay the original apply blindly. Stdout and
56
+ stderr identify operation/journal paths. Retained inputs under
57
+ `.pipeline/repository-inputs/` let recovery work without the original user preview
58
+ or pipeline source. Preserve these records until recovery and retention checks.
59
+
60
+ ```powershell
61
+ workspace-pipeline repositories status --workspace "C:\Work\GameWorkspace"
62
+ workspace-pipeline repositories finalize --workspace "C:\Work\GameWorkspace"
63
+ workspace-pipeline repositories finalize --workspace "C:\Work\GameWorkspace" --apply --preview "C:\Work\finalize-preview.json"
64
+ ```
65
+
66
+ Each mutation requires its own current preview. `status` is read-only;
67
+ `no-pending-marker` means no pending marker, not comprehensive workspace health.
68
+ Uncertain effects are not silently turned into completed ones. Follow the exact
69
+ diagnostics and [recovery contract](repository-recovery.md).
70
+
71
+ If a stopped process retained operation locks, use the explicit journal UUID from
72
+ the operation record, never guess the newest directory:
73
+
74
+ ```powershell
75
+ workspace-pipeline repositories recover-locks --workspace "C:\Work\GameWorkspace" --journal "<UUID>"
76
+ workspace-pipeline repositories recover-locks --workspace "C:\Work\GameWorkspace" --journal "<UUID>" --apply --preview "C:\Work\locks-preview.json"
77
+ ```
78
+
79
+ This can retire attributable locks only after verifying owners, effects and
80
+ history. It does not authorize replaying uncertain operations. Bootstrap has
81
+ separate `recover-bootstrap`, `continue-bootstrap` and `retire-bootstrap` routes; use only a supported,
82
+ verified native preview. Live or unconfirmed owners, torn records and foreign
83
+ files must not be removed to force progress.
84
+
85
+ For the **first** recovery of wrapper creation, retain the original complete
86
+ `init`/`adopt` preview (or the native repository preview). This route needs no
87
+ pipeline-source access. It supports either a still-absent wrapper with its exact
88
+ intent, or an existing wrapper with a matching creation receipt; the recorded
89
+ local owner must have stopped. It archives the attributable bootstrap attempt,
90
+ not a replay of repository operations.
91
+
92
+ ```powershell
93
+ workspace-pipeline repositories recover-bootstrap --workspace "C:\Work\GameWorkspace" --bootstrap-preview "C:\Work\original-init-preview.json"
94
+ workspace-pipeline repositories recover-bootstrap --workspace "C:\Work\GameWorkspace" --apply --preview "C:\Work\fresh-bootstrap-recovery.json"
95
+ ```
96
+
97
+ Save the first command's full output as the fresh recovery preview for the second
98
+ command. The original bootstrap preview and fresh recovery approval are different
99
+ files. A stale preview is rejected. If this recovery itself is interrupted, use
100
+ `continue-bootstrap` against its retained request instead. Missing/torn original
101
+ records or a wrapper without a matching receipt remain blocked; do not fabricate
102
+ the original preview or clear a lock to proceed.
103
+
104
+ ## Missing parents and abandoning an uncertain attempt
105
+
106
+ Missing wrapper ancestors have a separate bounded plan. It creates approved
107
+ parents only, not the wrapper or repositories. Afterward prepare a fresh
108
+ `init`/`adopt` preview against the new filesystem state.
109
+
110
+ ```powershell
111
+ workspace-pipeline repositories prepare-parent --workspace "C:\Work\New\GameWorkspace"
112
+ workspace-pipeline repositories prepare-parent --workspace "C:\Work\New\GameWorkspace" --apply --preview "C:\Work\parent-preview.json"
113
+ ```
114
+
115
+ After interruption, preserve the original parent preview. Continuation preview
116
+ reads it with `--parent-preview`; apply takes the newly saved continuation envelope
117
+ with `--preview`. These files are different approvals and cannot be interchanged.
118
+
119
+ ```powershell
120
+ workspace-pipeline repositories continue-parent --workspace "C:\Work\New\GameWorkspace" --parent-preview "C:\Work\parent-preview.json"
121
+ workspace-pipeline repositories continue-parent --workspace "C:\Work\New\GameWorkspace" --apply --preview "C:\Work\parent-continuation.json"
122
+ ```
123
+
124
+ ### Nested repository destinations
125
+
126
+ Paths such as `repos/api` and `repos/documentation` remain valid manifest paths.
127
+ One-shot `init` deliberately refuses missing destination parents; it does not
128
+ silently widen repository approval into recursive directory creation. Use the
129
+ existing bounded parent-preparation route, then obtain a **fresh** `init` preview.
130
+
131
+ For a new `C:\Work\Services` wrapper, the following parent preview has
132
+ `C:\Work\Services\repos\api` as its **sentinel**, not as the actual pipeline
133
+ workspace. It proposes creating only the missing chain `Services`, `Services\repos`;
134
+ neither `api` nor `documentation` is created by this command. Review the returned
135
+ `targets`, `anchor`, and history location before saving and applying its JSON.
136
+
137
+ ```powershell
138
+ workspace-pipeline repositories prepare-parent --workspace "C:\Work\Services\repos\api"
139
+ workspace-pipeline repositories prepare-parent --workspace "C:\Work\Services\repos\api" --apply --preview "C:\Work\nested-parent-preview.json"
140
+ workspace-pipeline init --workspace "C:\Work\Services" --manifest "C:\Work\workspace.json" --choices "C:\Work\choices.json"
141
+ ```
142
+
143
+ Save the last command's new complete preview and apply it to `C:\Work\Services`
144
+ through the normal `init --apply --preview` route. Do not reuse an `init` preview
145
+ from before parent creation. Both sibling repositories can now be created by the
146
+ same repository plan. For separate missing branches, prepare each required chain
147
+ explicitly and inspect it separately. The manifest/schema/examples are unchanged.
148
+
149
+ This route also works for an **existing quiescent wrapper**: the parent preview
150
+ creates only missing descendants. Stop canonical-workspace CLI writers and agent
151
+ sessions first. The parent primitive's lease covers its first missing path, **not
152
+ the canonical workspace's writer locks**; it does not certify isolation against
153
+ an active `init`, provider mutation, or arbitrary editor in that workspace. Do
154
+ not run these operations concurrently. This is an explicit preparation route,
155
+ not an automatically guarded one-shot nested bootstrap.
156
+
157
+ Directory staging records exact per-directory identities before publication and
158
+ retains a projection and receipt. If interrupted, use `continue-parent` with the
159
+ same sentinel and original parent preview, then approve its fresh continuation.
160
+ Unknown/incomplete staging stays blocked for manual review; no blind `mkdir`,
161
+ recursive rollback, or automatic deletion is required or authorized. History
162
+ may live at an existing ancestor inside the eventual wrapper; preserve it.
163
+
164
+ If repository effects remain uncertain, explicit abandonment can retain the
165
+ failed attempt as history without certifying completion. It preserves partial
166
+ repository data; it is not rollback, cleanup, permission to delete data, or a
167
+ claim the original operation succeeded. Inspect the entire fresh observation
168
+ before applying, then reassess the preserved repositories in a new plan.
169
+
170
+ ```powershell
171
+ workspace-pipeline repositories abandon --workspace "C:\Work\GameWorkspace"
172
+ workspace-pipeline repositories abandon --workspace "C:\Work\GameWorkspace" --apply --preview "C:\Work\abandon-preview.json"
173
+ workspace-pipeline repositories continue-abandon --workspace "C:\Work\GameWorkspace" --attempt "<attempt UUID>"
174
+ workspace-pipeline repositories continue-abandon --workspace "C:\Work\GameWorkspace" --attempt "<attempt UUID>" --apply --preview "C:\Work\abandon-continuation.json"
175
+ ```
176
+
177
+ The attempt UUID must come from the actual abandonment record. Unknown owners,
178
+ changed subjects or unverifiable history still block these commands.
179
+
180
+ ## Corrected control records and recovery boundaries
181
+
182
+ Full file observations and compact saved records are described in
183
+ [repository observations](repository-observations.md). Separate user-repository
184
+ clone ceilings are listed in [transport budgets](repository-transport-budgets.md),
185
+ including their preview-visible pack/time limits; pipeline-package limits do not
186
+ serve as implicit game-repository limits.
187
+
188
+ Successful layout work reports `repositories-prepared` with
189
+ `pipelineActivated:false`; it is not harness or game readiness.
190
+ Abandonment refuses a finalizable completed operation: use the exact finalization
191
+ route instead. Interrupted abandonment approvals are retained sequentially as
192
+ `authorization-NNNN.json`, each bound to previous authorization hashes. Earlier
193
+ development histories using UUID approval names are not rewritten or silently
194
+ accepted under the new format; preserve them for manual inspection.
195
+ First lock recovery now archives the whole gate as `recovery-gate` in its history,
196
+ including the owner record, instead of deleting the gate in separate steps.
197
+
198
+ ## Packed regression details
199
+
200
+ `npm run test:packed` packs and installs the npm tarball offline into a unique
201
+ temporary directory. It verifies packaged files, runs the installed entrypoint,
202
+ and retains `report.json` plus fixtures at the printed location. The S7 portion
203
+ covers init, dirty/untracked wrap, destination collision, unavailable-source apply
204
+ refusal, source-independent finalization, uncertain-effect refusal and stopped-lock recovery.
205
+
206
+ Crash setup uses real exited children and native APIs **from the installed
207
+ tarball**, not a hidden public CLI fault flag; recovery uses the public installed
208
+ entrypoint. These are synthetic author tests, not independent review, real
209
+ provider/runtime validation or permission to migrate a user's workspace.
@@ -0,0 +1,102 @@
1
+ # Repository recovery when ownership or evidence is incomplete
2
+
3
+ This is the operator path for states that cannot safely enter a native recovery
4
+ writer. An error or an empty lock directory is not evidence that nobody owns the
5
+ operation. A missing result record is not evidence that a clone/move did not run.
6
+ Nothing in this document authorizes deleting a lock, editing a journal, inventing
7
+ an owner record, overwriting a repository, or converting an unknown result to PASS.
8
+
9
+ ## First: preserve and classify, without applying anything
10
+
11
+ 1. Record the exact absolute wrapper and the CLI error code. Keep the original
12
+ preview, operation UUID, reported journal/history locations and console output.
13
+ Do not select an operation by newest timestamp. These records may contain
14
+ private configuration: keep diagnostic copies local and access-restricted.
15
+ 2. Ask the people/process owners using that workspace to stop relevant installer,
16
+ recovery and repository-writing work through their normal controls. Do not
17
+ kill a PID merely because it appears in an old record: PIDs are reused. A
18
+ foreign hostname or inability to inspect a process leaves liveness unknown.
19
+ 3. Use the following read-only commands. A nonzero exit/error is useful evidence;
20
+ it does not mean the command repaired anything. Do not append `--apply`.
21
+
22
+ ```text
23
+ workspace-pipeline repositories status --workspace <absolute-wrapper>
24
+ workspace-pipeline logs list --workspace <absolute-wrapper>
25
+ ```
26
+
27
+ `repositories status` reads a pending operation and its retained inputs when
28
+ available; it reports persistent blockers. `no-pending-marker` does **not**
29
+ certify historical completion or absence of effects. `logs list` may report
30
+ inaccessible/incomplete records rather than parse them. Neither command repairs
31
+ missing records, retires locks or establishes unknown process ownership.
32
+ 4. Preserve original bytes in place. If an operator makes a diagnostic copy,
33
+ record source paths and hashes, distinguish a copy from the original, and do
34
+ not follow unknown links/reparse points. An inconsistent or changing copy is
35
+ not a stable before-state. Do not publish credentials or whole user configs.
36
+ 5. Compare with the cases below and select a matching preview-only route. A route
37
+ that rejects the state must not be bypassed by editing the record it rejected.
38
+
39
+ ## Cases and actual native boundaries
40
+
41
+ | Observed state | Supported next observation/action | Boundary |
42
+ | --- | --- | --- |
43
+ | Completed repository effects with intact retained input/journal and no ownership blocker | `repositories finalize --workspace <wrapper>` previews exact finalization | Its approved apply only records verified completion; it does not repeat clone/init/move |
44
+ | Completed evidenced effects but stopped, attributable locks remain | `repositories recover-locks --workspace <wrapper> --journal <uuid>` | Preview/apply checks exact journal, owner and effects; live/unknown owners remain blocked |
45
+ | Wrapper absent; bootstrap lock contains only a complete valid local owner record | `repositories retire-bootstrap --workspace <wrapper>` | Eligible only when that local owner is confirmed stopped; archives the lock, never certifies execution |
46
+ | Original bootstrap preview is intact; exact intent with absent wrapper, or matching wrapper creation receipt | `repositories recover-bootstrap --workspace <wrapper> --bootstrap-preview <original-preview.json>` | First recovery only, with a confirmed stopped local owner; creates a fresh recovery preview without source lookup or repository replay |
47
+ | Bootstrap recovery gate has a complete retained request and coherent original records | `repositories continue-bootstrap --workspace <wrapper>` | Continues only remaining attributable archival/receipt actions; fresh exact preview approval is required |
48
+ | Interrupted repeated paired-lock continuation with intact approval chain | `repositories recover-locks` for the same explicit journal | Requires a fresh observed-state preview; does not reuse an old approval as ownership |
49
+ | Pending repository operation with intact inputs, unchanged inventoried trees and attributable stopped locks, but effects not finalizable | `repositories abandon --workspace <wrapper>` | Explicitly preserves current source/destination trees and abandons the operation; does not call partial effects completed or undo them. New repository preview is required |
50
+ | Interrupted abandon with intact retained request and guard | `repositories continue-abandon --workspace <wrapper> --attempt <uuid>` | Preview binds the named attempt; apply does not infer a different attempt |
51
+ | Parent staging has a complete projection or was published before its receipt | `repositories continue-parent --workspace <wrapper> --parent-preview <original-preview.json>` | Fresh preview may finish the exact projection; foreign additions or identity drift reject continuation |
52
+ | Parent staging stopped before a complete projection, with no live-path publication | Preserve that attempt; a fresh `repositories prepare-parent` preview can choose a new staging history | The earlier staging remains untouched. This does not adopt unknown directories or delete remnants |
53
+ | Empty bootstrap lock; torn/invalid owner; wrong host or owner liveness unknown | Manual decision required; native owner retirement refuses | An empty record cannot prove a dead owner, even if no process is visible to this shell |
54
+ | Recovery gate without a complete request; torn continuation authorization; corrupted input/receipt | Manual decision required; native readers refuse missing/inconsistent bindings | Do not fill gaps using similar neighboring files or remembered chat text |
55
+ | Wrapper exists but there is no matching creation receipt, or clone/move effects conflict with retained evidence | Manual decision, or explicit abandon only if its independent eligibility checks pass | Compatible-looking files alone do not prove origin or successful completion |
56
+
57
+ For each eligible route, save its full preview privately as UTF-8, inspect the
58
+ exact operations and blockers, then separately approve the corresponding
59
+ `--apply --preview <file>` command. See [native recovery](repository-recovery.md).
60
+ Parent continuation retains each fresh approval as `authorization-NNNN.json`
61
+ inside its history before remaining actions. Each record binds the exact observed
62
+ state and preceding approval hashes; the chain admits at most 64 approvals.
63
+ A torn authorization is not rewritten. A completed readback appends nothing.
64
+ No route proves that unrelated harness sessions, Unity, Git helpers or other
65
+ machines have stopped. Local IPC exclusion is cooperative and not a distributed
66
+ or hostile-process safety boundary.
67
+
68
+ ## What an operator decision must establish
69
+
70
+ A manual decision is a bounded escalation, not a hidden retry loop. Provide:
71
+
72
+ - Exact affected wrapper, source/destination repositories, journal/attempt ID and
73
+ observed files; identities/hashes where the current observation supports them.
74
+ - Who established quiescence, on which host, and which process identities were
75
+ actually checked. Unknown ownership stays explicitly unknown.
76
+ - Original preview and independently retained request/receipt/backup, if they
77
+ exist. Identify their source and hashes. A user-supplied copy is evidence to
78
+ evaluate, not permission to replace a missing native record or proof of a
79
+ historical result. Human recollection can guide investigation, not manufacture
80
+ machine provenance.
81
+ - Intended disposition: preserve the present repositories and start a new plan,
82
+ or a specific separately reviewed reconciliation/compensation. Enumerate exact
83
+ paths and preservation requirements. No broad cleanup or implicit origin change.
84
+ - Remaining uncertainty and how the proposed action avoids touching files whose
85
+ ownership or before-state cannot be established.
86
+
87
+ There is intentionally no force/unlock recipe here. If native prerequisites cannot
88
+ be established, stop and review the exact situation with the workspace owner; an
89
+ explicit separately designed recovery may be necessary. A diagnostic report can
90
+ close the investigation step while the operation itself remains unresolved. Do
91
+ not represent that as successful recovery, installation readiness or S7 runtime
92
+ certification.
93
+
94
+ ## Why this is consistent with the execution contract
95
+
96
+ The execution contract requires reinspection, a fresh preview before continuing or
97
+ compensating, ownership-aware compensation, and owner/liveness review for abandoned
98
+ locks. It explicitly forbids blind deletion and recursive repository rollback.
99
+ It does not require the CLI to reconstruct absent proof or automatically repair
100
+ every corrupted record. Partial moves still need a documented disposition:
101
+ supported preserve-current-state abandonment is one such route when its bindings
102
+ remain intact; genuinely unbound cases retain an explicit operator decision.
@@ -0,0 +1,29 @@
1
+ # Repository observations and control-record size
2
+
3
+ Repository files (including ignored and untracked data) are fully inspected under
4
+ the repository bounds: 200000 entries, 100 GiB content and depth128. Full entry
5
+ lists are transient observations, not embedded into saved command previews or
6
+ per-operation evidence. The shared JSON/YAML control parser retains its 2 MiB and
7
+ 50000-node limits; these are not user-repository file limits.
8
+
9
+ Saved inventory summaries contain root identity, entry count, byte total, exact
10
+ identity-inventory digest and a separate rename-stable content/mode digest.
11
+ Committed-tree summaries contain commit, entry count, total bytes and tree digest.
12
+ Apply still rebuilds the whole observation from original trusted inputs and
13
+ compares the complete compact preview. After effects, native evidence records the
14
+ new exact summary; reconciliation rescans current trees and compares it. A digest
15
+ alone is neither an execution receipt nor authority to replay missing work.
16
+
17
+ Historical full-entry evidence remains readable for reconciliation/retention where
18
+ it fits the original parser bounds. Saved previews from the earlier development
19
+ format are not silently rewritten; take a fresh preview before a new operation.
20
+ Interrupted records that cannot be verified remain manual recovery cases.
21
+
22
+ Filesystem identity uses mtime/ctime, not atime. Concurrent changes may refuse a
23
+ preview even when an operator considers the content equivalent. Do not suppress
24
+ drift checks to force apply; stop writers and obtain a fresh observation.
25
+
26
+ Busy/access diagnostics are deliberately distinct: EBUSY is busy, EACCES/EPERM is
27
+ access-denied (permissions or sharing policy may be responsible). A read-only
28
+ preflight cannot guarantee that a later rename/open will be permitted. Such an
29
+ apply failure preserves pending uncertainty and never claims automatic rollback.