| name | tech-vision |
| description | Interactive author for the architecture vision template — target, gap, migration, anti-scope, cadence. |
| argument-hint | [project-slug | . | --framework] |
| allowed-tools | Bash, Read, Grep, Glob, Write |
/tech-vision — Interactive Architecture Vision Author
Walks the operator through the existing templates/architecture/vision.md (shipped in #224) section by section — instead of leaving the operator staring at an empty template — so the load-bearing sections (Anti-scope, Current-vs-Target, Migration path) actually get filled in honestly rather than left as aspirational stubs.
The output is a fully populated vision.md ready to commit. Markdown-only — the single graphical element (target-state C4 L1) renders inline via Mermaid on GitHub. No HTML, no SVG, no build step.
Why /tech-vision and not /vision? In a multi-stakeholder portfolio the word "vision" collides with product / company vision documents that Heads of Product and CEOs author in a different shape. The tech- prefix disambiguates this skill as the technical / architecture vision author. The output filename (vision.md) and template path (templates/architecture/vision.md) stay unchanged — only the slash-command carries the prefix.
Design rationale + sub-decisions: AgDR-0028.
| Skill | Role |
|---|
/tech-vision (this skill) | Authors the target-state + migration path — north-star architecture, prose + bulleted horizons |
/c4 | Static topology — current-state system + container diagrams |
/dfd | Data flow — trust boundaries + data classifications (input to /threat-model) |
/sequence (template) | Request-flow walkthroughs (auth handshake, payment flow) |
Path resolution
Read the registry path via portfolio_registry, the per-project docs dir via portfolio_projects_dir, and the template path via portfolio_resolve_template — all from .claude/hooks/_lib-portfolio-paths.sh. Source the helper at the top of any bash block that touches those paths:
source "$(git rev-parse --show-toplevel)/.claude/hooks/_lib-read-config.sh"
source "$(git rev-parse --show-toplevel)/.claude/hooks/_lib-portfolio-paths.sh"
projects_dir=$(portfolio_projects_dir)
template=$(portfolio_resolve_template architecture/vision.md)
Defaults match today's single-fork layout (./projects, ./templates/architecture/vision.md). Adopters in split-portfolio mode override the portfolio.{registry, projects_dir} keys in .claude/project-config.json and may drop a custom template at <private_repo>/custom-templates/architecture/vision.md — the helper resolves whichever mode they're in. See docs/multi-project.md and templates/README.md (custom-templates layer).
Write targets (see me2resh/apexyard#373 + #443): paths documented as projects/<name>/X in this skill are canonical adopter-facing forms — implement them in bash as "${projects_dir}/<name>/X". Never construct from "${PWD}/projects/...", "$(git rev-parse --show-toplevel)/projects/...", or a literal ./projects/... — those break in split-portfolio v2 mode where projects_dir resolves to a sibling repo.
REQUIRED per-block preamble (see #443): Claude executes each bash block as a separate shell invocation. The projects_dir assignment from the Path resolution section above does NOT carry into later blocks. Every bash block that writes to a projects/<name>/X path MUST start with this three-line preamble so it's self-contained:
source "$(git rev-parse --show-toplevel)/.claude/hooks/_lib-read-config.sh"
source "$(git rev-parse --show-toplevel)/.claude/hooks/_lib-portfolio-paths.sh"
projects_dir=$(portfolio_projects_dir)
The Path resolution section's example sources the helper once for documentation purposes; it does not absolve later blocks from sourcing it themselves. Treat each bash fence as a fresh process.
Usage
/tech-vision # interactive — asks which project (or framework-wide)
/tech-vision billing-api # registered project — writes to projects/billing-api/architecture/vision.md
/tech-vision . # treat cwd as the project root
/tech-vision --framework # framework-wide vision — writes to docs/architecture/vision.md
Re-running on an existing vision.md OFFERS (default-no) to overwrite — same UX as /c4, /extract-features, /dfd. Accept-no preserves the existing file; accept-yes seeds each section's prompt with the existing content as the default, so the operator can refresh a single section without rewriting the whole vision.
Output location
Where the file lands depends on where the skill is invoked from and what argument is passed — same split as /c4:
| Invoked from | Arg | Output |
|---|
| Ops fork root | <name> (registered project) | projects/<name>/architecture/vision.md |
| Ops fork root | --framework | docs/architecture/vision.md |
workspace/<name>/ (project clone) | none | projects/<name>/architecture/vision.md (resolved via the ops fork — vision is the ops-fork view of where the project's architecture is going) |
| Anywhere | . | Treat cwd as the project; write to docs/architecture/vision.md inside the cwd |
The split mirrors the existing convention from docs/multi-project.md § "Architecture diagrams".
Process
1. Resolve the target + load the template
source "$(git rev-parse --show-toplevel)/.claude/hooks/_lib-read-config.sh"
source "$(git rev-parse --show-toplevel)/.claude/hooks/_lib-portfolio-paths.sh"
template=$(portfolio_resolve_template architecture/vision.md)
if [ -z "$template" ] || [ ! -f "$template" ]; then
echo "BLOCKED: cannot resolve architecture/vision.md template" >&2
exit 1
fi
If the resolved output file already exists:
projects/<name>/architecture/vision.md already exists (last written {date}).
(k) keep existing — exit without changes
(o) overwrite — start a fresh interview
(r) refresh — start the interview with existing content as defaults (recommended for quarterly review)
>
On k: exit. On o: ignore existing content, proceed to step 2 with empty defaults. On r: parse existing file's sections, use each section's content as the default during the interview.
2. Read the template structure
Parse the resolved template (portfolio_resolve_template architecture/vision.md) to discover its sections. The framework default has seven, in order:
| # | Section | Interview shape |
|---|
| 1 | Scope | Single one-sentence answer |
| 2 | Principles | Repeated prompt: "principle N (or done)" — 5–10 items, skill suggests stopping at 5 unless operator has strong reason for more |
| 3 | Target-state architecture | Multi-line: paste Mermaid C4 L1, OR accept template's placeholder, OR ask operator to run /c4 <project> --level=1 first and paste the output |
| 4 | Current state vs target state | Repeated row prompt: dimension / today / target / gap — 4–8 rows, skill suggests dimensions (Data layer, Auth, Deployment, Observability, Async messaging, Frontend, Secrets management) from the template's worked example as starters |
| 5 | Migration path | Repeated row prompt: quarter / milestone / owner / "done when" — 3–5 milestones |
| 6 | Things we explicitly chose NOT to build (anti-scope) | Repeated prompt: anti-scope item + rationale + "reconsider when" trigger — at least 2 required, skill emphasises this is the load-bearing section |
| 7 | Review cadence | Default quarterly, operator can override (single answer) |
If the operator has overridden the template at <private_repo>/custom-templates/architecture/vision.md, the skill reads that file's sections instead. The interview follows whatever sections the resolved template defines — the section list is not hardcoded.
Discovery: walk the template's ^## headings in order; each heading is one interview section. Use the heading text verbatim in the prompts.
3. Run the interview — section by section, per-section confirm
For each section:
-
Show the section heading and a one-line context (extracted from the template's section intro paragraph, trimmed to one line).
-
Prompt for the section's content. The prompt shape depends on whether the section is single-answer, multi-line, or repeated-row (per the table above). For sections with worked examples in the template, surface 1–2 examples as starting suggestions — never as the answer.
-
Show the assembled section as it will appear in the final file.
-
Confirm:
Section "Principles" — looks good?
(y) accept and continue to next section
(e) edit — restart this section
(s) skip — leave section as template default (NOT recommended for Anti-scope or Migration path)
(q) quit — don't write anything
>
If the operator picks s on Anti-scope or Migration path, re-prompt with a stronger warning:
Anti-scope is the load-bearing section that prevents the vision from rotting
into aspirational filler. Skipping it produces a half-filled-in stub of the
exact kind /tech-vision exists to prevent.
Really skip? [y/N]
Default N. Other sections can be skipped without warning (Scope, Principles, Review cadence have sane template defaults).
4. Show the assembled doc + final confirm
After all sections, show the fully assembled vision as it will be written. Final prompt:
Vision assembled — {N} sections, {M} principles, {K} anti-scope items, {Q} migration milestones.
(y) write to <output-path>
(e) restart at section: 1 / 2 / 3 / 4 / 5 / 6 / 7 → re-prompt for that section
(q) quit — don't write
>
5. Write the file + lint the Mermaid
Write the assembled markdown to the resolved output path. The Target-state section may contain a ```mermaid C4 L1 block (pasted by the operator or generated via /c4). Validate every Mermaid block in the file via the shared lint:
SKILL_DIR="$(dirname "$(realpath "$0")")"
"$SKILL_DIR/lint.sh" "$vision_out" || lint_rc=$?
Wraps _lib-mermaid-lint.sh — graceful-degrades when Node / npx is unavailable (exit 3, advisory only). Exit 1 (parse error) → ask the operator whether to fix the Target-state block by hand or re-run with --skip-lint. Exit 3 → one-line warning, proceed.
End the file with the apexyard-skill footer convention (same as /c4, /dfd, /extract-features):
---
_Generated by `/tech-vision` on YYYY-MM-DD. Re-run quarterly (or after a significant architecture decision) — `/tech-vision <project>` with the `r` (refresh) option preserves the existing content as defaults._
Print a one-line summary:
✓ Vision written: projects/<name>/architecture/vision.md
Sections: 7 · Principles: 5 · Anti-scope: 3 · Migration milestones: 4
Reviewed quarterly per § "Review cadence" — next review: {Q+1}
6. Suggest follow-ups
Surface the natural next-steps the operator likely wants:
- C4 current-state diagrams — if no
projects/<name>/architecture/{context,container}.md exists, suggest /c4 <project> to capture the as-is system topology (the vision's Target-state section describes where we're going; /c4 documents where we are today).
- Migration ticket for the Q1 milestone —
/migration if it touches schema, /feature otherwise.
- AgDRs for any technical decisions implied by the migration path —
/decide for each.
- Quarterly review reminder — surface the cadence so the operator knows to re-run
/tech-vision <project> (refresh mode) in 3 months.
Rules
- Operator authors the content; the skill structures the prompts. Never fill in section bodies on the operator's behalf — the worked examples in the template are starting suggestions, not auto-accepted answers.
- Never auto-overwrite — existing
vision.md requires explicit o or r. The file may have been hand-edited; clobbering silently is the worst-case failure.
- Per-section confirm is mandatory — the operator iterates one section at a time, not by re-running the whole interview.
- Anti-scope cannot be skipped silently — the second-warning prompt is the load-bearing UX that turns the "stub vision" failure mode into a deliberate decision.
- Follow the resolved template's section list — do not hardcode the framework default's seven sections. An adopter with a custom template (5 sections, 9 sections) gets an interview that matches their template.
- Footer signature is mandatory — every generated file ends with the
Generated by /tech-vision on YYYY-MM-DD line so future readers know how to refresh it.
- Markdown-only output — no HTML, no SVG, no JSON sidecar. The vision IS the source of truth.
- Refuse if no template resolves —
portfolio_resolve_template returning empty means the framework default is missing too; stop with a clear error rather than producing an empty file.
When to use this
| Trigger | Use /tech-vision? |
|---|
| Quarterly architecture review for a registered project | Yes — re-run with r (refresh) to preserve last quarter's content as defaults |
New project just adopted via /handover; need to set north-star architecture | Yes — fresh run, all 7 sections from scratch |
| Tech Lead onboarding wants to see "what's the target state" | Read the existing projects/<name>/architecture/vision.md — the skill produced it for exactly this reader |
| Drawing a current-state container diagram | No — use /c4 |
| Drawing a data-flow diagram | No — use /dfd |
| Recording a single technical decision (library choice, framework upgrade) | No — use /decide (writes an AgDR, much narrower scope) |
| Multi-team vision (one team's vision feeds another's) | No — out of scope for v1; one vision per system / domain |
| Product / company vision (audience, market, business goals) | No — /tech-vision is the technical / architecture vision; product vision belongs in a separate PRD / strategy doc |
Anti-patterns
- Don't auto-generate vision content from a problem statement — the model doesn't have the operator's architecture context. The skill structures the interview; the operator authors the answers.
- Don't chain
/c4 automatically from inside /tech-vision (v1 scope). /c4 produces a current-state diagram; the vision's Target-state section is by definition NOT today's code. Suggest /c4 as a follow-up if no current-state diagram exists; let the operator paste a target-state Mermaid block inline.
- Don't ship without an Anti-scope section. The skill enforces this via the second-warning prompt; the rationale section in the output documents WHY each item was declined and WHEN to reconsider — without those the section is filler.
- Don't treat the vision as a once-and-done artefact. The template includes a Review cadence (default quarterly). Re-run with
r (refresh) at each review; preserve content for unchanged sections, update the rest.
Out of scope (v1)
- Chaining
/c4 to scaffold the target-state diagram — accept inline Mermaid in v1; chain in a v1.x follow-up if operators ask.
- HTML / SVG / interactive rendering — markdown-only by design.
- A
/tech-vision-review companion that re-prompts every section quarterly — the idempotent refresh mode handles this.
- Vision enforcement (Rex checking whether new code matches the vision) — that's a
/decide + AgDR concern, not a vision-doc one.
- Multi-team vision composition — one vision per system / domain.
- Vision-doc trend tracking across quarterly reviews — use
git log projects/<name>/architecture/vision.md and the AgDR history instead.
Part of ApexYard — multi-project SDLC framework for Claude Code · MIT.