` when a store is selected, and uses absolute paths
+ cross-root. A hint a user pastes must work verbatim.
+- **Agent contracts**: new JSON fields and diagnostic codes follow the
+ existing shared shapes (the root block pattern; severity/code/message/fix
+ diagnostics). Additive, consistent, no parallel envelope styles.
+- **Lean modules**: a touched module exceeding ~600 lines triggers a split
+ or a recorded reason. New abstractions need at least two real call sites
+ or a recorded reason — no speculative generality.
+- **Dependency direction**: core never imports from commands; store Git
+ mechanics stay behind the single git module; config parsing and
+ instruction injection stay in their own modules. Root resolution remains
+ exactly one shared code path — no command-local forks of precedence.
+
+Codex review invocation: `codex exec` non-interactively with model 5.5 at
+high reasoning (`-c model=...` and reasoning-effort overrides; confirm the
+exact model id with `codex exec --help`/config on first use and then reuse
+it). Give codex the commit range or artifact paths and ask for findings with
+severity and file:line evidence.
+
+Deletion-slice review profile (Phase 5 remainder only): spec review keeps
+the full dual shape (subagent + codex); plan review runs the adversarial
+subagent alone, no codex; post-implementation review runs the
+spec-compliance agent and `/code-review` at high effort, no per-slice
+codex. Rationale: deletion slices are mechanical, their review-fix rounds
+have been the smallest of the run, and the 6.1 whole-delta codex review
+re-covers every deleted line anyway. Build slices (4.1) keep the full
+discipline.
+
+Slice-specific acceptance:
+
+- **1.4**: after implementation, run the dogfood proof headlessly — in a
+ scratch project with isolated XDG state and a registered store, a fresh
+ headless agent session must complete a store-scoped change from a single
+ prompt without hand-holding.
+
+## Final acceptance capstone (6.1 — last queue item)
+
+The capstone proves the *product*, not the slices. It only passes when a
+cold user could start using this today. Its checks:
+
+1. **Persona journeys**, each as an e2e test or headless dogfood:
+ - Fresh team: create a store, work a change through archive, commit and
+ push locally; second checkout clones, registers, continues (the 1.3
+ journey must still pass after the rename and deletions, with new
+ names).
+ - Layered flow: requirements in a store; an agent in an app repo that
+ references it discovers the relationship from config, cites the
+ upstream spec, writes a low-level design in the app repo's own root.
+ - Externalized planning: a repo with no local root and a fallback
+ declaration runs the normal lifecycle without `--store` repetition.
+ - Cold start: a fresh headless agent, given only a vague human prompt
+ ("set up planning in a separate repo for this project") and no insider
+ knowledge, succeeds using only `--help` output and generated guidance.
+2. **Usability audits**: an error-catalog walk (every likely wrong turn on
+ the new paths yields an actionable, store-carrying error); a vocabulary
+ sweep (zero "context store"/initiative/workspace residue in any
+ user-facing surface, including `docs/cli.md`); a documented
+ time-to-first-success count (commands and concepts from install to first
+ store-scoped change).
+3. **Technical audits**: single-resolver invariant (one precedence
+ implementation, no command-local forks); dependency-direction check;
+ dead-code sweep over touched areas; module-size report; an agent-contract
+ inventory (all JSON shapes and diagnostic codes documented in one
+ reference file and verified consistent); net LOC delta vs `origin/main`
+ reported (expected net-negative given the Phase 5 deletions — justify if
+ not).
+4. **Whole-delta review gauntlet** over `origin/main...HEAD` (the sum, not
+ the slices): `/code-review` at max effort, a codex CLI review, a
+ fan-out of adversarial Workflow reviewers, and a completeness critic
+ asking what is missing. Fix all P1/P2 findings.
+5. **Release-readiness report** committed to this work folder: the
+ five-minute new-user story, audit results, the full
+ `Decided autonomously` ledger, and known gaps mapped to Later Ideas.
+
+## Autonomous decision protocol
+
+When a slice surfaces a decision the roadmap has not locked:
+
+1. Make the call most consistent with the locked decisions, the guardrails,
+ and the goal ("Specs are what is true. Work is what is in motion.").
+2. Record it the same day in the roadmap changelog under a clearly marked
+ line: `Decided autonomously (review me): ...` with the rationale.
+3. Continue. Do not stop to ask; do not silently decide either — the
+ changelog marker is the user's review surface.
+
+Phase 5 deletion slices proceed without confirmation: they delete code and
+generated guidance only, never user data, and git history is the undo.
+
+## Hard boundaries (prohibitions, not gates)
+
+- **Never** merge, rebase onto, or push to `main`; never push at all —
+ commits stay local on `codex/store-root-parity`.
+- Never delete user data files.
+- Never re-open a locked decision; never rebuild per-change links
+ (relationships are location, declaration, or citation).
+- One change lives in one root.
+
+## Parallelism policy
+
+- **Cross-slice work stays serial.** Every slice lands on the single branch;
+ the junction files (`src/cli/index.ts`, the completions registry,
+ `project-config.ts`, `foundation.ts`/`registry.ts`, and `roadmap.md`
+ bookkeeping) are shared by nearly every slice; and the queue's two largest
+ commits — the 1.4 mass rename and the Phase 5 mass deletion — are the
+ worst bases to rebase parallel tracks across.
+- **Within-slice fan-outs are encouraged.** Mechanical sweeps over
+ partitioned file sets — the 1.4 rename and guidance surfaces, the Phase 5
+ deletion sweep — run as Workflows, with worktree isolation when agents
+ edit concurrently. One integration point, one full-suite run.
+- **Lookahead research is allowed.** During implementation turns, a
+ background read-only workflow may pre-build the next slice's code map
+ (file:line anchors for its plan). Never pre-write the next spec against
+ unlanded code or names.
+
+## Turn sizing and status (the evaluator reads this)
+
+- One coherent unit per turn: a spec with its reviews, a plan with its
+ reviews, an implementation checkpoint, or a review-and-fix cycle.
+- End every turn with an explicit status block stating: current slice and
+ step, what was produced this turn, review verdicts, test-suite state, any
+ `Decided autonomously` entries, and what the next turn does. The goal
+ evaluator only sees what the transcript surfaces — state progress
+ plainly, never implicitly.
+- The run is complete when every queue item's roadmap progress boxes are
+ ticked except "Merged to `main`", the full suite is green, all work is
+ committed, **and the 6.1 capstone passes with its release-readiness
+ report committed and no open P1/P2 findings**. When that is true, say so
+ explicitly in the final status: "ROADMAP QUEUE COMPLETE" plus the closing
+ summary including every `Decided autonomously` entry for review.
diff --git a/openspec/work/simplify-context-and-workspace-model/slice-1.2-decision-review.html b/openspec/work/simplify-context-and-workspace-model/slice-1.2-decision-review.html
new file mode 100644
index 000000000..d21a1c6fa
--- /dev/null
+++ b/openspec/work/simplify-context-and-workspace-model/slice-1.2-decision-review.html
@@ -0,0 +1,436 @@
+
+
+
+
+
+Slice 1.2 — Decision Review
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openspec/work/simplify-context-and-workspace-model/slices/assemble-working-context/plan.md b/openspec/work/simplify-context-and-workspace-model/slices/assemble-working-context/plan.md
new file mode 100644
index 000000000..f42b61a1a
--- /dev/null
+++ b/openspec/work/simplify-context-and-workspace-model/slices/assemble-working-context/plan.md
@@ -0,0 +1,167 @@
+# Assemble Working Context Plan (4.1)
+
+## Status
+
+Spec locked 2026-06-11 after two adversarial rounds (binding.ts dies
+whole; the five template guards join; the member-mapping table; pinned
+write semantics; getRepoPath deleted). Plan drafted 2026-06-11.
+Implementation not started.
+
+The main move:
+
+```text
+Delete the dead opening machinery, extract doctor's gather, and the
+working set becomes one thin command over data Phase 3 already built.
+```
+
+## Source Of Truth
+
+Start from `spec.md` (this folder). Keep nearby: `../../roadmap.md`
+(Phase 4 + the absorbed 2.3), the deletion ledger
+(`../delete-legacy-command-groups/deletion-ledger.md` — updated by this
+slice), `../relationship-health/spec.md` (the consumed data shapes).
+
+## Current Code Map (verified during spec review)
+
+- **Deletion targets and their consumers**:
+ - `src/core/workspace/` (897 lines): imported by `planning-home.ts`
+ and the `src/core/index.ts` barrel only (plus its own tests).
+ - `src/core/store/binding.ts` (~300 lines): imported by
+ `workspace/foundation.ts` and the `store/index.ts` barrel; tests in
+ `test/core/store/registry.test.ts` (the binding describe block).
+ - `planning-home.ts`: `PlanningHomeKind = 'repo' | 'workspace'`,
+ the workspace state read, `WORKSPACE_DEFAULT_SCHEMA`; consumers of
+ `PlanningHome` never branch on `kind === 'workspace'` in production
+ (verified — `toPlanningHome` hardcodes repo;
+ `resolveCurrentPlanningHomeSync`'s workspace branch is the
+ CLI-unreachable carve-out).
+ - `change-status-policy.ts` cascade: `summarizeAffectedAreas`,
+ `AffectedAreasSummary`, `ChangeNextStepsInput.affectedAreas`,
+ workspace next-steps (~:130-135), `PlanningHomeSummary
+ .workspaceName`, the `'workspace-planning'` mode member;
+ instruction-loader plumbing at `instruction-loader.ts:465-496`.
+ - The five template guards:
+ `src/core/templates/workflows/{apply-change.ts:57,
+ verify-change.ts:41, archive-change.ts:40,
+ bulk-archive-change.ts:47, sync-specs.ts:39}` + mirrored second
+ occurrences — grep `workspace-planning` in templates to catch all.
+ - `getRepoPath` (`store/registry.ts`) + its unit tests.
+ - Test deletions: `planning-home.test.ts` workspace cases; the
+ legacy-groups workspace-planning LIBRARY pin (:185-203);
+ `test/core/workspace/{foundation,legacy-state}.test.ts`.
+ - Ledger updates: carve-outs → executed; Surviving tokens pruned;
+ `workspace_skills` allowlist entry removed
+ (`test/vocabulary-sweep.test.ts:79`).
+- **Assembly anchors**: doctor's `gatherHealth`
+ (`src/commands/doctor.ts:37-141`) — the DATA half (snapshot +
+ health-mode index + targets + root inspection ≈ :42-75) extracts to
+ `src/commands/shared-gather.ts`; `readRegistrySnapshot`
+ (`store/registry.ts`); `inspectRelationships`
+ (`core/relationship-health.ts`); `fetchRecipe` (module-private at
+ `references.ts:133` — export); `RelationshipHealth.targets` =
+ `HealthTargetEntry[]`; the failure-payload mechanism
+ (`resolveRootForCommand` + `failurePayload`, doctor precedent).
+- **Command registration**: doctor precedent
+ (`src/commands/doctor.ts:registerDoctorCommand`, `cli/index.ts`,
+ completions `command-registry.ts`, `STORE_SELECTION_GUIDANCE`,
+ parity hashes).
+
+## Implementation Plan
+
+### Checkpoint 1 — the deletions (commit)
+
+Order: leaves first, compiler-verified after each tranche.
+
+1. Templates: remove the five workspace-planning guards (grep-driven);
+ regenerate parity hashes + `.codex` guidance; FLIP the parity
+ test's guard assertion (skill-templates-parity.test.ts:179 asserts
+ the guards exist — it becomes an absence assertion: no generated
+ template contains `workspace-planning`).
+2. `change-status-policy.ts` cascade + instruction-loader plumbing
+ (incl. `ChangeStatus.affectedAreas` and the
+ `artifact-graph/index.ts` barrel re-export of
+ `AffectedAreasSummary`); the legacy-groups library pin dies; the
+ six CLI-surface pins stay green untouched.
+3. `planning-home.ts`: collapse to repo-only (keep the interface);
+ delete the workspace import; `planning-home.test.ts` workspace
+ cases die.
+4. `src/core/workspace/` whole + `core/index.ts` barrel line +
+ `test/core/workspace/{foundation,legacy-state}.test.ts`.
+5. `store/binding.ts` whole + `store/index.ts` barrel line + the two
+ binding `it` cases in `registry.test.ts` (:356, :414) and their
+ imports.
+6. `getRepoPath` + its tests; amend the repo-map ledger note.
+7. Ledger + vocabulary-allowlist updates; full suite green; net-LOC
+ note in the commit message.
+
+### Checkpoint 2 — assembly: core + command + e2e + docs (commit)
+
+1. `references.ts`: export `fetchRecipe`.
+2. `src/commands/shared-gather.ts`: `gatherRelationshipData(root)` →
+ `{registrySnapshot, referenceEntries, effectiveTargets,
+ storeTargets, projectConfig, storeConfigPath, rootInspection}` —
+ doctor refactors onto it (behavior byte-identical; doctor e2e is
+ the net), context consumes it.
+3. `src/core/working-set.ts` (pure):
+ - `WorkingSet {root: {path, source, store_id?, role}, members:
+ WorkingSetMember[], status: []}`;
+ `WorkingSetMember {role, id, path?, remote?, fetch?, status}`.
+ - `assembleWorkingSet({root, referenceEntries, targets,
+ registryUnreadable})`: the spec's member-mapping table
+ (available = path + empty status; references before targets;
+ synthesized entries appended; fetch recipes on available stores).
+ - `buildCodeWorkspaceJson(workingSet, rootName)`: pure string
+ builder, available members only, `ref:`/`repo:` prefixes.
+4. `src/commands/context.ts`: resolution like doctor
+ (`allowImplicitRoot: false`, failure payload
+ `{root: null, members: []}`); the shared gather;
+ human listing (Available sections + "Not available on this
+ machine"); `--json`; `--code-workspace ` (+`--force`): refuse
+ `context_file_exists` exit 1 (spec-amended name — the draft's
+ `code_workspace_exists` trips the sweep's `workspace_*` ban);
+ missing parent dir → clear error, no mkdir; stderr confirmation
+ under `--json`; unresolved members reported on stderr during
+ writes; try/catch via `emitFailure` (the 3.6 lesson). CLI +
+ completions + `STORE_SELECTION_GUIDANCE` + parity hashes.
+5. Tests: working-set unit (mapping table incl. stale-path,
+ invalid-id, registry-unreadable-bare members; ordering; fetch);
+ builder unit (folders, prefixes, omission); command e2e (three
+ session shapes; JSON exact shape; nothing-declared; the write
+ matrix — fresh/exists/force/nested-missing-parent/json-stderr;
+ read-only snapshot; failure payloads).
+6. `docs/cli.md`: context section + summary row + doctor cross-link +
+ the project-context vs working-context disambiguation sentence.
+7. Full suite; built-binary smoke of the UX transcript.
+
+## Risks And Guardrails
+
+- **Deletion order is the spine**: each tranche compiles and the full
+ suite passes before the next; never delete ahead of the compiler.
+- **Doctor must not change**: the shared-gather extraction is a pure
+ refactor; doctor's e2e suite is the net (behavior-identical — the
+ suite asserts fields and sections, not full-output bytes).
+- **The six legacy-groups CLI pins** and the user-data byte-identity
+ test stay untouched and green — they are the proof the deletions
+ changed no repo-local behavior.
+- **Parity churn is deliberate twice** (template guards in CP1,
+ guidance in CP2) — update hashes from the test diff, never loosen.
+- **No new diagnostic codes except `context_file_exists`** (the one
+ write needs the one refusal). Implementation amendment: the
+ missing-parent-directory failure also got a typed code
+ (`context_output_dir_missing`) — the spec pinned only "fails with a
+ clear error" with no code, and a typed code serves JSON consumers
+ better than the generic fallback; recorded here rather than left as
+ silent drift.
+- **Vocabulary**: 'working context' in user-facing strings; never
+ 'workspace' — enforced by manual review + the Done-Definition grep
+ (the sweep bans only the compound and `workspace_*` tokens, not the
+ bare word).
+
+## Done Definition
+
+- Both checkpoints green on the full suite and committed.
+- `grep -r workspace src/` returns only the `.code-workspace` file
+ format references and historical comments (verify; the sweep
+ allowlist reflects reality).
+- Roadmap 4.1 boxes ticked through "Tests pass"; changelog updated;
+ pointer moved to the Phase 5 remainder.
diff --git a/openspec/work/simplify-context-and-workspace-model/slices/assemble-working-context/spec.md b/openspec/work/simplify-context-and-workspace-model/slices/assemble-working-context/spec.md
new file mode 100644
index 000000000..461a118b1
--- /dev/null
+++ b/openspec/work/simplify-context-and-workspace-model/slices/assemble-working-context/spec.md
@@ -0,0 +1,281 @@
+# Assemble Working Context Spec (4.1)
+
+## Outcome
+
+From any root, one command produces the full working set its
+declarations describe — the OpenSpec root, its referenced stores, and
+its mapped target repos — consumable as an agent session brief (JSON +
+human) or as an editor view (a `.code-workspace` file, one consumer of
+assembly, not the feature). Unresolvable pieces are reported, not
+guessed. And the old workspace opening machinery this replaces — the
+state model and workspace-planning mode that have been CLI-unreachable
+since 1.2 — is deleted per the recorded ledger carve-outs (the absorbed
+2.3: no de-initiative-ing of a path that dies).
+
+## Locked Decisions (roadmap)
+
+1. **Assembly is a local convenience computed from Phase 3's declared
+ relationships, not a new planning system.** The selected OpenSpec
+ root is the durable planning source of truth; references supply
+ upstream stores; the local repo map supplies target checkouts. No
+ workspace-owned planning state, ever.
+2. **The primary interface is an agent session** — the assembled set
+ must be agent-consumable, not only editor-shaped.
+3. **No machinery**: no clone, pull, push, sync, branch, worktree,
+ dashboard, or edit-boundary enforcement.
+4. **Unresolvable pieces are reported, not guessed.**
+5. **The absorbed 2.3**: opening is rebuilt around assembled context;
+ the old workspace state model (with initiative selection hardcoded
+ in) is deleted, not decoupled.
+
+## Decisions This Spec Makes (autonomous, recorded in the changelog)
+
+1. **The surface is a new top-level `openspec context`** — "print the
+ working context for the resolved root". Resolution is the normal
+ precedence (`--store`, nearest, declared pointer; no implicit
+ scaffold). JSON is the agent brief; human output is a readable set
+ listing; `--code-workspace ` additionally WRITES a VS Code
+ workspace file (the one write this feature performs, explicit and
+ user-requested — never implied). The name "context" is the phase's
+ own noun; the banned token is the compound "context store", not the
+ word.
+2. **Assembly is presentation over `inspectRelationships`** — the 3.6
+ spec recorded 4.1 as its consumer. The DATA gather (registry
+ snapshot, health-mode reference index, store-level targets, root
+ inspection) is EXTRACTED into a shared command-layer helper that
+ doctor and context both call; doctor-only inputs (store facts, the
+ wrong-turn detections, stale-path stats) stay in doctor — context
+ is deliberately SILENT on both-shapes/inert-pointer/divergence
+ (recorded: context answers "what is my working set", doctor answers
+ "is it healthy"; 3.6 pinned those diagnostics to doctor output and
+ ONLY there). Member mapping from the health data, pinned:
+ - AVAILABLE = `path` present AND per-entry `status` empty. Only
+ available members enter the `.code-workspace`.
+ - `target_path_missing` entries (path + warning) are NOT available
+ (the stale path appears in the message, never as a folder).
+ - Synthesized `target_invalid_id` entries are NOT-available members
+ carrying their status; they append after declared members
+ (declaration order holds for declared members only — recorded).
+ - Registry-unreadable bare targets are NOT-available members with
+ empty per-entry status; the top-level registry-unreadable entry
+ names the cause.
+ No new diagnostic codes; the unresolved members carry the existing
+ fixes verbatim.
+3. **JSON shape**:
+ `{root: {path, source, store_id?, role: "openspec_root"},
+ members: [{role: "referenced_store" | "target_repo", id, path?,
+ remote?, status: []}], status: []}` — `path` present iff resolved/
+ mapped; members in declaration order, references before targets;
+ the top-level `status` carries the registry-unreadable degradation.
+ The fetch recipe for referenced stores rides each resolved member
+ (`fetch: openspec show --type spec --store `, reusing
+ the exported references `fetchRecipe` — one source for the string)
+ so an agent brief is self-contained.
+4. **The `.code-workspace` emitter** writes
+ `{folders: [{name, path}...]}` — the root first (name: the root
+ dir basename or store id), then AVAILABLE referenced stores
+ (`ref:`), then AVAILABLE targets (`repo:`). Unavailable
+ members are omitted from the file and reported on stderr. Write
+ semantics, pinned: an existing path refuses with exit 1 and a typed
+ `context_file_exists` diagnostic whose fix names `--force`
+ (implementation amendment: the draft's `code_workspace_exists`
+ would trip the vocabulary sweep's `workspace_*` token ban — the
+ flag name `--code-workspace` is safe, hyphenated);
+ `--force` overwrites; a missing parent directory fails with a clear
+ error (NO implicit mkdir — the requested file is the only write);
+ with `--json`, the brief stays pure on stdout and the write
+ confirmation goes to stderr. 4.1 replaces opening with emitted
+ assembled-context artifacts; no `open` verb or editor process
+ launch is introduced.
+5. **The deletions — the ledger's 4.1 carve-outs, widened where the
+ carve-out rationale collapses**:
+ - `src/core/workspace/` whole (foundation, state-io, legacy-state,
+ index — ~900 lines) plus the `src/core/index.ts` barrel line.
+ - `planning-home.ts`'s workspace branch: `PlanningHomeKind`
+ collapses to `'repo'`, the workspace state read and
+ `WORKSPACE_DEFAULT_SCHEMA` die; the `PlanningHome` interface
+ survives as the repo-shaped carrier.
+ - `binding.ts` WHOLE (review finding: 5.1 kept it only because
+ workspace/foundation imported it; with workspace/ gone it has
+ zero production consumers — the whole ~300-line module dies, with
+ its `registry.test.ts` binding tests and the `store/index.ts`
+ barrel line, exactly the hidden-not-deleted state the 5.1
+ criteria reject).
+ - `change-status-policy.ts`'s workspace-planning branch AND its
+ cascade: `summarizeAffectedAreas` (constant-undefined
+ post-collapse), `AffectedAreasSummary`,
+ `ChangeNextStepsInput.affectedAreas`, the workspace next-steps,
+ `PlanningHomeSummary.workspaceName`, the `'workspace-planning'`
+ mode union member, and the instruction-loader plumbing that
+ threads them.
+ - The FIVE workflow-template workspace-planning guards
+ (apply/verify/archive/bulk-archive/sync-specs templates, two
+ occurrences each) — 5.1 explicitly deeded them here ("they quote
+ the library contract that 4.1 deletes"); their removal churns the
+ skill-template parity hashes and the checked-in `.codex` guidance
+ deliberately.
+ - `getRepoPath` (review finding: its recorded consumers
+ evaporated — the snapshot serves every caller; delete-don't-hide,
+ with the repo-map record amended).
+ Library pins that existed solely to freeze the carve-outs
+ (`planning-home.test.ts` workspace cases, the legacy-groups
+ workspace-planning library pin) are deleted WITH the behavior; the
+ six legacy-groups CLI-surface pins stay and must remain
+ byte-identical. The deletion ledger is updated throughout
+ (carve-outs marked executed, the Surviving-tokens section pruned,
+ the `workspace_skills` vocabulary-allowlist entry removed — its
+ referents die here, verified). The workspace-planning SCHEMA files
+ and the accepted-spec L2 question stay with the Phase 5 remainder
+ as recorded.
+6. **Naming, recorded**: `openspec context` over `openspec view` (the
+ dashboard owns `view`) and over an `open` verb (no process
+ launching). The vocabulary sweep bans only the compound
+ `context store`; docs disambiguate "project context" (the config
+ field injected into instructions) from "working context" (this
+ set). Adding `context` to `STORE_SELECTION_GUIDANCE` rewrites the
+ generated workflow templates — the parity hashes and guidance walk
+ update deliberately, as in 3.6.
+
+## User Experience
+
+```text
+$ openspec context
+Working context for team-context (/Users/dev/src/team-context)
+
+OpenSpec root
+ team-context /Users/dev/src/team-context
+
+Referenced stores
+ upstream-context /Users/dev/openspec/upstream-context
+ Fetch: openspec show --type spec --store upstream-context
+
+Target repos
+ api-server /Users/dev/src/api-server
+
+Not available on this machine
+ - design-system: not registered
+ Fix: git clone -- https://github.com/acme/design-system.git /Users/dev/openspec/design-system && openspec store register '/Users/dev/openspec/design-system' --id design-system
+ - web-app: not mapped
+ Fix: Run: openspec repo register --id web-app
+```
+
+```text
+$ openspec context --code-workspace team.code-workspace
+Wrote team.code-workspace (3 folders; 2 members not available, see above)
+```
+
+The agent brief:
+
+```json
+{
+ "root": { "path": "/Users/dev/src/team-context", "source": "store", "store_id": "team-context", "role": "openspec_root" },
+ "members": [
+ { "role": "referenced_store", "id": "upstream-context", "path": "/Users/dev/openspec/upstream-context", "fetch": "openspec show --type spec --store upstream-context", "status": [] },
+ { "role": "referenced_store", "id": "design-system", "status": [{ "code": "reference_unresolved", ... }] },
+ { "role": "target_repo", "id": "api-server", "path": "/Users/dev/src/api-server", "status": [] },
+ { "role": "target_repo", "id": "web-app", "status": [{ "code": "target_unmapped", ... }] }
+ ],
+ "status": []
+}
+```
+
+## Scope
+
+In scope:
+
+- **Core** (`src/core/working-set.ts`): `assembleWorkingSet` — pure
+ mapping from `RelationshipHealth` (or its inputs) to the members
+ shape; the `.code-workspace` content builder (pure: returns the JSON
+ string; the COMMAND writes it).
+- **Command** (`src/commands/context.ts`) + the shared gather
+ (`src/commands/shared-gather.ts`): the data gather extracted from
+ doctor (snapshot + health-mode index + targets + root inspection),
+ consumed by both; doctor keeps its wrong-turn/store-facts/stale-path
+ additions; `--code-workspace ` + `--force`; CLI/completions
+ registration (friction pins; `STORE_SELECTION_GUIDANCE` gains
+ `context`).
+- **Deletions** per decision 5, with `pnpm test` green after each
+ removal tranche; the deletion ledger updated (carve-outs marked
+ executed); the vocabulary-sweep allowlist pruned if the
+ workspace_skills entry's referent died (verify).
+- **Docs**: `docs/cli.md` context section + summary row; the doctor
+ section cross-links ("doctor answers whether the set is healthy").
+- **Tests**: working-set unit (member mapping, ordering, fetch
+ recipes, unresolved members, registry-unreadable degradation);
+ code-workspace builder unit (folder list, name prefixes, omission of
+ unresolved); command e2e (the three session shapes; JSON shape; the
+ write + `--force` + refusal; stderr reporting; read-only except the
+ requested file); deletion regression (the full suite is the net —
+ workspace tests die with the code; `legacy-groups-removed.test.ts`
+ drops its workspace-planning library pins and keeps the
+ CLI-surface pins).
+
+Out of scope:
+
+- Editor integrations beyond the `.code-workspace` file; terminal
+ multiplexers; session managers.
+- Any open/launch behavior (no spawning editors).
+- The workspace-planning schema files, obsolete beta change folders,
+ and the L2 accepted-specs question (Phase 5 remainder, as recorded).
+- Per-change context narrowing (instructions already shows per-change
+ targets).
+
+## Acceptance Criteria
+
+### The Working Set Is Complete And Honest
+
+#### Scenario: Assembly From Declarations
+
+- **GIVEN** a store-backed root with one resolvable + one unresolvable
+ reference and one mapped + one unmapped target
+- **WHEN** `openspec context` runs (human + JSON; `--store`, nearest,
+ and declared-pointer sessions)
+- **THEN** JSON matches decision 3 exactly: resolved members carry
+ absolute paths (and fetch recipes for stores), unresolved members
+ carry the existing diagnostics verbatim (the 3.3 clone fix, the
+ register fix), members in declaration order, references before
+ targets
+- **AND** human output separates available from "Not available on this
+ machine"
+- **AND** exit code is 0 (unresolved members are reported, not errors;
+ command failures keep the resolution taxonomy and the null-shape
+ payload `{root: null, members: [], status: [diagnostic]}`)
+
+#### Scenario: Nothing Declared
+
+- **GIVEN** a root with no references or targets
+- **WHEN** context runs
+- **THEN** the set contains only the root, `members: []`, and human
+ output says so plainly
+
+### The Editor View Is One Consumer
+
+#### Scenario: Code-Workspace Emission
+
+- **GIVEN** the mixed fixture above
+- **WHEN** `openspec context --code-workspace out.code-workspace` runs
+- **THEN** the file contains folders for the root + resolved members
+ only, named ``, `ref:`, `repo:`, in that order
+- **AND** unresolved members are reported on stderr, not written
+- **AND** rerunning without `--force` refuses with exit 1 and the
+ typed `context_file_exists` fix naming `--force`; with `--force`
+ it overwrites
+- **AND** a missing parent directory fails clearly with no mkdir
+- **AND** with `--json`, stdout stays the pure brief and the write
+ confirmation lands on stderr
+- **AND** no other file or registry state changes (snapshot)
+
+### The Old Machinery Is Gone
+
+#### Scenario: The Carve-Outs Are Executed
+
+- **GIVEN** the post-4.1 tree
+- **WHEN** the suite runs and the ledger is read
+- **THEN** `src/core/workspace/` does not exist; `PlanningHomeKind`
+ is `'repo'` only; the change-status-policy and binding carve-outs
+ are gone; no `workspace_*` diagnostic codes or workspace state reads
+ remain in src (the vocabulary sweep's allowlist reflects reality)
+- **AND** every repo-local CLI behavior pinned by
+ `legacy-groups-removed.test.ts`'s surface tests is byte-identical
+- **AND** assembly works without any workspace/initiative state
+ (no `.openspec-workspace` reads anywhere in src)
diff --git a/openspec/work/simplify-context-and-workspace-model/slices/declared-store-fallback/plan.md b/openspec/work/simplify-context-and-workspace-model/slices/declared-store-fallback/plan.md
new file mode 100644
index 000000000..0df7342d6
--- /dev/null
+++ b/openspec/work/simplify-context-and-workspace-model/slices/declared-store-fallback/plan.md
@@ -0,0 +1,183 @@
+# Declared Store Fallback Plan (3.2)
+
+## Status
+
+Spec locked 2026-06-11 after two adversarial rounds (the store-selected
+predicate adopted by all seven source-keyed consumers; init's pointer
+guard; malformed-pointer errors; one-hop rule; warning-silent resolver
+reads; the recorded doctor-wording amendment). Plan drafted 2026-06-11.
+Implementation not started.
+
+The main move:
+
+```text
+One predicate ("a store-selected root has storeId"), one pointer branch
+in the resolver, one init guard — and externalized planning needs no
+flags.
+```
+
+## Source Of Truth
+
+Start from `spec.md` (this folder). Keep nearby: `../../roadmap.md`
+(Phase 3 precedence lock + the recorded amendment),
+`../store-references/spec.md` (3.1 config patterns),
+`../store-lifecycle-proof/spec.md` (hint-continuity contracts).
+
+## Current Code Map (verified during spec review)
+
+- **Resolver**: `resolveOpenSpecRoot` (`src/core/root-selection.ts:258-314`);
+ the nearest-root arm at 277-280 (`findRepoPlanningRootSync` returns
+ the project root whose `openspec/` exists and terminates at the
+ nearest ancestor — `planning-home.ts:52-77`); the stores-hint error
+ at 293-302; implicit at 305-313. `resolveStoreRoot` (134-218, module
+ private, same file) is the pipeline the pointer branch calls.
+- **Source-keyed consumers to switch to the predicate** (all EIGHT
+ checks — plan review found the spec's "seven" missed one):
+ `emitStoreRootBanner` (`root-selection.ts:339`), `withStoreFlag`
+ (`root-selection.ts:349`), new-change path display
+ (`src/commands/workflow/new-change.ts:77`), status storeId
+ threading (`src/commands/workflow/status.ts:106` → `buildNextSteps`
+ appends `--store`), validate noun-suggestion suppression
+ (`src/commands/validate.ts:136`), show noun-suggestion suppression in
+ BOTH branches (`src/commands/show.ts:138` and
+ `printNonInteractiveHint` at `show.ts:160`), archive absolute display
+ paths (`src/core/archive.ts:446`). Spec amendment recorded in the
+ changelog: eight checks, not seven.
+- **Config**: `ProjectConfigSchema`/`readProjectConfig`
+ (`src/core/project-config.ts`); the resolver does NOT reuse
+ `readProjectConfig` (it would re-emit field warnings) — it does a
+ targeted read.
+- **Init**: `InitCommand.execute` → `createDirectoryStructure`
+ (`src/core/init.ts:144, 455-487`) unconditionally scaffolds under an
+ existing `openspec/`; the guard goes before that.
+- **Tests**: `test/core/root-selection.test.ts` (resolver unit),
+ `test/commands/store-root-selection.test.ts` (CLI),
+ `test/core/init.test.ts`, `test/cli-e2e/` harness,
+ `test/helpers/openspec-fixtures.ts` (shared fixtures from 3.1).
+
+## Implementation Plan
+
+### Checkpoint 1 — resolver + predicate (commit)
+
+1. `src/core/project-config.ts`: add `store: z.string().optional()` to
+ the schema; resilient parse keeps a string, drops non-strings with
+ a warning (the parser's behavior is unchanged in spirit — the
+ RESOLVER, not the parser, owns the malformed-pointer error, and it
+ reads the file itself).
+2. `src/core/root-selection.ts`:
+ - `OpenSpecRootSource` gains `'declared'`.
+ - New `isStoreSelectedRoot(root)` predicate (`storeId !== undefined`);
+ `emitStoreRootBanner` and `withStoreFlag` switch to it.
+ - In the nearest-root arm: stat `openspec/specs` and
+ `openspec/changes` as directories. Planning shape → today's path,
+ plus the both-shapes check: a targeted, warning-silent read of
+ `openspec/config.{yaml,yml}` (small local helper: read file, YAML
+ parse in try/catch, pluck `store`) and one stderr warning when a
+ `store` key exists ("openspec/config.yaml declares store 'x', but
+ this directory is a real OpenSpec root; the declaration is
+ ignored.").
+ - Config-only → targeted read: no config or no `store` key → today's
+ nearest behavior; unparseable config or non-string `store` →
+ `invalid_store_pointer` RootSelectionError naming the actual file
+ read; a string → call `resolveStoreRoot(id, globalDataDir,
+ 'declared')` inside a try/catch that **rewraps** any thrown
+ `RootSelectionError`/store error with the message prefix
+ "Declared in : " while preserving `code`, `target`, and
+ an UNPREFIXED `fix` — one wrapper covers all ~7 throw paths
+ including the `fromStoreError` pass-throughs
+ (`root-selection.ts:138,146`), no per-template surgery.
+ - `resolveStoreRoot` gains only a source parameter (default
+ `'store'`; `makeRoot` already takes source as its second arg).
+ - The targeted read is a small exported helper (host it next to
+ `readProjectConfig` in `project-config.ts`, reusing its
+ `.yaml`/`.yml` preference): read file, YAML parse in try/catch,
+ pluck `store` — returning `{value?, malformed?, filePath}`. The
+ both-shapes warning fires only for STRING values (a non-string in
+ a real root is not a pointer; the resilient parser's later
+ drop-warning covers it).
+3. Command-layer predicate adoption: new-change display, status
+ threading, validate/show suppression, archive display paths — each
+ switched from `source === 'store'` to the shared predicate (import
+ from root-selection).
+4. Tests (resolver unit + CLI):
+ - Pointer resolves: source `declared`, store_id set, banner, hints
+ carry `--store`, absolute paths in new-change/archive output, and
+ the show nothing-to-show hint suppresses noun-form suggestions
+ (the eighth consumer).
+ - `--store` beats the pointer, asserting `source === 'store'`.
+ - Real root + pointer: stdout byte-identical to a no-pointer run —
+ same directory, add/remove the line in place, using deterministic
+ commands (`status --json`, `list --json`; normalize or avoid
+ `durationMs`-bearing outputs like validate's) — plus exactly one
+ stderr warning per invocation in human AND JSON modes, JSON stdout
+ clean.
+ - Config-only without pointer (positive assertions — no "today"
+ binary exists to diff): `source === 'nearest'`, path is the
+ config-only dir, zero stderr warnings, registry never consulted.
+ - Malformed pointer (non-string, unparseable YAML) →
+ `invalid_store_pointer` with origin AND a no-write assertion (the
+ pointer dir is untouched); invalid grammar → `invalid_store_id`
+ with the declared prefix; ALL five taxonomy codes prefixed
+ (`unknown_store`, `no_registered_stores`, `unhealthy_store_root`,
+ `store_identity_mismatch`, `invalid_store_id`), each asserting
+ the prefixed `diagnostic.message` and an UNPREFIXED
+ `diagnostic.fix`.
+ - One hop: pointer → store whose config has `store:` → resolves to
+ the first store.
+ - `.yml` origin naming.
+ - No-pointer no-root: stores-hint error byte-identical.
+
+### Checkpoint 2 — init guard, e2e, docs (commit)
+
+1. `src/core/init.ts`: the guard goes **immediately after `validate()`
+ returns `extendMode`** (`init.ts:111`) — before legacy cleanup
+ (`:114`, which mutates project files), migration (`:121`, which
+ writes global config), and the interactive prompts — so the refusal
+ truly creates and changes nothing. Detection: `extendMode` and the
+ shared targeted-read helper reports a string `store:` in a
+ config-only `openspec/`. Test asserts: refusal with the conversion
+ guidance; NO filesystem changes (project tree snapshot identical;
+ global data dir untouched); after removing the line, a rerun
+ scaffolds `openspec/specs/` and `openspec/changes/` normally.
+2. e2e externalized-planning journey (`test/cli-e2e/` or
+ `test/commands/`, runCLI): rootless app repo with pointer →
+ `new change`, `status`, `instructions` (+ references composition:
+ the store's own `references:` appear per 3.1 symmetry), artifact
+ writes, `validate`, `list`, `show`, `archive` — no `--store`
+ anywhere; work lands in the store; pointer dir never gains
+ `specs/`/`changes/` (snapshot); banner + JSON root block assert
+ `declared`.
+3. `docs/cli.md`: "Declaring a default store" subsection next to the
+ references one (the pointer, precedence, the init conversion note).
+4. Full suite; built-binary smoke of the UX transcript.
+
+## Risks And Guardrails
+
+- **Predicate adoption must not change `--store` behavior**: the
+ predicate is true for both sources; every switched site already
+ behaved this way for explicit stores — the suite's existing
+ store-root expectations are the net.
+- **Resolver read cost**: the targeted read happens only when the
+ nearest root exists (one stat for the config file in the
+ planning-shape case; full read only in the config-only case or for
+ the both-shapes warning). Keep it synchronous-fs and tiny; no
+ `readProjectConfig` reuse (its warnings would double-fire — the
+ 3.1-recorded behavior).
+- **`invalid_store_pointer` is a new code**: document it in the slice
+ artifacts; additive to the resolver taxonomy (the capstone
+ agent-contract inventory picks it up).
+- **planning-home untouched**: `findRepoPlanningRootSync` semantics
+ stay; only `resolveOpenSpecRoot` classifies the found dir. The
+ legacy planning-home workspace branch is unaffected.
+- **Byte-identity pins**: the no-pointer baseline assertions must run
+ the SAME fixture twice (with/without the line), not rely on
+ hand-written expectations.
+
+## Done Definition
+
+- All spec acceptance scenarios pass; both checkpoints green on the
+ full suite and committed.
+- The e2e journey proves externalized planning end to end without
+ flags, including the 3.1 composition.
+- Roadmap 3.2 boxes ticked through "Tests pass"; changelog updated;
+ pointer moved to 3.3.
diff --git a/openspec/work/simplify-context-and-workspace-model/slices/declared-store-fallback/spec.md b/openspec/work/simplify-context-and-workspace-model/slices/declared-store-fallback/spec.md
new file mode 100644
index 000000000..983ea51d2
--- /dev/null
+++ b/openspec/work/simplify-context-and-workspace-model/slices/declared-store-fallback/spec.md
@@ -0,0 +1,273 @@
+# Declared Store Fallback Spec (3.2)
+
+## Outcome
+
+A repo whose planning is fully externalized — no local OpenSpec root —
+declares its store once, and every normal command works there without
+`--store` on every invocation. The declaration is a fallback, never an
+override: with any local root present, behavior is byte-identical to
+today, declaration or not. The fixed precedence is finally complete:
+explicit `--store` → nearest local root → declared store (only when no
+local root exists) → today's error with the stores hint.
+
+## Locked Decisions (roadmap, 2026-06-11)
+
+1. **The declaration lives in `openspec/config.yaml`** — the fallback
+ `store:` pointer shares one home with `references:`. The fallback
+ case is a **config-only `openspec/` directory** (no `specs/`, no
+ `changes/`): root detection keeps today's stat-only walk, and two
+ extra stats distinguish a real root from a pointer. A top-level
+ marker file was rejected (`.openspec.yaml` is taken; dot-only
+ filename collisions are an agent hazard).
+2. **Fallback, never override.** A declared store never overrides a
+ local root. With a local root present, behavior is byte-identical
+ with or without the declaration.
+3. **A root with both planning shape and a pointer warns** (the pointer
+ is ignored per precedence). The locked wording said "doctor warns";
+ no project-level doctor command exists, so this slice relocates the
+ warning to resolution stderr — recorded as a reviewed amendment in
+ the roadmap changelog; 3.6 owns the structured health surface.
+4. **The no-root error/hint from slice 1.2 remains** for repos with no
+ declaration.
+5. Without a local root, commands resolve to the declared store and
+ report it **through the existing root banner and JSON root block**.
+
+## Decisions This Spec Makes (autonomous, recorded in the changelog)
+
+1. **Detection mechanics.** The walk is unchanged: nearest ancestor
+ carrying `openspec/` wins and terminates the walk. On that one
+ directory, two stats (`openspec/specs`, `openspec/changes`, each
+ required to be a **directory**) classify it: either present → a
+ real root, today's `nearest` path, byte-identical. Both absent
+ (config-only) → a **warning-silent targeted read** of the config
+ (parse for the `store:` key only — never re-emitting the resilient
+ parser's field warnings during resolution); a `store:` key makes it
+ a pointer and resolution proceeds through the shared store pipeline;
+ **no `store:` key → today's behavior is preserved** (the config-only
+ directory is still a root — freshly initialized minimal roots keep
+ working). The walk never continues past the nearest `openspec/`
+ directory; nesting a pointer under a real root is pathological and
+ out of scope.
+2. **A malformed pointer is an error, never a silent local root.** In a
+ config-only directory, a present-but-malformed `store:` value
+ (non-string, invalid id grammar) or an unparseable config file fails
+ resolution with an origin-naming error (`invalid_store_pointer` for
+ the malformed/unparseable cases; the grammar case flows into the
+ pipeline's `invalid_store_id`) — it must not degrade into scaffolding
+ work next to the pointer. (This deliberately differs from 3.1's
+ drop-with-warning references parsing: a dropped reference degrades
+ an index; a dropped pointer would silently flip the write target.)
+3. **A declared root behaves exactly like a `--store` root except for
+ its `source` — enforced by one predicate.** "Store-selected" means
+ `root.storeId` is set; every consumer currently keyed on
+ `source === 'store'` switches to that predicate: the banner and
+ `withStoreFlag` (`root-selection.ts:339,349`), new-change's absolute
+ path display (`new-change.ts:77`), status's `storeId` threading
+ (`status.ts:106`), validate/show noun-form suggestion suppression —
+ both show branches, including `printNonInteractiveHint`
+ (`validate.ts:136`, `show.ts:138`, `show.ts:160` — the eighth check,
+ found in plan review), and archive's absolute cross-root display
+ paths (`archive.ts:446`).
+ Resolution runs the same `resolveStoreRoot` pipeline via an optional
+ `declaredOrigin` parameter; errors keep their codes and gain a true
+ prefix: "Declared in : " +
+ the existing message. The JSON root block carries
+ `source: "declared"` (additive enum value) plus `store_id`; hint
+ continuity appends `--store ` exactly as for explicit selection
+ (pasted hints work from any cwd). Explicit `--store` always wins and
+ never consults the pointer.
+4. **Pointer resolution is one hop.** A resolved store's own `store:`
+ key is never consulted — no chaining, no recursion (a pointer chain
+ target that is itself config-only simply fails health as
+ `unhealthy_store_root`).
+5. **The both-shapes warning lives in resolution, on stderr** (the
+ recorded amendment of the locked "doctor" wording). When the nearest
+ root has planning shape AND a `store:` pointer, commands emit
+ exactly one stderr warning per invocation — "Warning: declares store 'x', but this directory is a real
+ OpenSpec root; the declaration is ignored." (implementation
+ amendment: the absolute path replaces the spec draft's relative
+ `openspec/config.yaml`, per the absolute-paths quality bar) — in
+ both human and JSON modes (stderr keeps stdout payloads clean).
+ `references:` in the same config keeps working; only the `store:`
+ pointer is ignored.
+6. **The pointer directory is never scaffolded by normal commands; only
+ `openspec init` may convert it, deliberately.** No lifecycle command
+ creates `specs/` or `changes/` inside a config-only pointer
+ directory; work lands in the declared store's root. `openspec init`
+ run in a pointer repo **refuses** with an actionable error ("this
+ repo's planning is externalized to store 'x' (openspec/config.yaml);
+ remove the store: line first to convert it to a local root") instead
+ of silently scaffolding a both-shapes directory.
+
+## User Experience
+
+A team keeps all planning in `team-context`. Their app repo carries
+only a pointer:
+
+```yaml
+# app-repo/openspec/config.yaml
+store: team-context
+```
+
+Every normal command just works there, no flag:
+
+```text
+$ openspec new change billing-rework
+Using OpenSpec root: team-context (/Users/dev/src/team-context)
+Created change 'billing-rework' at /Users/dev/src/team-context/openspec/changes/billing-rework/
+...
+$ openspec status --change billing-rework --json
+{ ..., "root": { "path": "/Users/dev/src/team-context",
+ "source": "declared", "store_id": "team-context" } }
+```
+
+(Note the absolute path: a declared root is cross-root, exactly like
+`--store`, so every displayed path is absolute.)
+
+The pointer never hijacks a real root: in a repo that has its own
+`openspec/specs/`, the same `store:` line changes nothing except one
+stderr warning that it is being ignored. And a teammate without the
+store registered gets the full store-error treatment, told exactly
+where the requirement came from:
+
+```text
+Error: Declared in /Users/dev/src/app-repo/openspec/config.yaml: Unknown store
+'team-context'. No stores are registered. Run openspec store setup team-context
+or openspec store register first.
+```
+
+## Scope
+
+In scope:
+
+- **Config**: `store:` (optional string) in `ProjectConfigSchema` and
+ the resilient parser (`src/core/project-config.ts`).
+- **Resolver**: in `resolveOpenSpecRoot`
+ (`src/core/root-selection.ts:275-313`), after
+ `findRepoPlanningRootSync` returns a directory: the two
+ directory-shape stats; the pointer branch (warning-silent targeted
+ config read, malformed-pointer errors, resolve via the existing
+ `resolveStoreRoot` with the `declaredOrigin` prefix); `source:
+ 'declared'` added to `OpenSpecRootSource` and `RootOutput`; the
+ store-selected predicate (`storeId` set) adopted by all seven
+ source-keyed consumers (decision 3's list); the both-shapes stderr
+ warning.
+- **Init guard**: `openspec init` refuses to scaffold a config-only
+ pointer directory (decision 6), with its own test.
+- **Docs**: extend the `docs/cli.md` "Referencing stores from a
+ project" area with a sibling "Declaring a default store" subsection;
+ add the `store:` bullet to the config keys covered there.
+- **Tests**: resolver unit coverage (pointer resolves; pointer +
+ explicit `--store` precedence; pointer ignored with planning shape +
+ warning; config-only without pointer unchanged; pointer to
+ unknown/unhealthy store errors with origin prefix; invalid pointer id
+ grammar); byte-identity pin (real root with and without `store:` —
+ identical stdout); an e2e externalized-planning journey (rootless app
+ repo with pointer → `new change`, `status`, `instructions`, artifact
+ writes, `validate`, `archive`, all without `--store`; work lands in
+ the store; the pointer dir gains no `specs/`/`changes/`; banner and
+ JSON root block report `declared`).
+
+Out of scope:
+
+- References behavior (3.1, shipped) beyond the natural composition:
+ the declared root's `references:` work exactly as for any resolved
+ root.
+- Remotes (3.3), targets and the repo map (3.4/3.5), the structured
+ health surface (3.6), assembly (4.1).
+- Any change to explicit `--store` behavior, the stores-hint error, or
+ the implicit-root scaffold for directories without `openspec/`.
+- Multi-store pointers, per-command pointer overrides, or pointer
+ inheritance across the walk.
+
+## Acceptance Criteria
+
+### The Fallback Resolves
+
+#### Scenario: Externalized Planning Without Flags
+
+- **GIVEN** a repo whose `openspec/` contains only `config.yaml` with
+ `store: team-context`, and `team-context` registered and healthy
+- **WHEN** `new change`, `status`, `instructions`, `validate`, `list`,
+ `show`, and `archive` run there without `--store`
+- **THEN** every command acts on the store's root
+- **AND** the banner prints `Using OpenSpec root: team-context (…)`
+- **AND** JSON output's root block is
+ `{path: