feat(shell-projection): centralize managed hook command policy (#3450)
* feat(shell-projection): route persistent PATH hints through projection seam * refactor(shell-projection): unify managed hook command policy * fix(install): guard malformed settings hooks during uninstall * chore(changeset): add fragment for pr 3450 * fix(install): guard malformed settings hook entries
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Shell Command Projection Module owns runtime-aware OS command rendering
|
||||
|
||||
- **Status:** Proposed
|
||||
- **Status:** Accepted
|
||||
- **Date:** 2026-05-12
|
||||
|
||||
We propose introducing a Shell Command Projection Module that owns projection from typed command intent to concrete shell/runtime-specific command text. GSD currently hand-builds hook commands, PATH repair commands, shim scripts, and other serialized OS-facing command strings across installer call sites. That drift has repeatedly produced cross-shell regressions (`#2376`, `#2979`, `#3002`, `#3011`, `#3181`, `#3393`, `#3413`). The proposed seam concentrates quoting, path-style, and runtime-wrapper policy in one module while keeping real subprocess execution on array-arg/non-shell paths.
|
||||
|
||||
102
docs/adr/0010-file-operation-engine-module.md
Normal file
102
docs/adr/0010-file-operation-engine-module.md
Normal file
@@ -0,0 +1,102 @@
|
||||
# File Operation Engine Module owns safe runtime/config file mutations
|
||||
|
||||
- **Status:** Proposed
|
||||
- **Date:** 2026-05-12
|
||||
|
||||
We propose introducing a File Operation Engine Module that owns policy for managed file reads, writes, deletes, locks, backups, and rollbacks across installer, migration, and planning surfaces. Today, file mutation behavior is duplicated across `bin/install.js`, `get-shit-done/bin/lib/installer-migrations.cjs`, and multiple planning modules, with drift in atomic-write guarantees, path safety checks, and ownership classification.
|
||||
|
||||
This ADR also captures where Shell Command Projection Module policy should be consumed or expanded for hook-command-specific file mutations, so shell command drift and file mutation drift do not evolve as separate bug classes.
|
||||
|
||||
## Decision
|
||||
|
||||
- Add a **File Operation Engine Module** under `get-shit-done/bin/lib/` as the single seam for file mutation safety policy.
|
||||
- Keep command-text projection in the Shell Command Projection Module (ADR-0009), but route projection-adjacent hook file mutations through shared managed-hook ownership policy.
|
||||
- Move file operation adapters to the new seam in two tracks:
|
||||
- **Track A (projection-adjacent):** runtime config hook-command detection/rewrite/delete paths consume shared managed-hook policy from the projection seam.
|
||||
- **Track B (solution-wide):** shared file operation engine owns atomic write, path containment, lock behavior, rollback bookkeeping, and best-effort cleanup policy.
|
||||
- Keep internal subprocess execution out of this seam (same boundary as ADR-0009): this is a file operation seam, not a command runner.
|
||||
|
||||
## Initial Scope
|
||||
|
||||
1. Unify managed-hook ownership classification used by install/uninstall/migration hook config rewrites.
|
||||
2. Unify atomic write behavior currently duplicated in installer/core/migration paths.
|
||||
3. Unify lock-file lifecycle policy used by planning workspace and installer migration journal flows.
|
||||
4. Expose typed file mutation plan IR for tests (`rewrite-json`, `rewrite-text` with format (`toml`/`markdown`/`plain`), `delete-file`, `backup-file`, `restore-file`, `ensure-dir`).
|
||||
|
||||
## Migration Inventory
|
||||
|
||||
### Projection-adjacent file mutation drift (Track A)
|
||||
|
||||
- `bin/install.js`
|
||||
- hook cleanup command detection (`isGsdHookCommand`)
|
||||
- stale Codex hook strip basenames (`STALE_HOOK_BASENAMES`)
|
||||
- settings/config hook entry prune/rewrite paths
|
||||
- `get-shit-done/bin/lib/installer-migrations/002-codex-legacy-hooks-json.cjs`
|
||||
- `isManagedCodexHookCommand` regex/path detection duplicated from installer-owned hook policy
|
||||
- `get-shit-done/bin/lib/shell-command-projection.cjs`
|
||||
- `isManagedHookBasename` already owns part of this policy and should become the canonical owner
|
||||
|
||||
### Solution-wide file operation drift (Track B)
|
||||
|
||||
- `bin/install.js`
|
||||
- local `atomicWriteFileSync` and temp cleanup registry
|
||||
- large inlined read/modify/write + backup/rollback logic for runtime config and hooks
|
||||
- `get-shit-done/bin/lib/core.cjs`
|
||||
- `atomicWriteFileSync` helper diverges in fallback behavior from installer/migration variants
|
||||
- `get-shit-done/bin/lib/installer-migrations.cjs`
|
||||
- separate `writeFileAtomicSync`, rollback journaling, lock handling, and containment checks
|
||||
- `get-shit-done/bin/lib/planning-workspace.cjs` and `get-shit-done/bin/lib/state.cjs`
|
||||
- duplicated lock-file create/release/remove patterns and best-effort cleanup semantics
|
||||
- `get-shit-done/bin/lib/roadmap.cjs`, `phase.cjs`, `milestone.cjs`, `frontmatter.cjs`, `drift.cjs`
|
||||
- direct read/modify/write flows with inconsistent atomicity and normalization policy application
|
||||
|
||||
## Interface sketch
|
||||
|
||||
The File Operation Engine Module should expose typed mutation planning and execution helpers:
|
||||
|
||||
```js
|
||||
planFileMutations({
|
||||
rootDir,
|
||||
operations: [
|
||||
{ type: 'rewrite-json', relPath, mutate },
|
||||
{ type: 'rewrite-text', relPath, mutate, format: 'toml' | 'markdown' | 'plain' },
|
||||
{ type: 'delete-file', relPath },
|
||||
{ type: 'ensure-dir', relPath },
|
||||
],
|
||||
ownership: { mode: 'managed-only' | 'allow-user', classifier },
|
||||
})
|
||||
```
|
||||
|
||||
```js
|
||||
applyFileMutationPlan({
|
||||
plan,
|
||||
atomic: true,
|
||||
rollback: true,
|
||||
lock: { scope: 'config' | 'planning', id: '...' },
|
||||
})
|
||||
```
|
||||
|
||||
For projection-adjacent paths, adapters should consume projection policy:
|
||||
|
||||
```js
|
||||
isManagedHookCommand(commandText, { surface, configDir })
|
||||
```
|
||||
|
||||
## Consequences
|
||||
|
||||
- File mutation safety policy becomes local to one module, reducing drift across installer/migration/planning paths.
|
||||
- Shell command projection and hook ownership classification stay aligned at one seam family.
|
||||
- Tests can assert typed mutation IR and reason codes instead of source-grep and duplicated predicate mirrors.
|
||||
- Initial migration is broad; sequencing should prioritize projection-adjacent hook config paths first, then converge atomic-write and lock semantics.
|
||||
|
||||
## Open questions
|
||||
|
||||
- Whether lock semantics should be one shared policy for installer + planning, or two adapters over one lock primitive.
|
||||
- Whether SDK query write paths should consume the same engine in the first pass or follow after CJS convergence.
|
||||
- Whether file mutation telemetry (per-op reason codes and rollback events) should be required for all engine adapters.
|
||||
|
||||
## References
|
||||
|
||||
- ADR-0008: `0008-installer-migration-module.md`
|
||||
- ADR-0009: `0009-shell-command-projection-module.md`
|
||||
- Related bug history: `#1755`, `#2866`, `#2979`, `#3002`, `#3017`, `#3439`
|
||||
@@ -16,7 +16,8 @@ Each ADR documents one architectural decision: what was decided, why, and what c
|
||||
| [0006-planning-path-projection-module.md](0006-planning-path-projection-module.md) | Planning Path Projection Module for SDK query handlers | Accepted |
|
||||
| [0007-sdk-package-seam-module.md](0007-sdk-package-seam-module.md) | SDK Package Seam Module owns SDK-to-get-shit-done-cc compatibility | Accepted |
|
||||
| [0008-installer-migration-module.md](0008-installer-migration-module.md) | Installer Migration Module owns install-time upgrade safety | Accepted |
|
||||
| [0009-shell-command-projection-module.md](0009-shell-command-projection-module.md) | Shell Command Projection Module owns runtime-aware OS command rendering | Proposed |
|
||||
| [0009-shell-command-projection-module.md](0009-shell-command-projection-module.md) | Shell Command Projection Module owns runtime-aware OS command rendering | Accepted |
|
||||
| [0010-file-operation-engine-module.md](0010-file-operation-engine-module.md) | File Operation Engine Module owns safe runtime/config file mutations | Proposed |
|
||||
|
||||
## Seam map
|
||||
|
||||
@@ -28,3 +29,7 @@ ADR 0008 documents the Installer Migration Module for safe install-time moves, r
|
||||
|
||||
ADR 0009 documents the Shell Command Projection Module seam for runtime-aware
|
||||
projection of installer-owned command text and projection IR.
|
||||
|
||||
ADR 0010 documents the File Operation Engine Module seam for converging
|
||||
installer/migration/planning file mutation safety policy, and its relationship
|
||||
to ADR 0009 hook-command ownership policy.
|
||||
|
||||
Reference in New Issue
Block a user