docs/demo_graft_vertical_slice.md

# Graft Vertical Slice Demo

## Command

```bash
mix graft.graft.demo --repo <path> --name <name> [--root <path>] [--json]
```

## Flow

The demo exercises the complete graft loop in one command:

1. **Snapshot (current)** — Build an empty workspace snapshot rooted at a temp directory.
2. **Snapshot (desired)** — Build a workspace snapshot containing the specified repo as a `:managed` entry.
3. **Diff** — Compute structural delta between current and desired.
4. **Plan** — Generate a declarative graft plan (`:attach` action) from the diff.
5. **Verify** — Check real prerequisites:
   - Source repo path exists
   - Source repo is a git repository
   - Graft root is confined to temp dir or current working directory
   - No destructive overlap at materialization path
6. **Materialize** — Create a symlink from `<graft_root>/<name>` → `<repo_path>`.
7. **Observe** — Check drift between materialized state and desired state.
8. **Teardown** — Remove the symlink. The source repo is **never** touched.

## Output

### Human-readable (default)

```
═══════════════════════════════════════════════════════════════
 GRAFT VERTICAL SLICE DEMO
═══════════════════════════════════════════════════════════════

  Current snapshot id : <uuid>
  Desired snapshot id   : <uuid>

  Diff:
    added    : 2
    removed  : 0
    changed  : 0
    same     : 0

  Plan:
    id          : <id>
    action      : attach
    operations  : 2

  Verification:
    status  : PASS

  Materialization:
    path    : /tmp/.../<name>
    ok      : true

  Drift (observed vs desired):
    result  : <name>: no drift
    ok      : true

  Teardown:
    ok      : true

═══════════════════════════════════════════════════════════════
```

### JSON (`--json`)

```json
{
  "current_snapshot_id": "...",
  "desired_snapshot_id": "...",
  "diff": {"added": 2, "removed": 0, "changed": 0, "same": 0},
  "plan": {"id": "...", "action": "attach", "operations_count": 2},
  "verification": {"ok": true, "status": "verified", "message": "..."},
  "materialized_path": "/tmp/.../name",
  "materialization_ok": true,
  "drift": "name: no drift",
  "drift_ok": true,
  "teardown_ok": true,
  "graft_root": "/tmp/...",
  "repo_path": "/path/to/repo",
  "repo_name": "name"
}
```

## Guarantees

* **Source-repo immutability**: The source repository is never modified. Only a symlink is created inside the graft root.
* **Graft-root confinement**: Materialization is refused if the graft root escapes the temp directory or the current working directory.
* **Idempotency**: Running materialization twice is safe — if the correct symlink already exists, it is a no-op.
* **Clean teardown**: After the demo completes, no symlinks remain in the graft root. The graft root directory itself may remain (empty) but contains no managed entries.
* **Git validation**: The demo refuses to operate on non-git directories, ensuring the target is a real repository.

## Known Limitations

* **Local paths only**: Remote git URLs are parsed but return `{:error, :unsupported_remote_repo}`. Cloning from remotes is not implemented.
* **Symlinks only**: Materialization uses symbolic links. Copy-based or hard-link materialization is not supported.
* **Single repo**: The demo handles one repo at a time. Multi-repo grafts require orchestration at a higher level.
* **No rollback on failure**: If materialization fails after partial progress, manual cleanup of the graft root may be required.
* **No persistent state**: The demo does not write `.graft/state.json` or any other persistent metadata. It is purely ephemeral.
* **Plan verification bypass**: The standard `Graft.Plan.verify/1` checks preconditions against the current snapshot, which is empty in the demo. The demo therefore uses custom verification that checks real filesystem prerequisites instead.

## Files

| File | Purpose |
|------|---------|
| `lib/mix/tasks/graft.demo.ex` | CLI entrypoint |
| `lib/graft/graft/materializer.ex` | Filesystem materialization (symlink creation) |
| `lib/graft/graft/teardown.ex` | Safe removal of managed entries |
| `lib/graft/graft/drift.ex` | Observed-vs-desired state classification |
| `test/mix/tasks/graft.graft.demo_test.exs` | End-to-end tests |