container-superposition 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -1370
- package/dist/scripts/init.js +350 -185
- package/dist/scripts/init.js.map +1 -1
- package/dist/tool/commands/adopt.d.ts +63 -0
- package/dist/tool/commands/adopt.d.ts.map +1 -0
- package/dist/tool/commands/adopt.js +1104 -0
- package/dist/tool/commands/adopt.js.map +1 -0
- package/dist/tool/commands/hash.d.ts +36 -0
- package/dist/tool/commands/hash.d.ts.map +1 -0
- package/dist/tool/commands/hash.js +242 -0
- package/dist/tool/commands/hash.js.map +1 -0
- package/dist/tool/commands/plan.d.ts +2 -0
- package/dist/tool/commands/plan.d.ts.map +1 -1
- package/dist/tool/commands/plan.js +262 -42
- package/dist/tool/commands/plan.js.map +1 -1
- package/dist/tool/schema/project-config.d.ts +17 -0
- package/dist/tool/schema/project-config.d.ts.map +1 -0
- package/dist/tool/schema/project-config.js +441 -0
- package/dist/tool/schema/project-config.js.map +1 -0
- package/dist/tool/schema/types.d.ts +39 -1
- package/dist/tool/schema/types.d.ts.map +1 -1
- package/dist/tool/utils/backup.d.ts +23 -0
- package/dist/tool/utils/backup.d.ts.map +1 -0
- package/dist/tool/utils/backup.js +123 -0
- package/dist/tool/utils/backup.js.map +1 -0
- package/docs/README.md +12 -2
- package/docs/adopt.md +202 -0
- package/docs/custom-patches.md +1 -1
- package/docs/discovery-commands.md +55 -3
- package/docs/examples.md +40 -6
- package/docs/filesystem-contract.md +58 -0
- package/docs/hash.md +183 -0
- package/docs/minimal-and-editor.md +1 -1
- package/docs/overlays.md +70 -0
- package/docs/presets-architecture.md +1 -1
- package/docs/presets.md +1 -1
- package/docs/publishing.md +36 -23
- package/docs/security.md +43 -0
- package/docs/specs/001-verbose-plan-graph/checklists/requirements.md +36 -0
- package/docs/specs/001-verbose-plan-graph/contracts/plan-verbose-output.md +96 -0
- package/docs/specs/001-verbose-plan-graph/data-model.md +111 -0
- package/docs/specs/001-verbose-plan-graph/plan.md +127 -0
- package/docs/specs/001-verbose-plan-graph/quickstart.md +106 -0
- package/docs/specs/001-verbose-plan-graph/research.md +100 -0
- package/docs/specs/001-verbose-plan-graph/spec.md +128 -0
- package/docs/specs/001-verbose-plan-graph/tasks.md +223 -0
- package/docs/specs/002-superposition-config-file/checklists/requirements.md +36 -0
- package/docs/specs/002-superposition-config-file/contracts/init-project-config.md +98 -0
- package/docs/specs/002-superposition-config-file/data-model.md +126 -0
- package/docs/specs/002-superposition-config-file/plan.md +213 -0
- package/docs/specs/002-superposition-config-file/quickstart.md +140 -0
- package/docs/specs/002-superposition-config-file/research.md +144 -0
- package/docs/specs/002-superposition-config-file/spec.md +136 -0
- package/docs/specs/002-superposition-config-file/tasks.md +215 -0
- package/docs/team-workflow.md +33 -1
- package/docs/workflows.md +139 -0
- package/features/cross-distro-packages/README.md +18 -0
- package/features/cross-distro-packages/devcontainer-feature.json +3 -3
- package/features/cross-distro-packages/install.sh +49 -7
- package/overlays/.presets/sdd.yml +84 -0
- package/overlays/README.md +7 -1
- package/overlays/amp/README.md +70 -0
- package/overlays/amp/devcontainer.patch.json +3 -0
- package/overlays/amp/overlay.yml +15 -0
- package/overlays/amp/setup.sh +21 -0
- package/overlays/amp/verify.sh +21 -0
- package/overlays/claude-code/README.md +83 -0
- package/overlays/claude-code/devcontainer.patch.json +3 -0
- package/overlays/claude-code/overlay.yml +15 -0
- package/overlays/claude-code/setup.sh +21 -0
- package/overlays/claude-code/verify.sh +21 -0
- package/overlays/gemini-cli/README.md +77 -0
- package/overlays/gemini-cli/devcontainer.patch.json +3 -0
- package/overlays/gemini-cli/overlay.yml +15 -0
- package/overlays/gemini-cli/setup.sh +21 -0
- package/overlays/gemini-cli/verify.sh +21 -0
- package/overlays/opencode/README.md +76 -0
- package/overlays/opencode/devcontainer.patch.json +3 -0
- package/overlays/opencode/overlay.yml +14 -0
- package/overlays/opencode/setup.sh +21 -0
- package/overlays/opencode/verify.sh +21 -0
- package/overlays/pandoc/README.md +279 -0
- package/overlays/pandoc/devcontainer.patch.json +14 -0
- package/overlays/pandoc/overlay.yml +19 -0
- package/overlays/pandoc/setup.sh +94 -0
- package/overlays/pandoc/verify.sh +13 -0
- package/overlays/spec-kit/README.md +181 -0
- package/overlays/spec-kit/devcontainer.patch.json +6 -0
- package/overlays/spec-kit/overlay.yml +19 -0
- package/overlays/spec-kit/setup.sh +45 -0
- package/overlays/spec-kit/verify.sh +33 -0
- package/overlays/windsurf-cli/README.md +69 -0
- package/overlays/windsurf-cli/devcontainer.patch.json +3 -0
- package/overlays/windsurf-cli/overlay.yml +15 -0
- package/overlays/windsurf-cli/setup.sh +21 -0
- package/overlays/windsurf-cli/verify.sh +21 -0
- package/package.json +1 -1
- package/tool/schema/config.schema.json +138 -9
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Data Model: Verbose Plan Graph
|
|
2
|
+
|
|
3
|
+
## Entity: PlanRequest
|
|
4
|
+
|
|
5
|
+
**Purpose**: Describes a single `plan` invocation and the presentation options that shape the response.
|
|
6
|
+
|
|
7
|
+
**Fields**:
|
|
8
|
+
|
|
9
|
+
- `stack`: requested base template type
|
|
10
|
+
- `selectedOverlayIds`: user-provided overlay IDs after trimming and de-duplication
|
|
11
|
+
- `manifestPath`: optional path to an existing `superposition.json` manifest
|
|
12
|
+
- `manifestOverlayIds`: overlays loaded from a manifest when manifest-driven planning is used
|
|
13
|
+
- `portOffset`: optional numeric port offset
|
|
14
|
+
- `jsonRequested`: whether structured output is requested
|
|
15
|
+
- `diffRequested`: whether diff mode is requested
|
|
16
|
+
- `verboseRequested`: whether dependency narration is requested
|
|
17
|
+
- `outputPath`: optional comparison target for diff mode
|
|
18
|
+
|
|
19
|
+
**Validation rules**:
|
|
20
|
+
|
|
21
|
+
- `stack` must be present and valid for the command
|
|
22
|
+
- `selectedOverlayIds` must contain only known overlay IDs
|
|
23
|
+
- duplicate overlay IDs are normalized before planning
|
|
24
|
+
- manifest-driven requests must resolve to a valid manifest before explanation data is generated
|
|
25
|
+
- `verboseRequested` must not change resolution behavior, only presentation and additional metadata
|
|
26
|
+
|
|
27
|
+
## Entity: IncludedOverlay
|
|
28
|
+
|
|
29
|
+
**Purpose**: Represents one overlay that appears in the resolved final plan.
|
|
30
|
+
|
|
31
|
+
**Fields**:
|
|
32
|
+
|
|
33
|
+
- `id`: stable overlay identifier
|
|
34
|
+
- `displayName`: human-readable overlay name if available
|
|
35
|
+
- `selectionKind`: `direct` or `dependency` based on how the overlay first entered the resolved set
|
|
36
|
+
- `selectionSource`: `command-line`, `manifest`, or `dependency`
|
|
37
|
+
- `reasons`: one or more inclusion reasons attached to this overlay
|
|
38
|
+
- `dependencyPaths`: one or more ordered paths from a direct selection to this overlay
|
|
39
|
+
- `compatibleWithStack`: whether the overlay remains in the final stack-specific plan
|
|
40
|
+
|
|
41
|
+
**Validation rules**:
|
|
42
|
+
|
|
43
|
+
- each included overlay appears only once in the final resolved set
|
|
44
|
+
- `reasons` must contain at least one entry
|
|
45
|
+
- `dependencyPaths` may have multiple entries when multiple parents lead to the same overlay
|
|
46
|
+
- if `selectionKind` is `direct`, at least one reason must identify the user request as the source
|
|
47
|
+
- if `selectionSource` is `manifest`, at least one reason must identify the manifest-defined root set as the source
|
|
48
|
+
|
|
49
|
+
## Entity: InclusionReason
|
|
50
|
+
|
|
51
|
+
**Purpose**: Explains why a single overlay was kept in the plan.
|
|
52
|
+
|
|
53
|
+
**Fields**:
|
|
54
|
+
|
|
55
|
+
- `kind`: `selected`, `required`, `transitive`, or `skipped`
|
|
56
|
+
- `origin`: `command-line` or `manifest`
|
|
57
|
+
- `sourceOverlayId`: the overlay that directly caused this reason, if applicable
|
|
58
|
+
- `rootOverlayId`: the original user-selected overlay at the start of the path
|
|
59
|
+
- `message`: user-facing explanation text
|
|
60
|
+
- `depth`: number of dependency edges between the root selection and the included overlay
|
|
61
|
+
|
|
62
|
+
**Validation rules**:
|
|
63
|
+
|
|
64
|
+
- direct selections use `kind: selected` and `depth: 0`
|
|
65
|
+
- manifest-defined root overlays also use `kind: selected` and `depth: 0`
|
|
66
|
+
- dependency-driven inclusions must include `sourceOverlayId`
|
|
67
|
+
- transitive reasons must include both `sourceOverlayId` and `rootOverlayId`
|
|
68
|
+
- failure or skip reasons must remain attached to the affected overlay or attempted overlay so users can identify the boundary condition
|
|
69
|
+
|
|
70
|
+
## Entity: DependencyPath
|
|
71
|
+
|
|
72
|
+
**Purpose**: Captures the ordered chain from a requested overlay to an included dependency.
|
|
73
|
+
|
|
74
|
+
**Fields**:
|
|
75
|
+
|
|
76
|
+
- `rootOverlayId`: directly selected starting overlay
|
|
77
|
+
- `segments`: ordered overlay IDs showing the path from root to final overlay
|
|
78
|
+
- `finalOverlayId`: included overlay reached by the path
|
|
79
|
+
|
|
80
|
+
**Validation rules**:
|
|
81
|
+
|
|
82
|
+
- `segments[0]` must match `rootOverlayId`
|
|
83
|
+
- `segments[segments.length - 1]` must match `finalOverlayId`
|
|
84
|
+
- repeated paths for the same overlay should be de-duplicated before output
|
|
85
|
+
|
|
86
|
+
## Entity: VerbosePlanOutput
|
|
87
|
+
|
|
88
|
+
**Purpose**: Extends the standard plan result with explanation data when verbose mode is requested.
|
|
89
|
+
|
|
90
|
+
**Fields**:
|
|
91
|
+
|
|
92
|
+
- `standardPlan`: the existing plan summary data
|
|
93
|
+
- `includedOverlays`: ordered list of `IncludedOverlay` records for human and JSON rendering
|
|
94
|
+
- `resolutionSummary`: concise summary of how many overlays were selected directly vs added automatically
|
|
95
|
+
- `failureContext`: optional description of the point where planning stopped or skipped overlays
|
|
96
|
+
- `inputMode`: `overlay-list` or `manifest`
|
|
97
|
+
|
|
98
|
+
**Relationships**:
|
|
99
|
+
|
|
100
|
+
- one `PlanRequest` produces one `VerbosePlanOutput`
|
|
101
|
+
- one `PlanRequest` may be sourced from explicit overlay flags or a manifest
|
|
102
|
+
- one `VerbosePlanOutput` contains many `IncludedOverlay` records
|
|
103
|
+
- one `IncludedOverlay` contains many `InclusionReason` records and zero or more `DependencyPath` records
|
|
104
|
+
|
|
105
|
+
## State Notes
|
|
106
|
+
|
|
107
|
+
- Resolution begins with the user-selected overlays.
|
|
108
|
+
- Resolution begins with either the user-selected overlays or the manifest-defined overlay roots.
|
|
109
|
+
- Dependencies are added recursively as required relationships are traversed.
|
|
110
|
+
- Stack compatibility filtering may remove overlays from the final renderable set after dependency discovery.
|
|
111
|
+
- Conflict detection runs against the resolved compatible set and may attach failure context to the verbose result.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Implementation Plan: Verbose Plan Graph
|
|
2
|
+
|
|
3
|
+
**Branch**: `001-verbose-plan-graph` | **Date**: 2026-03-10 | **Spec**: [spec.md](spec.md)
|
|
4
|
+
**Input**: Feature specification from `/docs/specs/001-verbose-plan-graph/spec.md`
|
|
5
|
+
|
|
6
|
+
## Summary
|
|
7
|
+
|
|
8
|
+
Extend the `plan` command so `--verbose` explains dependency resolution for both direct overlay selection and manifest-driven planning from an existing `superposition.json`. The design must keep one shared resolution and explanation model so text output, JSON output, and manifest-based workflows stay consistent.
|
|
9
|
+
|
|
10
|
+
## Technical Context
|
|
11
|
+
|
|
12
|
+
**Language/Version**: TypeScript 5.3.3 on Node.js 20+
|
|
13
|
+
**Primary Dependencies**: Commander, chalk, boxen, js-yaml, ora, Inquirer
|
|
14
|
+
**Storage**: Filesystem-based overlay manifests, project `superposition.json` manifests, templates, and generated devcontainer artifacts
|
|
15
|
+
**Testing**: Vitest unit and command tests, shell-based smoke tests, TypeScript compile checks
|
|
16
|
+
**Target Platform**: Node.js CLI on Linux, macOS, and Windows developer environments
|
|
17
|
+
**Project Type**: CLI scaffolding tool
|
|
18
|
+
**Performance Goals**: Preserve the current fast interactive feel of the `plan` command for typical overlay selections and avoid introducing noticeable delay when verbose explanation is enabled
|
|
19
|
+
**Constraints**: Preserve current concise output unless `--verbose` is requested; preserve source/dist path compatibility patterns; keep manifest-driven and overlay-list-driven planning aligned to one resolved overlay set; keep JSON and text views consistent
|
|
20
|
+
**Scale/Scope**: Single command enhancement affecting `scripts/init.ts`, `tool/commands/plan.ts`, command tests, user-facing docs, and manifest-driven planning behavior
|
|
21
|
+
|
|
22
|
+
## Constitution Check
|
|
23
|
+
|
|
24
|
+
_GATE: Must pass before Phase 0 research. Re-check after Phase 1 design and before implementation._
|
|
25
|
+
|
|
26
|
+
- [x] Spec exists at `docs/specs/001-verbose-plan-graph/spec.md`.
|
|
27
|
+
- [x] Spec is committed and reviewed before implementation tasks or code begin.
|
|
28
|
+
- [x] Plan scope, compatibility impact, and complexity notes match the approved spec.
|
|
29
|
+
- [x] Verification scope covers tests, smoke checks, and documentation updates needed for the change.
|
|
30
|
+
- [x] User-visible changes include documentation updates and an `[Unreleased]` `CHANGELOG.md` entry.
|
|
31
|
+
|
|
32
|
+
## Project Structure
|
|
33
|
+
|
|
34
|
+
### Documentation (this feature)
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
docs/specs/001-verbose-plan-graph/
|
|
38
|
+
├── plan.md
|
|
39
|
+
├── research.md
|
|
40
|
+
├── data-model.md
|
|
41
|
+
├── quickstart.md
|
|
42
|
+
├── contracts/
|
|
43
|
+
│ └── plan-verbose-output.md
|
|
44
|
+
└── tasks.md
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Source Code (repository root)
|
|
48
|
+
|
|
49
|
+
```text
|
|
50
|
+
scripts/
|
|
51
|
+
└── init.ts
|
|
52
|
+
|
|
53
|
+
tool/
|
|
54
|
+
├── commands/
|
|
55
|
+
│ └── plan.ts
|
|
56
|
+
├── __tests__/
|
|
57
|
+
│ └── commands.test.ts
|
|
58
|
+
├── schema/
|
|
59
|
+
└── utils/
|
|
60
|
+
|
|
61
|
+
docs/
|
|
62
|
+
├── discovery-commands.md
|
|
63
|
+
└── specs/
|
|
64
|
+
|
|
65
|
+
README.md
|
|
66
|
+
CHANGELOG.md
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Structure Decision**: Keep the existing CLI structure centered on `scripts/init.ts` for command options and manifest-loading hooks, and `tool/commands/plan.ts` for shared planning logic. Keep verification concentrated in `tool/__tests__/commands.test.ts`, with documentation updates in `README.md` and `docs/discovery-commands.md`.
|
|
70
|
+
|
|
71
|
+
## Phase 0: Research
|
|
72
|
+
|
|
73
|
+
### Research Goals
|
|
74
|
+
|
|
75
|
+
- Confirm the simplest way to reuse the verbose explanation model for manifest-driven planning.
|
|
76
|
+
- Decide how manifest-loaded overlays should appear in explanation data relative to directly requested overlays.
|
|
77
|
+
- Confirm failure behavior for missing or invalid manifests in verbose mode.
|
|
78
|
+
|
|
79
|
+
### Research Outputs
|
|
80
|
+
|
|
81
|
+
- [research.md](research.md)
|
|
82
|
+
|
|
83
|
+
## Phase 1: Design
|
|
84
|
+
|
|
85
|
+
### Data Model
|
|
86
|
+
|
|
87
|
+
- [data-model.md](data-model.md)
|
|
88
|
+
|
|
89
|
+
### Contracts
|
|
90
|
+
|
|
91
|
+
- [plan-verbose-output.md](contracts/plan-verbose-output.md)
|
|
92
|
+
|
|
93
|
+
### Quickstart
|
|
94
|
+
|
|
95
|
+
- [quickstart.md](quickstart.md)
|
|
96
|
+
|
|
97
|
+
## Implementation Approach
|
|
98
|
+
|
|
99
|
+
1. Extend `plan` input handling so it can build the same verbose explanation model whether overlays come from explicit flags or an existing manifest.
|
|
100
|
+
2. Reuse one dependency-resolution and explanation path inside `tool/commands/plan.ts` for concise, verbose, JSON, and manifest-driven planning.
|
|
101
|
+
3. Define manifest-aware explanation semantics so manifest-defined overlays remain distinguishable from auto-added dependencies without inventing a separate output format.
|
|
102
|
+
4. Add regression tests for manifest-driven verbose text output, verbose JSON output, and manifest failure paths.
|
|
103
|
+
5. Update README, discovery docs, quickstart guidance, and changelog entries to document manifest-driven verbose planning.
|
|
104
|
+
|
|
105
|
+
## Verification Strategy
|
|
106
|
+
|
|
107
|
+
- Add or update command tests in `tool/__tests__/commands.test.ts` for:
|
|
108
|
+
- verbose text output from direct overlay selection
|
|
109
|
+
- verbose text output from an existing manifest
|
|
110
|
+
- verbose JSON output from an existing manifest
|
|
111
|
+
- manifest failure behavior when the manifest is missing, invalid, or contains invalid overlays
|
|
112
|
+
- non-verbose output remaining unchanged
|
|
113
|
+
- Run `npm test` for automated coverage.
|
|
114
|
+
- Run `npm run lint` to verify TypeScript and formatting constraints.
|
|
115
|
+
- Perform targeted manual validation using the commands documented in `quickstart.md`, including manifest-driven scenarios.
|
|
116
|
+
|
|
117
|
+
## Post-Design Constitution Check
|
|
118
|
+
|
|
119
|
+
- [x] Design still preserves spec-first workflow and traces directly to the approved spec.
|
|
120
|
+
- [x] The planned change preserves overlay contract integrity by extending the existing planning model rather than creating a parallel manifest-only explanation path.
|
|
121
|
+
- [x] Verification remains proportional to risk: command tests plus documentation updates are planned before merge.
|
|
122
|
+
- [x] Documentation synchronization is explicitly included: `README.md`, `docs/discovery-commands.md`, `quickstart.md`, and `CHANGELOG.md`.
|
|
123
|
+
- [x] Simplicity and compatibility remain intact: verbose mode stays opt-in and manifest-driven planning uses the same reasoning model as direct selection.
|
|
124
|
+
|
|
125
|
+
## Complexity Tracking
|
|
126
|
+
|
|
127
|
+
No constitution violations require a design exception.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Quickstart: Verbose Plan Graph
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Validate that the `plan` command can explain dependency inclusion reasons for both direct overlay selection and existing manifest workflows without changing its default concise behavior.
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
- Repository dependencies installed
|
|
10
|
+
- Working tree on branch `001-verbose-plan-graph`
|
|
11
|
+
|
|
12
|
+
## Validation Steps
|
|
13
|
+
|
|
14
|
+
1. Run the existing concise plan and confirm no narration appears:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm run init -- plan --stack compose --overlays grafana
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Expected result:
|
|
21
|
+
|
|
22
|
+
- Standard plan summary appears
|
|
23
|
+
- `Auto-Added Dependencies` includes `prometheus`
|
|
24
|
+
- No dependency narration section is shown
|
|
25
|
+
|
|
26
|
+
2. Run the verbose text plan for a direct dependency:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm run init -- plan --stack compose --overlays grafana --verbose
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Expected result:
|
|
33
|
+
|
|
34
|
+
- Standard summary still appears
|
|
35
|
+
- A dependency narration section explains:
|
|
36
|
+
- `grafana` was selected directly
|
|
37
|
+
- `prometheus` was included because `grafana` requires it
|
|
38
|
+
|
|
39
|
+
3. Run the verbose JSON plan and inspect explanation data:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm run init -- plan --stack compose --overlays grafana --json --verbose
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Expected result:
|
|
46
|
+
|
|
47
|
+
- JSON remains valid
|
|
48
|
+
- Standard plan fields are still present
|
|
49
|
+
- Structured explanation data identifies direct vs dependency-driven inclusions
|
|
50
|
+
|
|
51
|
+
4. Run the verbose plan from an existing manifest:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npm run init -- --from-manifest .devcontainer/superposition.json --no-interactive
|
|
55
|
+
npm run init -- plan --from-manifest .devcontainer/superposition.json --verbose
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Expected result:
|
|
59
|
+
|
|
60
|
+
- The plan loads overlays from the manifest without re-entering them manually
|
|
61
|
+
- The verbose explanation treats manifest-defined overlays as the explicit root set
|
|
62
|
+
- Auto-added dependencies are still explained separately from manifest-defined overlays
|
|
63
|
+
|
|
64
|
+
5. Run the automated regression suite:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
npm test
|
|
68
|
+
npm run lint
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Expected result:
|
|
72
|
+
|
|
73
|
+
- Updated command tests pass
|
|
74
|
+
- TypeScript and formatting checks pass
|
|
75
|
+
|
|
76
|
+
## Manual Edge Checks
|
|
77
|
+
|
|
78
|
+
- Multi-parent dependency case: choose overlays that share a required dependency and confirm the dependency appears once with multiple reasons.
|
|
79
|
+
- Stack-incompatible case: run a compose-only overlay against `--stack plain` with `--verbose` and confirm the skip reason and dependency path are shown.
|
|
80
|
+
- Manifest case: run a verbose plan from an existing `superposition.json` and confirm the explanation covers both manifest-defined overlays and auto-added dependencies.
|
|
81
|
+
- Conflict case: run a known conflicting pair with `--verbose` and confirm the failure context explains why the command cannot proceed.
|
|
82
|
+
|
|
83
|
+
## Validation Log
|
|
84
|
+
|
|
85
|
+
Validated on 2026-03-10:
|
|
86
|
+
|
|
87
|
+
- `npm run init -- plan --stack compose --overlays grafana`
|
|
88
|
+
- Confirmed the concise plan output remains unchanged and still auto-adds `prometheus`
|
|
89
|
+
- `npm run init -- plan --stack compose --overlays grafana --verbose`
|
|
90
|
+
- Confirmed verbose output adds a `Dependency Resolution` section with direct-selection and required-dependency reasons
|
|
91
|
+
- `npm run init -- plan --stack compose --overlays grafana --json --verbose`
|
|
92
|
+
- Confirmed JSON output remains valid and adds a `verbose` object with inclusion reasons and summary counts
|
|
93
|
+
- `npm run init -- plan --from-manifest .devcontainer/superposition.json --verbose`
|
|
94
|
+
- Confirmed manifest-driven verbose output treats manifest overlays as the root set and still explains manifest-triggered dependencies like `codex -> nodejs`
|
|
95
|
+
- `npm run init -- plan --from-manifest .devcontainer/superposition.json --json --verbose`
|
|
96
|
+
- Confirmed JSON output records `inputMode: "manifest"` and marks manifest-defined overlays with `selectionSource: "manifest"`
|
|
97
|
+
- `npm run init -- plan --stack compose --overlays docker-in-docker,docker-sock --verbose`
|
|
98
|
+
- Confirmed verbose output adds `Resolution Notes` for the conflict boundary before the command exits with the existing conflict failure
|
|
99
|
+
- `npm run init -- plan --stack plain --overlays grafana --verbose`
|
|
100
|
+
- Confirmed verbose output reports stack-incompatible skip reasons for both `grafana` and its required dependency `prometheus`
|
|
101
|
+
- `npm test -- tool/__tests__/commands.test.ts`
|
|
102
|
+
- Passed after adding verbose coverage for direct, transitive, multi-parent, conflict, and invalid-selection behavior
|
|
103
|
+
- `npm test`
|
|
104
|
+
- Passed across the full Vitest suite after the verbose plan changes and documentation updates
|
|
105
|
+
- `npm run lint`
|
|
106
|
+
- Passed after formatting the remaining repository files that were part of the active verification surface
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Research: Verbose Plan Graph
|
|
2
|
+
|
|
3
|
+
## Decision 1: Attach explanation data to the existing dependency resolver
|
|
4
|
+
|
|
5
|
+
**Decision**: Extend the current `plan` dependency-resolution flow so it records inclusion reasons while producing the same resolved overlay set used by normal text and JSON output.
|
|
6
|
+
|
|
7
|
+
**Rationale**: `tool/commands/plan.ts` already resolves dependencies and feeds both text and JSON views. Reusing that path avoids divergence where verbose mode could explain a different result than the standard plan.
|
|
8
|
+
|
|
9
|
+
**Alternatives considered**:
|
|
10
|
+
|
|
11
|
+
- Build a separate explanation pass after resolution: rejected because it duplicates traversal logic and risks drifting from the actual resolver.
|
|
12
|
+
- Infer reasons only from `autoAddedOverlays`: rejected because it cannot represent transitive chains or multi-parent dependencies clearly enough.
|
|
13
|
+
|
|
14
|
+
## Decision 2: Model overlay inclusion as one final entry with one or more reasons
|
|
15
|
+
|
|
16
|
+
**Decision**: Represent each included overlay once, with attached reason records that indicate whether it was directly selected, required by another overlay, or reached through a transitive chain.
|
|
17
|
+
|
|
18
|
+
**Rationale**: The spec requires no duplicate final inclusion entries, even when a dependency is reached by multiple parents. A single overlay record with multiple reasons meets that requirement and keeps both text and JSON outputs easy to consume.
|
|
19
|
+
|
|
20
|
+
**Alternatives considered**:
|
|
21
|
+
|
|
22
|
+
- Emit one explanation row per path: rejected because the same overlay would appear multiple times and make the final resolved set harder to read.
|
|
23
|
+
- Keep only the first discovered reason: rejected because it hides valid parent relationships when multiple overlays require the same dependency.
|
|
24
|
+
|
|
25
|
+
## Decision 3: Keep verbose output opt-in and additive
|
|
26
|
+
|
|
27
|
+
**Decision**: Show the new explanation section only when `--verbose` is present, while leaving default text output unchanged.
|
|
28
|
+
|
|
29
|
+
**Rationale**: The existing `plan` command is a concise preview tool, and the spec explicitly requires backward-compatible default behavior. Opt-in narration preserves scanability for current users.
|
|
30
|
+
|
|
31
|
+
**Alternatives considered**:
|
|
32
|
+
|
|
33
|
+
- Always show inclusion reasons: rejected because it would alter the established command output and add noise to the common case.
|
|
34
|
+
- Replace the existing auto-added summary with verbose narration: rejected because it would collapse the quick summary and the detailed explanation into one harder-to-scan format.
|
|
35
|
+
|
|
36
|
+
## Decision 4: Expose explanation data in JSON only when verbose mode is requested
|
|
37
|
+
|
|
38
|
+
**Decision**: Add structured inclusion-reason data to the JSON plan payload when `--json` and `--verbose` are both present; preserve the existing JSON shape otherwise.
|
|
39
|
+
|
|
40
|
+
**Rationale**: Scripted consumers need access to the same reasoning as human readers, but existing JSON users should not be forced to adapt to new fields unless they explicitly request verbose mode.
|
|
41
|
+
|
|
42
|
+
**Alternatives considered**:
|
|
43
|
+
|
|
44
|
+
- Always add explanation fields to JSON: rejected because it changes the default contract for existing automation.
|
|
45
|
+
- Omit explanation data from JSON entirely: rejected because the spec requires structured verbose output for scripted consumers.
|
|
46
|
+
|
|
47
|
+
## Decision 5: Treat conflicts and invalid input as explanation boundaries, not silent failures
|
|
48
|
+
|
|
49
|
+
**Decision**: When resolution fails due to conflicts, unsupported overlays, or invalid overlay IDs, verbose mode should explain the last valid inclusion context and then identify the reason the plan cannot proceed.
|
|
50
|
+
|
|
51
|
+
**Rationale**: The feature principle is that nothing should feel magical. Users need to know where resolution stopped and why, especially when the command refuses to proceed.
|
|
52
|
+
|
|
53
|
+
**Alternatives considered**:
|
|
54
|
+
|
|
55
|
+
- Fall back to the existing failure messages without verbose context: rejected because it leaves the explanation incomplete in the scenarios where users most need it.
|
|
56
|
+
- Produce partial verbose output without marking the failure boundary: rejected because it could imply that the plan completed successfully.
|
|
57
|
+
|
|
58
|
+
## Decision 6: Verification should focus on command behavior, not only the helper function
|
|
59
|
+
|
|
60
|
+
**Decision**: Cover the new mode primarily with `planCommand` tests in `tool/__tests__/commands.test.ts`, supported by existing unit-level confidence around the command module.
|
|
61
|
+
|
|
62
|
+
**Rationale**: The user-visible risk is in the final text/JSON behavior and backward compatibility of the command surface. Command-level tests exercise option handling, output shaping, and failure behavior together.
|
|
63
|
+
|
|
64
|
+
**Alternatives considered**:
|
|
65
|
+
|
|
66
|
+
- Test only low-level resolver helpers: rejected because it would miss regressions in the rendered CLI and JSON contracts.
|
|
67
|
+
- Rely on manual validation alone: rejected because the change is user-visible and should be guarded by repeatable regression tests.
|
|
68
|
+
|
|
69
|
+
## Decision 7: Manifest-driven planning should reuse the same explanation model
|
|
70
|
+
|
|
71
|
+
**Decision**: When `plan` is run from an existing `superposition.json` manifest, verbose output should use the same inclusion-reason model and rendering rules as overlay-list-driven planning.
|
|
72
|
+
|
|
73
|
+
**Rationale**: Users should not receive different explanations depending on whether overlays were provided as flags or loaded from a manifest. One model keeps the output easier to reason about and reduces the risk of semantic drift.
|
|
74
|
+
|
|
75
|
+
**Alternatives considered**:
|
|
76
|
+
|
|
77
|
+
- Create a manifest-specific explanation mode: rejected because it would duplicate logic and force users to learn two explanation formats.
|
|
78
|
+
- Treat manifest-defined overlays as opaque input with no per-overlay reasoning: rejected because it violates the “nothing here is magic” principle.
|
|
79
|
+
|
|
80
|
+
## Decision 8: Manifest-defined overlays should be explained as the explicit starting set
|
|
81
|
+
|
|
82
|
+
**Decision**: In manifest-driven verbose planning, overlays loaded from the manifest should be treated as the explicit root selection set for explanation purposes, while still distinguishing auto-added dependencies from those roots.
|
|
83
|
+
|
|
84
|
+
**Rationale**: The user did not type the overlays on the current command line, but they are still part of an explicit saved configuration. Treating them as the root set preserves explainability without forcing users to re-enter them.
|
|
85
|
+
|
|
86
|
+
**Alternatives considered**:
|
|
87
|
+
|
|
88
|
+
- Label manifest overlays as dependencies: rejected because it misstates user intent and blurs the line between saved configuration and auto-resolved requirements.
|
|
89
|
+
- Add a third top-level selection mode with separate rendering rules: rejected because it adds conceptual weight without improving user value.
|
|
90
|
+
|
|
91
|
+
## Decision 9: Manifest failure should stop explanation before partial output is emitted
|
|
92
|
+
|
|
93
|
+
**Decision**: Missing, invalid, or semantically broken manifests should fail before verbose explanation output is produced, with a clear message explaining why planning cannot continue.
|
|
94
|
+
|
|
95
|
+
**Rationale**: A broken manifest means the plan has no trustworthy starting configuration. Producing partial verbose output in that state would make the command feel unreliable.
|
|
96
|
+
|
|
97
|
+
**Alternatives considered**:
|
|
98
|
+
|
|
99
|
+
- Emit partial verbose output for valid fragments of the manifest: rejected because partial planning from invalid input is misleading.
|
|
100
|
+
- Reconstruct overlays heuristically when the manifest is malformed: rejected because it adds hidden behavior and weakens trust.
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Feature Specification: Verbose Plan Graph
|
|
2
|
+
|
|
3
|
+
**Feature Branch**: `001-verbose-plan-graph`
|
|
4
|
+
**Created**: 2026-03-10
|
|
5
|
+
**Status**: Final
|
|
6
|
+
**Input**: User description: "Extend the plan command with a --verbose flag that narrates the dependency resolution graph — explaining why each overlay was included, not just what was included. The principle: nothing here is magic. Scope update: it should also be possible to run plan including --verbose on an existing manifest."
|
|
7
|
+
|
|
8
|
+
## Review & Approval _(mandatory before implementation)_
|
|
9
|
+
|
|
10
|
+
- **Spec Path**: `docs/specs/001-verbose-plan-graph/spec.md`
|
|
11
|
+
- **Commit Status**: Committed
|
|
12
|
+
- **Review Status**: APPROVED
|
|
13
|
+
- **Implementation Gate**: No implementation code may begin until this spec is committed and reviewed.
|
|
14
|
+
|
|
15
|
+
## User Scenarios & Testing _(mandatory)_
|
|
16
|
+
|
|
17
|
+
### User Story 1 - Explain auto-included overlays (Priority: P1)
|
|
18
|
+
|
|
19
|
+
A user previews a stack and wants to understand why extra overlays appear in the plan so they can trust the result before generating files.
|
|
20
|
+
|
|
21
|
+
**Why this priority**: The plan command is a decision aid. If users cannot see why dependencies were added, they cannot confidently approve the generated setup.
|
|
22
|
+
|
|
23
|
+
**Independent Test**: Can be fully tested by running `plan` with one overlay that causes at least one dependency to be included and confirming the verbose output explains each included overlay and its reason.
|
|
24
|
+
|
|
25
|
+
**Acceptance Scenarios**:
|
|
26
|
+
|
|
27
|
+
1. **Given** a user requests a plan with an overlay that requires another overlay, **When** the user adds `--verbose`, **Then** the plan explains that the requested overlay was included by user choice and the dependency was included because it is required by that overlay.
|
|
28
|
+
2. **Given** a dependency is included through more than one path, **When** the user adds `--verbose`, **Then** the plan shows all relevant parent reasons without duplicating the included overlay entry.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
### User Story 2 - Explain plans loaded from a manifest (Priority: P2)
|
|
33
|
+
|
|
34
|
+
A user reviews an existing `superposition.json` manifest and wants the same verbose dependency narration without re-entering overlay selections manually.
|
|
35
|
+
|
|
36
|
+
**Why this priority**: Manifest-driven workflows are already part of the product. Verbose explanation should work there too, or users will get different levels of transparency depending on how they invoke the plan.
|
|
37
|
+
|
|
38
|
+
**Independent Test**: Can be fully tested by running `plan` from an existing manifest with `--verbose` and confirming the explanation covers the manifest-defined overlays and any resolved dependencies.
|
|
39
|
+
|
|
40
|
+
**Acceptance Scenarios**:
|
|
41
|
+
|
|
42
|
+
1. **Given** a user runs the plan from an existing manifest, **When** the user adds `--verbose`, **Then** the plan explains why each overlay in the manifest-driven result was included using the same reasoning model as direct overlay selection.
|
|
43
|
+
2. **Given** the manifest includes overlays that produce required dependencies, **When** the user adds `--verbose`, **Then** the plan explains both the manifest-defined overlays and the auto-included dependencies without requiring duplicate manual input.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
### User Story 3 - Trace the full dependency path (Priority: P3)
|
|
48
|
+
|
|
49
|
+
A user wants to follow the dependency chain from requested overlays to transitive dependencies so they can review complex plans without guessing how the final set was derived.
|
|
50
|
+
|
|
51
|
+
**Why this priority**: Complex overlay combinations are harder to validate by inspection. Showing the chain reduces confusion and makes the tool easier to audit.
|
|
52
|
+
|
|
53
|
+
**Independent Test**: Can be fully tested by running `plan --verbose` with overlays that produce a multi-step dependency chain and verifying the explanation identifies each step in the chain.
|
|
54
|
+
|
|
55
|
+
**Acceptance Scenarios**:
|
|
56
|
+
|
|
57
|
+
1. **Given** a requested overlay leads to a transitive dependency chain, **When** the user adds `--verbose`, **Then** the plan narrates the chain in request-to-dependency order.
|
|
58
|
+
2. **Given** multiple requested overlays are resolved in one plan, **When** the user adds `--verbose`, **Then** the explanation groups or orders the reasoning so a user can tell which requested overlays caused each dependency.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
### User Story 4 - Preserve concise output when not needed (Priority: P4)
|
|
63
|
+
|
|
64
|
+
A user who only wants a quick summary should still be able to run the plan command without additional explanation noise.
|
|
65
|
+
|
|
66
|
+
**Why this priority**: The new explainability mode should add transparency without making the default workflow slower to scan.
|
|
67
|
+
|
|
68
|
+
**Independent Test**: Can be fully tested by comparing plan output with and without `--verbose` and confirming that explanation content appears only when explicitly requested.
|
|
69
|
+
|
|
70
|
+
**Acceptance Scenarios**:
|
|
71
|
+
|
|
72
|
+
1. **Given** a user runs the plan command without `--verbose`, **When** the plan is displayed, **Then** the command shows the existing summary output without dependency narration.
|
|
73
|
+
2. **Given** a user consumes the plan in structured output mode, **When** `--verbose` is present, **Then** the inclusion reasons are available in the structured result in addition to the standard plan data.
|
|
74
|
+
|
|
75
|
+
### Edge Cases
|
|
76
|
+
|
|
77
|
+
- A requested overlay has no dependencies and should still be explained as user-selected when `--verbose` is used.
|
|
78
|
+
- A dependency is required by multiple requested overlays and the explanation must show all contributing reasons without repeating the dependency as separate final selections.
|
|
79
|
+
- Dependency resolution stops because of a conflict or unsupported combination and the verbose output must clearly identify the last successful inclusion and the reason resolution could not continue.
|
|
80
|
+
- The user requests an invalid or unknown overlay and the plan must fail with a clear message instead of producing partial explanation data.
|
|
81
|
+
- A user attempts to plan from a missing or invalid manifest and the command must fail with a clear message instead of producing incomplete verbose explanation output.
|
|
82
|
+
|
|
83
|
+
## Requirements _(mandatory)_
|
|
84
|
+
|
|
85
|
+
### Functional Requirements
|
|
86
|
+
|
|
87
|
+
- **FR-001**: The plan command MUST accept a `--verbose` option that adds a narrative explanation of dependency resolution to the plan result.
|
|
88
|
+
- **FR-002**: When `--verbose` is present, the plan MUST explain why every included overlay appears in the final plan, including whether it was requested directly or added as a dependency.
|
|
89
|
+
- **FR-003**: When an included overlay was added because another overlay required it, the plan MUST identify the parent overlay or overlays that caused that inclusion.
|
|
90
|
+
- **FR-004**: When dependency resolution includes transitive dependencies, the plan MUST present the explanation as a traceable chain from the user-requested overlays to each transitive inclusion.
|
|
91
|
+
- **FR-005**: The plan MUST avoid duplicate final inclusion entries when the same dependency is reached through multiple paths while still preserving all relevant reasons for its inclusion.
|
|
92
|
+
- **FR-006**: When dependency resolution cannot complete because of conflicts, unsupported combinations, or invalid overlay selections, the verbose output MUST explain the point of failure and the reason the plan cannot proceed.
|
|
93
|
+
- **FR-007**: When the plan command is run from an existing `superposition.json` manifest, `--verbose` MUST provide the same dependency explanation coverage as overlay-list-driven planning.
|
|
94
|
+
- **FR-008**: When manifest-driven planning fails because the manifest is missing, invalid, or references invalid overlays, the command MUST produce a clear failure message and MUST NOT produce misleading partial verbose results.
|
|
95
|
+
- **FR-009**: When `--verbose` is not present, the plan command MUST preserve the existing concise behavior and must not require users to read dependency narration.
|
|
96
|
+
- **FR-010**: When the plan is requested in structured output mode together with `--verbose`, the inclusion reasons MUST be available in the structured result in a form that distinguishes direct selections from dependency-driven selections.
|
|
97
|
+
- **FR-011**: The explanation produced by `--verbose` MUST use the same resolved overlay set as the standard plan summary so users never see contradictory inclusion results between concise and verbose views.
|
|
98
|
+
|
|
99
|
+
### Key Entities _(include if feature involves data)_
|
|
100
|
+
|
|
101
|
+
- **Plan Request**: A user's preview request, including the chosen stack, selected overlays, and optional output flags that affect how the plan is presented.
|
|
102
|
+
- **Manifest-Based Plan Request**: A preview request loaded from an existing `superposition.json` manifest instead of explicit overlay flags, while preserving the same user-visible planning semantics.
|
|
103
|
+
- **Overlay Inclusion Reason**: A user-visible explanation describing why one overlay appears in the final plan, including whether it was directly requested, required by another overlay, or reached transitively through earlier inclusions.
|
|
104
|
+
- **Dependency Path**: The ordered relationship from one or more user-requested overlays through intermediate requirements to a final included overlay.
|
|
105
|
+
|
|
106
|
+
## Assumptions
|
|
107
|
+
|
|
108
|
+
- Users expect `--verbose` to add explanation only, not to change dependency resolution rules or the final set of included overlays.
|
|
109
|
+
- The same explainability data should be available to both human readers and scripted consumers when they explicitly request verbose output.
|
|
110
|
+
- Existing conflict and validation behavior remains in scope; this feature only expands how the reasoning is presented.
|
|
111
|
+
- Existing manifest-driven workflows should use the same explanation model as direct overlay selection rather than introducing a separate reasoning format.
|
|
112
|
+
|
|
113
|
+
## Dependencies & Impact _(mandatory)_
|
|
114
|
+
|
|
115
|
+
- **Affected Areas**: CLI command behavior, manifest-driven planning workflows, plan output, discovery documentation, CHANGELOG.md, automated tests
|
|
116
|
+
- **Compatibility Impact**: Backward compatible
|
|
117
|
+
- **Required Documentation Updates**: README.md, discovery command documentation, CHANGELOG.md
|
|
118
|
+
- **Verification Plan**: Unit tests for inclusion-reason reporting, command-level tests for verbose and non-verbose output, manifest-driven planning validation, and manual validation with direct, transitive, duplicate-path, manifest, and failure scenarios
|
|
119
|
+
|
|
120
|
+
## Success Criteria _(mandatory)_
|
|
121
|
+
|
|
122
|
+
### Measurable Outcomes
|
|
123
|
+
|
|
124
|
+
- **SC-001**: In review testing, 100% of overlays shown in a verbose plan include an explicit human-readable reason for inclusion.
|
|
125
|
+
- **SC-002**: Users can run a verbose plan from an existing manifest and receive the same class of inclusion explanations as they do from direct overlay selection in 100% of acceptance scenarios.
|
|
126
|
+
- **SC-003**: For plans with transitive dependencies, reviewers can identify the full inclusion chain for each dependency in under 30 seconds without consulting source code or overlay manifests.
|
|
127
|
+
- **SC-004**: In acceptance testing across representative plan scenarios, at least 90% of users correctly distinguish direct selections from auto-included dependencies after reading a single verbose plan output.
|
|
128
|
+
- **SC-005**: Running the plan command without `--verbose` continues to present the concise summary with no additional explanation sections in 100% of regression test cases.
|