feat(skills): adapt planning skills to artifact workflow
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
# Logic Prototype
|
# Logic Prototype
|
||||||
|
|
||||||
A tiny interactive terminal app that lets the user drive a state model by hand.
|
A tiny interactive terminal app that lets the user drive a state model by hand. Use this when the question is about **business logic, state transitions, or data shape** — the kind of thing that looks reasonable on paper but only feels wrong once you push it through real cases.
|
||||||
Use this when the question is about **business logic, state transitions, or data shape** — the kind of thing that looks reasonable on paper but only feels wrong once you push it through real cases.
|
|
||||||
|
|
||||||
## When this is the right shape
|
## When this is the right shape
|
||||||
|
|
||||||
@@ -10,105 +9,89 @@ Use this when the question is about **business logic, state transitions, or data
|
|||||||
- "I want to feel out what the API should look like before writing it."
|
- "I want to feel out what the API should look like before writing it."
|
||||||
- Anything where the user wants to **press buttons and watch state change**.
|
- Anything where the user wants to **press buttons and watch state change**.
|
||||||
|
|
||||||
If the question is "what should this look like" — wrong branch.
|
If the question is "what should this look like" — wrong branch. Use [UI.md](UI.md).
|
||||||
Use [UI.md](UI.md).
|
|
||||||
|
|
||||||
## Process
|
## Process
|
||||||
|
|
||||||
### 1. State the question
|
### 1. State the question
|
||||||
|
|
||||||
Before writing code, write down what state model and what question you're prototyping.
|
Before writing code, write down what state model and what question you're prototyping.
|
||||||
One paragraph, in the prototype's README or a comment at the top of the file.
|
Use one paragraph in the prototype's README or a comment at the top of the file.
|
||||||
A logic prototype that answers the wrong question is pure waste — make the question explicit so it can be checked later, whether the user is watching now or returning to it AFK.
|
A logic prototype that answers the wrong question is pure waste, so make the question explicit enough to check later whether the user is watching now or returning to it AFK.
|
||||||
|
|
||||||
|
Done when the prototype states one concrete logic question and the model being tested.
|
||||||
|
|
||||||
### 2. Pick the language
|
### 2. Pick the language
|
||||||
|
|
||||||
Use whatever the host project uses.
|
Use whatever the host project uses. If the project has no obvious runtime (e.g. a docs repo), ask.
|
||||||
If the project has no obvious runtime (e.g. a docs repo), ask.
|
|
||||||
|
|
||||||
Match the project's existing conventions for tooling — don't add a new package manager or runtime just for the prototype.
|
Match the project's existing conventions for tooling.
|
||||||
|
Don't add a new package manager or runtime just for the prototype.
|
||||||
|
|
||||||
|
Done when the prototype has a runnable host-project language and toolchain without introducing a new runtime convention.
|
||||||
|
|
||||||
### 3. Isolate the logic in a portable module
|
### 3. Isolate the logic in a portable module
|
||||||
|
|
||||||
Put the actual logic — the bit that's answering the question — behind a small, pure interface that could be lifted out and dropped into the real codebase later.
|
Put the actual logic — the bit that's answering the question — behind a small, pure interface that could be lifted out and dropped into the real codebase later. The TUI around it is throwaway; the logic module shouldn't be.
|
||||||
The TUI around it is throwaway.
|
|
||||||
The logic module shouldn't be.
|
|
||||||
|
|
||||||
The right shape depends on the question:
|
The right shape depends on the question:
|
||||||
|
|
||||||
- **A pure reducer** — `(state, action) => state`.
|
- **A pure reducer** — `(state, action) => state`. Good when actions are discrete events and state is a single value.
|
||||||
Good when actions are discrete events and state is a single value.
|
- **A state machine** — explicit states and transitions. Good when "which actions are even legal right now" is part of the question.
|
||||||
- **A state machine** — explicit states and transitions.
|
- **A small set of pure functions** over a plain data type. Good when there's no implicit current state — just transformations.
|
||||||
Good when "which actions are even legal right now" is part of the question.
|
|
||||||
- **A small set of pure functions** over a plain data type.
|
|
||||||
Good when there's no implicit current state — just transformations.
|
|
||||||
- **A class or module with a clear method surface** when the logic genuinely owns ongoing internal state.
|
- **A class or module with a clear method surface** when the logic genuinely owns ongoing internal state.
|
||||||
|
|
||||||
Pick whichever shape best fits the question being asked, *not* whichever is easiest to wire to a TUI.
|
Pick whichever shape best fits the question being asked, *not* whichever is easiest to wire to a TUI. Keep it pure: no I/O, no terminal code, no `console.log` for control flow. The TUI imports it and calls into it; nothing flows the other direction.
|
||||||
Keep it pure: no I/O, no terminal code, no `console.log` for control flow.
|
|
||||||
The TUI imports it and calls into it.
|
|
||||||
Nothing flows the other direction.
|
|
||||||
|
|
||||||
This is what makes the prototype useful past its own lifetime: when the question's been answered, the validated reducer / machine / function set can be lifted into the real module on its own.
|
This is what makes the prototype useful past its own lifetime.
|
||||||
|
When the question is answered, the validated reducer, machine, or function set can be lifted into the real module on its own.
|
||||||
|
|
||||||
|
Done when all tested logic lives behind one portable, pure interface and the TUI depends on it in only one direction.
|
||||||
|
|
||||||
### 4. Build the smallest TUI that exposes the state
|
### 4. Build the smallest TUI that exposes the state
|
||||||
|
|
||||||
Build it as a **lightweight TUI** — on every tick, clear the screen (`console.clear()` / `print("\033[2J\033[H")` / equivalent) and re-render the whole frame.
|
Build it as a **lightweight TUI** — on every tick, clear the screen (`console.clear()` / `print("\033[2J\033[H")` / equivalent) and re-render the whole frame. The user should always see one stable view, not an ever-growing scrollback.
|
||||||
The user should always see one stable view, not an ever-growing scrollback.
|
|
||||||
|
|
||||||
Each frame has two parts, in this order:
|
Each frame has two parts, in this order:
|
||||||
|
|
||||||
1. **Current state**, pretty-printed and diff-friendly (one field per line, or formatted JSON).
|
1. **Current state**, pretty-printed and diff-friendly (one field per line, or formatted JSON). Use **bold** for field names or section headers and **dim** for less important context (timestamps, IDs, derived values). Native ANSI escape codes are fine — `\x1b[1m` bold, `\x1b[2m` dim, `\x1b[0m` reset. No need to pull in a styling library unless one is already in the project.
|
||||||
Use **bold** for field names or section headers and **dim** for less important context (timestamps, IDs, derived values).
|
2. **Keyboard shortcuts**, listed at the bottom: `[a] add user [d] delete user [t] tick clock [q] quit`. Bold the key, dim the description, or vice-versa — whatever reads cleanly.
|
||||||
Native ANSI escape codes are fine — `\x1b[1m` bold, `\x1b[2m` dim, `\x1b[0m` reset.
|
|
||||||
No need to pull in a styling library unless one is already in the project.
|
|
||||||
2. **Keyboard shortcuts**, listed at the bottom: `[a] add user [d] delete user [t] tick clock [q] quit`.
|
|
||||||
Bold the key, dim the description, or vice-versa — whatever reads cleanly.
|
|
||||||
|
|
||||||
Behaviour:
|
Behaviour:
|
||||||
|
|
||||||
1. **Initialise state** — a single in-memory object/struct.
|
1. **Initialise state** — a single in-memory object/struct. Render the first frame on start.
|
||||||
Render the first frame on start.
|
|
||||||
2. **Read one keystroke (or one line)** at a time, dispatch to a handler that mutates state.
|
2. **Read one keystroke (or one line)** at a time, dispatch to a handler that mutates state.
|
||||||
3. **Re-render** the full frame after every action — don't append, replace.
|
3. **Re-render** the full frame after every action — don't append, replace.
|
||||||
4. **Loop until quit.**
|
4. **Loop until quit.**
|
||||||
|
|
||||||
The whole frame should fit on one screen.
|
The whole frame should fit on one screen.
|
||||||
|
|
||||||
|
Done when every available action re-renders a complete one-screen view of the current state and shortcuts.
|
||||||
|
|
||||||
### 5. Make it runnable in one command
|
### 5. Make it runnable in one command
|
||||||
|
|
||||||
Add a script to the project's existing task runner (`package.json` scripts, `Makefile`, `justfile`, `pyproject.toml`).
|
Add a script to the project's existing task runner (`package.json` scripts, `Makefile`, `justfile`, `pyproject.toml`). The user should run `pnpm run <prototype-name>` or equivalent — never need to remember a path.
|
||||||
The user should run `pnpm run <prototype-name>` or equivalent — never need to remember a path.
|
|
||||||
|
|
||||||
If the host project has no task runner, just put the command at the top of the prototype's README.
|
If the host project has no task runner, put the command at the top of the prototype's README.
|
||||||
|
|
||||||
|
Done when a fresh user can launch the prototype with one documented command.
|
||||||
|
|
||||||
### 6. Hand it over
|
### 6. Hand it over
|
||||||
|
|
||||||
Give the user the run command.
|
Give the user the run command.
|
||||||
They'll drive it themselves.
|
They drive it themselves.
|
||||||
The interesting moments are when they say "wait, that shouldn't be possible" or "huh, I assumed X would be different" — those are the bugs in the _idea_, which is the whole point.
|
The interesting moments are when they say "wait, that shouldn't be possible" or "huh, I assumed X would be different" because those expose bugs in the idea.
|
||||||
If they want new actions added, add them.
|
Add actions when the feedback needs them.
|
||||||
Prototypes evolve.
|
|
||||||
|
|
||||||
### 7. Capture the answer and the prototype
|
Done when the user can exercise the model and the prototype exposes every state transition needed to reach a verdict.
|
||||||
|
|
||||||
Once the prototype has answered its question, capture the answer, then capture the prototype the way the [SKILL](SKILL.md) describes.
|
## Production mapping
|
||||||
When the caller permits implementation, the validated reducer, machine, or function set lifts into the real module as the absorbed decision.
|
|
||||||
A planning-only caller leaves the real module unchanged.
|
When the shared [SKILL](SKILL.md) permits production work, lift the validated reducer, machine, or function set into the real module.
|
||||||
The TUI shell rides along to the throwaway branch that keeps the prototype as a primary source.
|
Keep the TUI shell on the throwaway branch.
|
||||||
|
|
||||||
## Anti-patterns
|
## Anti-patterns
|
||||||
|
|
||||||
- **Don't add tests.**
|
- **Don't generalise.** No "what if we wanted to support X later." The prototype answers one question.
|
||||||
A prototype that needs tests is no longer a prototype.
|
- **Don't blur the logic and the TUI together.** If the reducer / state machine references `console.log`, prompts, or terminal escape codes, it's no longer portable. Keep the TUI as a thin shell over a pure module.
|
||||||
- **Don't wire it to the real database.**
|
- **Don't ship the TUI shell into production.** The shell is optimised for being driven by hand from a terminal. The logic module behind it is the bit worth keeping.
|
||||||
Use an in-memory store unless the question is specifically about persistence.
|
|
||||||
- **Don't generalise.**
|
|
||||||
No "what if we wanted to support X later."
|
|
||||||
The prototype answers one question.
|
|
||||||
- **Don't blur the logic and the TUI together.**
|
|
||||||
If the reducer / state machine references `console.log`, prompts, or terminal escape codes, it's no longer portable.
|
|
||||||
Keep the TUI as a thin shell over a pure module.
|
|
||||||
- **Don't ship the TUI shell into production.**
|
|
||||||
The shell is optimised for being driven by hand from a terminal.
|
|
||||||
The logic module behind it is the bit worth keeping.
|
|
||||||
|
|||||||
@@ -5,43 +5,70 @@ description: Build a throwaway prototype to answer a design question. Use when t
|
|||||||
|
|
||||||
# Prototype
|
# Prototype
|
||||||
|
|
||||||
A prototype is **throwaway code that answers a question**.
|
A prototype is **throwaway code that answers one question**.
|
||||||
The question decides the shape.
|
The question decides the branch.
|
||||||
|
|
||||||
## Pick a branch
|
## 1. Pick a branch
|
||||||
|
|
||||||
Identify which question is being answered — from the user's prompt, the surrounding code, or by asking if the user is around:
|
Identify the question from the user's prompt and surrounding code.
|
||||||
|
Ask when it remains genuinely ambiguous and the user is reachable.
|
||||||
|
|
||||||
- **"Does this logic / state model feel right?"** → [LOGIC.md](LOGIC.md).
|
- **Does this logic or state model feel right?**
|
||||||
Build a tiny interactive terminal app that pushes the state machine through cases that are hard to reason about on paper.
|
Follow [`LOGIC.md`](LOGIC.md) to build a tiny interactive terminal app that pushes the model through hard-to-reason-about cases.
|
||||||
- **"What should this look like?"** → [UI.md](UI.md).
|
- **What should this look like?**
|
||||||
Generate several radically different UI variations on a single route, switchable via a URL search param and a floating bottom bar.
|
Follow [`UI.md`](UI.md) to build several radically different UI variants on one route with a URL-controlled switcher.
|
||||||
|
|
||||||
The two branches produce very different artifacts — getting this wrong wastes the whole prototype.
|
When the user is unavailable, default to Logic for a backend module and UI for a page or component, then state the assumption in the prototype.
|
||||||
If the question is genuinely ambiguous and the user isn't reachable, default to whichever branch better matches the surrounding code (a backend module → logic, a page or component → UI) and state the assumption at the top of the prototype.
|
|
||||||
|
|
||||||
## Rules that apply to both
|
Done when exactly one branch and one design question govern the prototype.
|
||||||
|
|
||||||
1. **Throwaway from day one, and clearly marked as such.**
|
## Common rules
|
||||||
Locate the prototype code close to where it will actually be used (next to the module or page it's prototyping for) so context is obvious — but name it so a casual reader can see it's a prototype, not production.
|
|
||||||
For throwaway UI routes, obey whatever routing convention the project already uses.
|
- **Throwaway from day one.**
|
||||||
Don't invent a new top-level structure.
|
Locate the code close to where it would be used, but name it so nobody mistakes it for production.
|
||||||
2. **One command to run.**
|
Follow the project's routing and source-layout conventions rather than inventing a new top-level structure.
|
||||||
Whatever the project's existing task runner supports — `pnpm <name>`, `python <path>`, `bun <path>`, etc.
|
- **One command to run.**
|
||||||
The user must be able to start it without thinking.
|
Use the project's existing task runner so the user does not need to remember a path or setup sequence.
|
||||||
3. **No persistence by default.**
|
- **No persistence by default.**
|
||||||
State lives in memory.
|
Keep state in memory unless persistence is the question being tested.
|
||||||
Persistence is the thing the prototype is _checking_, not something it should depend on.
|
Use an unmistakably disposable database or local file when that question requires one.
|
||||||
If the question explicitly involves a database, hit a scratch DB or a local file with a clear "PROTOTYPE — wipe me" name.
|
- **Skip polish.**
|
||||||
4. **Skip the polish.**
|
Add no tests, production-grade error handling, speculative abstractions, or unrelated cleanup.
|
||||||
No tests, no error handling beyond what makes the prototype _runnable_, no abstractions.
|
- **Surface state.**
|
||||||
The point is to learn something fast.
|
Show the full relevant state after every Logic action or UI variant switch.
|
||||||
5. **Surface the state.**
|
|
||||||
After every action (logic) or on every variant switch (UI), print or render the full relevant state so the user can see what changed.
|
## 2. Build and reach a verdict
|
||||||
6. **Capture it when done.**
|
|
||||||
When the caller permits implementation, fold any validated decision into the real code.
|
Follow the selected branch through its handover step and iterate on the prototype in response to the user's feedback.
|
||||||
A planning-only caller such as Wayfinder stops at the verdict.
|
Do not treat a runnable prototype as the result.
|
||||||
Commit the prototype itself to a throwaway branch, out of main, as a **primary source**.
|
The result is the verdict that answers the design question.
|
||||||
Write a Prototype artifact under `$(xdg-user-dir DOCUMENTS)/ai-artifacts/projects/<project>/`, where `<project>` is the lowercase basename of the current working directory, following the vault's `AGENTS.md`.
|
|
||||||
Include the question, a context pointer to the branch, run instructions, and the verdict, plus screenshots and useful code snippets where they help preserve the result.
|
Done when the user has reached an explicit verdict or stated that the prototype did not resolve the question.
|
||||||
The main branch keeps only a validated decision that the caller permitted the skill to fold in.
|
|
||||||
|
## 3. Capture the primary source
|
||||||
|
|
||||||
|
Commit the complete prototype to a throwaway branch outside main.
|
||||||
|
The branch is the primary source.
|
||||||
|
|
||||||
|
Resolve the AI artifacts vault through `$(xdg-user-dir DOCUMENTS)/ai-artifacts` and read its `AGENTS.md` before writing.
|
||||||
|
Use the lowercase basename of the current working directory as the project.
|
||||||
|
|
||||||
|
When the caller provides an allocated filename and `parent`, use them exactly and do not advance `.counter`.
|
||||||
|
Create only the Prototype artifact and leave the parent artifact unchanged.
|
||||||
|
Otherwise, allocate the next vault-sequence identifier and name the artifact `<NNN>-<project>-<subject-slug>-prototype.md`.
|
||||||
|
Include `parent` only when an earlier artifact directly caused the prototype.
|
||||||
|
|
||||||
|
The Prototype artifact links the throwaway branch and preserves the question, run instructions, verdict, and branch-appropriate evidence:
|
||||||
|
|
||||||
|
- UI evidence uses screenshots.
|
||||||
|
- Logic evidence uses useful code snippets and, where needed, a short interaction transcript.
|
||||||
|
|
||||||
|
Done when the complete prototype is committed outside main and exactly one Prototype artifact preserves the result according to the vault convention.
|
||||||
|
|
||||||
|
## 4. Fold in the decision when permitted
|
||||||
|
|
||||||
|
A planning-only caller such as Wayfinder stops after the verdict and leaves production code unchanged.
|
||||||
|
Otherwise, fold the validated decision into production only when the caller permits implementation.
|
||||||
|
Follow the selected branch's **Production mapping** and keep all other throwaway code out of main.
|
||||||
|
|
||||||
|
Done when production is unchanged for a planning-only run, or contains only the permitted validated decision for an implementation run.
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
# UI Prototype
|
# UI Prototype
|
||||||
|
|
||||||
Generate **several radically different UI variations** on a single route, switchable from a floating bottom bar.
|
Generate **several radically different UI variations** on a single route, switchable from a floating bottom bar. The user flips between variants in the browser, picks one (or steals bits from each), then throws the rest away.
|
||||||
The user flips between variants in the browser, picks one (or steals bits from each), then throws the rest away.
|
|
||||||
|
|
||||||
If the question is about logic/state rather than what something looks like — wrong branch.
|
If the question is about logic/state rather than what something looks like — wrong branch. Use [LOGIC.md](LOGIC.md).
|
||||||
Use [LOGIC.md](LOGIC.md).
|
|
||||||
|
|
||||||
## When this is the right shape
|
## When this is the right shape
|
||||||
|
|
||||||
@@ -15,32 +13,21 @@ Use [LOGIC.md](LOGIC.md).
|
|||||||
|
|
||||||
## Two sub-shapes — strongly prefer sub-shape A
|
## Two sub-shapes — strongly prefer sub-shape A
|
||||||
|
|
||||||
A UI prototype is much easier to judge when it's **butting up against the rest of the app** — real header, real sidebar, real data, real density.
|
A UI prototype is much easier to judge when it's **butting up against the rest of the app** — real header, real sidebar, real data, real density. A throwaway route on its own is a vacuum: every variant looks fine in isolation. Default to sub-shape A whenever there's a plausible existing page to host the variants. Only reach for sub-shape B if the prototype genuinely has no nearby home.
|
||||||
A throwaway route on its own is a vacuum: every variant looks fine in isolation.
|
|
||||||
Default to sub-shape A whenever there's a plausible existing page to host the variants.
|
|
||||||
Only reach for sub-shape B if the prototype genuinely has no nearby home.
|
|
||||||
|
|
||||||
### Sub-shape A — adjustment to an existing page (preferred)
|
### Sub-shape A — adjustment to an existing page (preferred)
|
||||||
|
|
||||||
The route already exists.
|
The route already exists. Variants are rendered **on the same route**, gated by a `?variant=` URL search param. The existing data fetching, params, and auth all stay — only the rendering swaps. This is the default; pick it unless there's a specific reason not to.
|
||||||
Variants are rendered **on the same route**, gated by a `?variant=` URL search param.
|
|
||||||
The existing data fetching, params, and auth all stay — only the rendering swaps.
|
|
||||||
This is the default.
|
|
||||||
Pick it unless there's a specific reason not to.
|
|
||||||
|
|
||||||
If the prototype is for something that doesn't yet have a page but *would naturally live inside one* (a new section of the dashboard, a new card on the settings screen, a new step in an existing flow) — that's still sub-shape A.
|
If the prototype is for something that doesn't yet have a page but *would naturally live inside one* (a new section of the dashboard, a new card on the settings screen, a new step in an existing flow) — that's still sub-shape A. Mount the variants inside the host page.
|
||||||
Mount the variants inside the host page.
|
|
||||||
|
|
||||||
### Sub-shape B — a new page (last resort)
|
### Sub-shape B — a new page (last resort)
|
||||||
|
|
||||||
Only use this when the thing being prototyped genuinely has no existing page to live inside — e.g. an entirely new top-level surface, or a flow that can't be embedded anywhere sensible.
|
Only use this when the thing being prototyped genuinely has no existing page to live inside — e.g. an entirely new top-level surface, or a flow that can't be embedded anywhere sensible.
|
||||||
|
|
||||||
Create a **throwaway route** following whatever routing convention the project already uses — don't invent a new top-level structure.
|
Create a **throwaway route** following whatever routing convention the project already uses — don't invent a new top-level structure. Name it so it's obviously a prototype (e.g. include the word `prototype` in the path or filename). Same `?variant=` pattern.
|
||||||
Name it so it's obviously a prototype (e.g. include the word `prototype` in the path or filename).
|
|
||||||
Same `?variant=` pattern.
|
|
||||||
|
|
||||||
Before committing to sub-shape B, sanity-check: is there really no existing page this could be embedded in?
|
Before committing to sub-shape B, sanity-check: is there really no existing page this could be embedded in? An empty route hides design problems that a populated one would expose.
|
||||||
An empty route hides design problems that a populated one would expose.
|
|
||||||
|
|
||||||
In both sub-shapes the floating bottom bar is identical.
|
In both sub-shapes the floating bottom bar is identical.
|
||||||
|
|
||||||
@@ -48,8 +35,7 @@ In both sub-shapes the floating bottom bar is identical.
|
|||||||
|
|
||||||
### 1. State the question and pick N
|
### 1. State the question and pick N
|
||||||
|
|
||||||
Default to **3 variants**.
|
Default to **3 variants**. More than 5 stops being radically different and starts being noise — cap there.
|
||||||
More than 5 stops being radically different and starts being noise — cap there.
|
|
||||||
|
|
||||||
Write down the plan in one line, in the prototype's location or a top-of-file comment:
|
Write down the plan in one line, in the prototype's location or a top-of-file comment:
|
||||||
|
|
||||||
@@ -57,18 +43,19 @@ Write down the plan in one line, in the prototype's location or a top-of-file co
|
|||||||
|
|
||||||
This works whether the user is here to push back or not.
|
This works whether the user is here to push back or not.
|
||||||
|
|
||||||
|
Done when the prototype states one concrete UI question, its host route, and a variant count from three through five.
|
||||||
|
|
||||||
### 2. Generate radically different variants
|
### 2. Generate radically different variants
|
||||||
|
|
||||||
Draft each variant.
|
Draft each variant. Hold each one to:
|
||||||
Hold each one to:
|
|
||||||
|
|
||||||
- The page's purpose and the data it has access to.
|
- The page's purpose and the data it has access to.
|
||||||
- The project's component library / styling system (TailwindCSS, shadcn, MUI, plain CSS, whatever).
|
- The project's component library / styling system (TailwindCSS, shadcn, MUI, plain CSS, whatever).
|
||||||
- A clear exported component name, e.g. `VariantA`, `VariantB`, `VariantC`.
|
- A clear exported component name, e.g. `VariantA`, `VariantB`, `VariantC`.
|
||||||
|
|
||||||
Variants must be **structurally different** — different layout, different information hierarchy, different primary affordance, not just different colours.
|
Variants must be **structurally different** — different layout, different information hierarchy, different primary affordance, not just different colours. Three slightly-tweaked card grids isn't a UI prototype, it's wallpaper. If two drafts come out too similar, redo one with explicit "do not use a card grid" guidance.
|
||||||
Three slightly-tweaked card grids isn't a UI prototype, it's wallpaper.
|
|
||||||
If two drafts come out too similar, redo one with explicit "do not use a card grid" guidance.
|
Done when every variant materially differs in layout, information hierarchy, and primary affordance while using the project's existing design system.
|
||||||
|
|
||||||
### 3. Wire them together
|
### 3. Wire them together
|
||||||
|
|
||||||
@@ -87,11 +74,12 @@ return (
|
|||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
For sub-shape A (existing page): keep all the existing data fetching above the switcher.
|
For sub-shape A (existing page): keep all the existing data fetching above the switcher; only the rendered subtree changes per variant.
|
||||||
Only the rendered subtree changes per variant.
|
|
||||||
|
|
||||||
For sub-shape B (new page): the throwaway route under `/prototype/<name>` mounts the same switcher.
|
For sub-shape B (new page): the throwaway route under `/prototype/<name>` mounts the same switcher.
|
||||||
|
|
||||||
|
Done when one route renders every variant from the URL parameter without duplicating data loading.
|
||||||
|
|
||||||
### 4. Build the floating switcher
|
### 4. Build the floating switcher
|
||||||
|
|
||||||
A small fixed-position bar at the bottom-centre of the screen with three pieces:
|
A small fixed-position bar at the bottom-centre of the screen with three pieces:
|
||||||
@@ -103,43 +91,31 @@ A small fixed-position bar at the bottom-centre of the screen with three pieces:
|
|||||||
Behaviour:
|
Behaviour:
|
||||||
|
|
||||||
- Clicking an arrow updates the URL search param (use the framework's router — `router.replace` on Next, `navigate` on React Router, etc) so the variant is shareable and reload-stable.
|
- Clicking an arrow updates the URL search param (use the framework's router — `router.replace` on Next, `navigate` on React Router, etc) so the variant is shareable and reload-stable.
|
||||||
- Keyboard: `←` and `→` arrow keys also cycle.
|
- Keyboard: `←` and `→` arrow keys also cycle. Don't intercept arrow keys when an `<input>`, `<textarea>`, or `[contenteditable]` is focused.
|
||||||
Don't intercept arrow keys when an `<input>`, `<textarea>`, or `[contenteditable]` is focused.
|
|
||||||
- Visually distinct from the page (e.g. high-contrast pill, subtle shadow) so it's obviously not part of the design being evaluated.
|
- Visually distinct from the page (e.g. high-contrast pill, subtle shadow) so it's obviously not part of the design being evaluated.
|
||||||
- Hidden in production builds — gate on `process.env.NODE_ENV !== 'production'` or an equivalent check, so a stray prototype merge can't ship the bar to users.
|
- Hidden in production builds — gate on `process.env.NODE_ENV !== 'production'` or an equivalent check, so a stray prototype merge can't ship the bar to users.
|
||||||
|
|
||||||
Put the switcher in a single shared component so both sub-shapes can reuse it.
|
Put the switcher in a single shared component so both sub-shapes can reuse it. Locate it wherever shared UI lives in the project.
|
||||||
Locate it wherever shared UI lives in the project.
|
|
||||||
|
Done when mouse and keyboard controls cycle through every shareable variant without intercepting text-editing keys, and the switcher cannot render in production.
|
||||||
|
|
||||||
### 5. Hand it over
|
### 5. Hand it over
|
||||||
|
|
||||||
Surface the URL (and the `?variant=` keys).
|
Surface the URL and the `?variant=` keys.
|
||||||
The user will flip through whenever they get to it.
|
The user flips through the variants and may combine elements rather than choosing one unchanged.
|
||||||
The interesting feedback is usually **"I want the header from B with the sidebar from C"** — that's the actual design they want.
|
|
||||||
|
|
||||||
### 6. Capture the answer and clean up
|
Done when the user can compare every variant in its host context and the prototype exposes enough contrast to reach a verdict.
|
||||||
|
|
||||||
Once a variant has won, capture the answer — which variant and why — then capture the prototype the way the [SKILL](SKILL.md) describes.
|
## Production mapping
|
||||||
When the caller permits implementation, fold the winner into the real code and move the rest onto the throwaway branch, not into main:
|
|
||||||
|
When the shared [SKILL](SKILL.md) permits production work, keep the full variant set on the throwaway branch and apply the verdict as follows:
|
||||||
|
|
||||||
- **Sub-shape A** — fold the winner into the existing page and drop the losing variants and switcher from main.
|
- **Sub-shape A** — fold the winner into the existing page and drop the losing variants and switcher from main.
|
||||||
- **Sub-shape B** — promote the winning variant to a real route and drop the throwaway route and switcher from main.
|
- **Sub-shape B** — promote the winner to a real route and drop the throwaway route and switcher from main.
|
||||||
|
|
||||||
A planning-only caller leaves the real route unchanged.
|
|
||||||
The full set of variants is the primary source, so it lands on the throwaway branch, not the bin — variant components and the switcher left in the main branch rot fast and confuse the next reader.
|
|
||||||
|
|
||||||
## Anti-patterns
|
## Anti-patterns
|
||||||
|
|
||||||
- **Variants that differ only in colour or copy.**
|
- **Variants that differ only in colour or copy.** That's a tweak, not a prototype. Real variants disagree about structure.
|
||||||
That's a tweak, not a prototype.
|
- **Sharing too much code between variants.** A shared `<Header>` is fine; a shared `<Layout>` defeats the point. Each variant should be free to throw out the layout.
|
||||||
Real variants disagree about structure.
|
- **Wiring variants to real mutations.** Read-only prototypes are fine. If a variant needs to mutate, point it at a stub — the question is "what should this look like", not "does the backend work".
|
||||||
- **Sharing too much code between variants.**
|
- **Promoting the prototype directly to production.** The variant code was written under prototype constraints (no tests, minimal error handling). Rewrite it properly when you fold it in.
|
||||||
A shared `<Header>` is fine.
|
|
||||||
A shared `<Layout>` defeats the point.
|
|
||||||
Each variant should be free to throw out the layout.
|
|
||||||
- **Wiring variants to real mutations.**
|
|
||||||
Read-only prototypes are fine.
|
|
||||||
If a variant needs to mutate, point it at a stub — the question is "what should this look like", not "does the backend work".
|
|
||||||
- **Promoting the prototype directly to production.**
|
|
||||||
The variant code was written under prototype constraints (no tests, minimal error handling).
|
|
||||||
Rewrite it properly when you fold it in.
|
|
||||||
|
|||||||
@@ -1,14 +1,46 @@
|
|||||||
---
|
---
|
||||||
name: research
|
name: research
|
||||||
description: Investigate a question against high-trust primary sources and capture the findings as a Markdown file in the AI artifacts vault. Use when the user wants a topic researched, docs or API facts gathered, or reading legwork delegated to a background agent.
|
description: Investigate a question against high-trust primary sources and capture the cited findings as a Research artifact in the AI artifacts vault. Use when a topic needs documentation, API, specification, source-code, or other reading legwork.
|
||||||
---
|
---
|
||||||
|
|
||||||
Spin up a **background agent** to do the research, so you keep working while it reads.
|
# Research
|
||||||
|
|
||||||
Its job:
|
Investigate one question and preserve the findings in one cited Research artifact.
|
||||||
|
Run in the current process.
|
||||||
|
Isolation and concurrency belong to the caller.
|
||||||
|
|
||||||
1. Investigate the question against **primary sources** — official docs, source code, specs, first-party APIs — not a secondary write-up of them.
|
## 1. Resolve the artifact
|
||||||
Follow every claim back to the source that owns it.
|
|
||||||
2. Write the findings to a single Markdown file, citing each claim's source.
|
Resolve the vault through `$(xdg-user-dir DOCUMENTS)/ai-artifacts` and read its `AGENTS.md` before writing.
|
||||||
3. Save it under `$(xdg-user-dir DOCUMENTS)/ai-artifacts/projects/<project>/`, where `<project>` is the lowercase basename of the current working directory.
|
Use the lowercase basename of the current working directory as the project and create its flat `projects/<project>/` directory only when needed.
|
||||||
Read the vault's `AGENTS.md` and follow its artifact conventions.
|
|
||||||
|
When the caller provides an allocated filename and `parent`, use them exactly and do not advance `.counter`.
|
||||||
|
Create only the Research artifact and leave the parent artifact unchanged.
|
||||||
|
|
||||||
|
Otherwise, allocate the next vault-sequence identifier through `.counter` and name the artifact `<NNN>-<project>-<subject-slug>-research.md`.
|
||||||
|
Include `parent` only when an earlier artifact directly caused the research.
|
||||||
|
|
||||||
|
Done when one authoritative output path and its metadata are settled according to the vault convention.
|
||||||
|
|
||||||
|
## 2. Investigate the question
|
||||||
|
|
||||||
|
Use primary sources such as official documentation, specifications, source code, and first-party APIs rather than relying on secondary accounts.
|
||||||
|
Follow every substantive claim back to the primary source that owns it.
|
||||||
|
Use secondary material only to discover primary sources.
|
||||||
|
When no primary source establishes a needed claim, record that limitation instead of presenting the claim as settled.
|
||||||
|
|
||||||
|
Done when the question is answered as far as primary evidence permits and every substantive claim has an owning source or an explicit evidence gap.
|
||||||
|
|
||||||
|
## 3. Write the Research artifact
|
||||||
|
|
||||||
|
Write the findings to the resolved Markdown file and follow the vault's artifact conventions.
|
||||||
|
Keep the question, findings, limitations, and citations sufficient for a future reader to evaluate the result without reconstructing the research session.
|
||||||
|
Do not create a source dump or research log.
|
||||||
|
|
||||||
|
Done when exactly one Research artifact exists at the resolved path and every substantive claim in it cites its source.
|
||||||
|
|
||||||
|
## 4. Return the result
|
||||||
|
|
||||||
|
Report the artifact path and a concise statement of what the research established or could not establish.
|
||||||
|
|
||||||
|
Done when the caller can locate the artifact and understand whether the question was resolved.
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ Create `projects/<project>/` when a new project first needs a map.
|
|||||||
Keep the project directory flat.
|
Keep the project directory flat.
|
||||||
|
|
||||||
Allocate every new artifact through the vault-root `.counter`.
|
Allocate every new artifact through the vault-root `.counter`.
|
||||||
The coordinating Wayfinder agent reconciles duplicate identifiers after concurrent workers return.
|
|
||||||
|
|
||||||
## Names
|
## Names
|
||||||
|
|
||||||
@@ -29,6 +28,12 @@ The map is the effort's root artifact and has no `parent`.
|
|||||||
It is an index rather than the store for ticket resolutions.
|
It is an index rather than the store for ticket resolutions.
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
|
---
|
||||||
|
status: open
|
||||||
|
tags:
|
||||||
|
- wayfinder/map
|
||||||
|
---
|
||||||
|
|
||||||
# <effort name>
|
# <effort name>
|
||||||
|
|
||||||
## Destination
|
## Destination
|
||||||
@@ -56,6 +61,8 @@ It is an index rather than the store for ticket resolutions.
|
|||||||
<work consciously ruled beyond the destination>
|
<work consciously ruled beyond the destination>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Map status is `open` while any live ticket or fog remains and `complete` when neither remains.
|
||||||
|
|
||||||
The Frontier is a derived navigation index.
|
The Frontier is a derived navigation index.
|
||||||
Ticket metadata is authoritative.
|
Ticket metadata is authoritative.
|
||||||
Repair the Frontier whenever it is missing, stale, or inconsistent with ticket state.
|
Repair the Frontier whenever it is missing, stale, or inconsistent with ticket state.
|
||||||
@@ -118,15 +125,24 @@ Use `PI_SESSION_ID` when available and an equivalent harness session identifier
|
|||||||
Claims do not expire automatically.
|
Claims do not expire automatically.
|
||||||
The acting agent uses the available context to recover an abandoned claim.
|
The acting agent uses the available context to recover an abandoned claim.
|
||||||
|
|
||||||
Only resolved tickets appear under Resolutions so far.
|
Only resolved tickets appear under **Resolutions so far**.
|
||||||
An out-of-scope ticket is closed and linked from Out of scope with the reason it lies beyond the destination.
|
An out-of-scope ticket is closed and linked from **Out of scope** with the reason it lies beyond the destination.
|
||||||
|
|
||||||
## Results
|
## Results
|
||||||
|
|
||||||
A Grill or Task ticket stores its canonical result under a `## Resolution` section in that ticket.
|
A Grill or Task ticket stores its canonical result under a `## Resolution` section in that ticket.
|
||||||
Research and Prototype tickets leave their question in the ticket and store results in one or more child artifacts whose `parent` points to the ticket.
|
Research and Prototype tickets leave their question in the ticket and store the result in a child artifact whose `parent` points to the ticket.
|
||||||
The called skill creates those result artifacts but does not edit the ticket or map.
|
|
||||||
The coordinating Wayfinder agent integrates the artifacts, marks the ticket resolved, and updates the map.
|
When invoking `research` or `prototype`, provide the project artifact directory, allocated filename, and ticket wikilink that the result must use as its `parent`.
|
||||||
|
The called skill creates the result artifact but does not edit the ticket or map.
|
||||||
|
The coordinating Wayfinder agent validates the returned artifact, marks the ticket resolved, and updates the map.
|
||||||
|
If a called skill cannot honor this artifact contract, leave the ticket unresolved and record the incompatibility instead of silently storing the result elsewhere.
|
||||||
|
|
||||||
Navigate the artifact journey forward by finding every note whose `parent` links to the current artifact.
|
Navigate the artifact journey forward by finding every note whose `parent` links to the current artifact.
|
||||||
Do not duplicate those relationships through per-artifact Next sections.
|
Do not duplicate those relationships through per-artifact Next sections.
|
||||||
|
|
||||||
|
## Concurrent writes
|
||||||
|
|
||||||
|
Re-read every shared artifact immediately before editing it.
|
||||||
|
After concurrent workers return, detect duplicate identifiers, preserve pre-existing artifacts, renumber current outputs, update their wikilinks, and advance `.counter` as required by the vault convention.
|
||||||
|
Recompute the Frontier only after returned artifacts and ticket states have been reconciled.
|
||||||
|
|||||||
@@ -1,36 +1,46 @@
|
|||||||
---
|
---
|
||||||
name: wayfinder
|
name: wayfinder
|
||||||
description: Plan work too large and uncertain for one agent session as a durable map of decision tickets, then resolve one frontier ticket at a time until the route to the destination is clear.
|
description: Plan a huge chunk of work that exceeds one agent session as a durable map of decision tickets, then resolve them one at a time until the way to the destination is clear.
|
||||||
disable-model-invocation: true
|
disable-model-invocation: true
|
||||||
---
|
---
|
||||||
|
|
||||||
# wayfinder
|
# Wayfinder
|
||||||
|
|
||||||
A loose idea has arrived that is too large for one agent session and too foggy to plan directly.
|
A loose idea has arrived that is too large for one agent session and wrapped in fog.
|
||||||
Wayfinding charts the decisions needed to reach a **destination**, then works those decisions one at a time until the route is clear.
|
Wayfinding charts the way to a **destination** rather than charging at it.
|
||||||
|
It creates a durable map of questions whose resolutions are decisions, findings, prototypes, or completed prerequisites rather than slices of the destination work.
|
||||||
|
|
||||||
Read [`ARTIFACTS.md`](ARTIFACTS.md) before charting or working a map.
|
Read [`ARTIFACTS.md`](ARTIFACTS.md) before charting or working a map.
|
||||||
It is the sole source for how maps, tickets, claims, blocking, results, and the Frontier live in the AI artifacts vault.
|
It is the single source of truth for how maps, tickets, claims, blocking, resolutions, and the Frontier live in the AI artifacts vault.
|
||||||
|
|
||||||
## Plan, don't do
|
## Plan, don't do
|
||||||
|
|
||||||
Wayfinder plans by default.
|
Wayfinder plans by default.
|
||||||
The map is complete when nothing remains to decide before someone performs the destination work.
|
The map is complete when nothing remains to decide before someone performs the destination work.
|
||||||
The urge to implement the destination usually marks the edge of the map.
|
The urge to implement the destination usually marks the edge of the map and the time to hand off.
|
||||||
An effort may explicitly permit execution in its Notes, but otherwise preserve resolutions and hand off rather than deliver the destination.
|
An effort may explicitly permit execution in its Notes, but otherwise preserve resolutions rather than deliver the destination.
|
||||||
|
|
||||||
|
The destination varies by effort and shapes every ticket.
|
||||||
|
It may be a spec to hand off, a decision to lock before planning, or a change whose route must be understood before implementation.
|
||||||
|
|
||||||
|
## Refer by name
|
||||||
|
|
||||||
|
Refer to every map and ticket by its human-readable title as a wikilink, never by a bare identifier, filename, or slug.
|
||||||
|
The artifact identifier remains inside the wikilink without standing in for the name.
|
||||||
|
|
||||||
## Ticket types
|
## Ticket types
|
||||||
|
|
||||||
Every ticket is either **HITL**, worked through a live exchange with the human, or **AFK**, driven by the agent.
|
Every ticket is either **HITL**, worked through a live exchange with the human, or **AFK**, driven by the agent.
|
||||||
A HITL ticket never resolves by having the agent speak for the human.
|
A HITL ticket only resolves through that exchange.
|
||||||
|
The agent never speaks for the human's side.
|
||||||
|
|
||||||
- **Research** (AFK): Investigate knowledge outside the current working directory through the `research` skill.
|
- **Research** (AFK): Investigate documentation, third-party APIs, or resources outside the current working directory through `research`.
|
||||||
- **Prototype** (HITL): Create concrete Logic or UI code to react to through the `prototype` skill.
|
The called skill creates a Research artifact and Wayfinder integrates it.
|
||||||
Within Wayfinder, stop at the verdict rather than folding the result into production.
|
- **Prototype** (HITL): Raise the fidelity of a logic, state-model, or UI decision through `prototype`.
|
||||||
- **Grill** (HITL): Resolve a decision through the `grill` skill.
|
The called skill creates a Prototype artifact and Wayfinder integrates it after the human reaches a verdict.
|
||||||
|
- **Grill** (HITL): Resolve a decision through `grill`.
|
||||||
This is the default ticket type.
|
This is the default ticket type.
|
||||||
- **Task** (AFK or HITL): Perform prerequisite work that must happen before a decision can be made.
|
- **Task** (AFK or HITL): Perform prerequisite work that must happen before a decision can be made.
|
||||||
The required capability is specific to the action.
|
|
||||||
The agent performs it where possible and otherwise gives the human a precise checklist.
|
The agent performs it where possible and otherwise gives the human a precise checklist.
|
||||||
|
|
||||||
A Task earns its place by unblocking a decision, not by delivering part of the destination.
|
A Task earns its place by unblocking a decision, not by delivering part of the destination.
|
||||||
@@ -38,13 +48,21 @@ A Task earns its place by unblocking a decision, not by delivering part of the d
|
|||||||
## Fog of war
|
## Fog of war
|
||||||
|
|
||||||
The map is deliberately incomplete.
|
The map is deliberately incomplete.
|
||||||
**Not yet specified** holds in-scope questions that are visible but cannot yet be stated precisely enough to ticket.
|
Beyond its tickets lies the **fog of war**, where in-scope questions are visible but cannot yet be stated precisely because they depend on unresolved questions.
|
||||||
Create a ticket as soon as its question is precise, even when it is blocked and cannot yet be answered.
|
Resolving a ticket clears the fog ahead of it and graduates newly precise questions into tickets.
|
||||||
A fog entry may graduate into several tickets or disappear when an earlier resolution changes the route.
|
|
||||||
|
Use this test:
|
||||||
|
|
||||||
|
- Create a ticket when the question is precise now, even if it is blocked.
|
||||||
|
- Keep an entry under **Not yet specified** when the question cannot yet be phrased precisely.
|
||||||
|
|
||||||
|
Do not pre-slice fog into speculative tickets.
|
||||||
|
One fog entry may become several tickets or disappear as the frontier advances.
|
||||||
|
|
||||||
The destination fixes scope.
|
The destination fixes scope.
|
||||||
Work beyond it belongs in **Out of scope**, never in fog.
|
Work beyond it belongs under **Out of scope**, never under **Not yet specified**.
|
||||||
If an existing ticket proves to be beyond the destination, close it as out of scope and link it from that section rather than recording it as a resolution.
|
When an existing ticket proves to be beyond the destination, mark it out of scope and link it from that section with the reason.
|
||||||
|
Do not record a scope boundary as a resolution on the route.
|
||||||
|
|
||||||
## Select the mode
|
## Select the mode
|
||||||
|
|
||||||
@@ -56,42 +74,50 @@ Never resolve more than one non-Research ticket in a session.
|
|||||||
## Chart the map
|
## Chart the map
|
||||||
|
|
||||||
1. **Name the destination.**
|
1. **Name the destination.**
|
||||||
Invoke `grill` to settle what reaching the end of this effort looks like.
|
Invoke `grill` to settle what this map is finding its way toward.
|
||||||
Done when the destination states the spec, decision, or change the map is finding its way toward and fixes its scope.
|
Done when the destination names the spec, decision, or change at the end of the effort and fixes its scope.
|
||||||
2. **Map breadth-first.**
|
2. **Map the frontier breadth-first.**
|
||||||
Invoke `grill` again to fan out across the whole space, identifying precise open questions, blocking relationships, and fog without drilling into any one answer.
|
Invoke `grill` again to fan out across the whole space without resolving any one branch in depth.
|
||||||
If this surfaces no fog and the route fits one session, stop and ask how the user wants to proceed instead of creating a map.
|
Surface every currently precise question, its blocking relationships, and the remaining fog.
|
||||||
Done when every visible in-scope uncertainty is either a precise ticket question or an honest fog entry.
|
If no fog remains and the whole route fits one session, stop and ask how the user wants to proceed instead of creating a map.
|
||||||
|
Done when every visible in-scope uncertainty has exactly one home as a precise ticket question or an honest fog entry.
|
||||||
3. **Create the map and tickets.**
|
3. **Create the map and tickets.**
|
||||||
Create the map first, then every currently precise ticket, then wire `blocked-by` relationships in a second pass according to `ARTIFACTS.md`.
|
Create the map first, then every currently precise ticket, then wire blocking relationships in a second pass according to [`ARTIFACTS.md`](ARTIFACTS.md).
|
||||||
Done when the map is the effort root, every precise question has one ticket, every known blocking edge is represented, and the Frontier is current.
|
Done when the map is the effort root, every precise question has one ticket, every known blocking edge is represented, and the Frontier is current.
|
||||||
4. **Dispatch Research.**
|
4. **Dispatch Research.**
|
||||||
Invoke `research` for each Research ticket using whatever isolation or concurrency the caller provides.
|
Invoke `research` for each Research ticket using whatever isolation or concurrency the caller provides.
|
||||||
Let the coordinating Wayfinder agent integrate returned Research artifacts according to `ARTIFACTS.md`.
|
Integrate each returned Research artifact according to [`ARTIFACTS.md`](ARTIFACTS.md).
|
||||||
Done when every dispatched Research result has been integrated or every Research ticket that could not run remains open with the reason visible.
|
Leave a ticket open with the reason visible when its Research run cannot complete.
|
||||||
5. Stop without resolving a HITL ticket.
|
Done when every dispatched result is integrated or every incomplete Research ticket records why it remains open.
|
||||||
|
5. **Stop.**
|
||||||
|
Stop without resolving a HITL ticket.
|
||||||
|
Done when charting has created and dispatched the visible route without consuming its human decision work.
|
||||||
|
|
||||||
## Work through the map
|
## Work through the map
|
||||||
|
|
||||||
1. **Orient.**
|
1. **Orient.**
|
||||||
Read the map at low resolution and reconcile its derived Frontier against ticket metadata.
|
Read the map at low resolution rather than loading every ticket.
|
||||||
Done when the destination, standing Notes, prior resolutions, fog, scope boundary, and current Frontier agree with the artifacts.
|
Reconcile its derived Frontier against ticket metadata.
|
||||||
|
Done when the destination, Notes, prior resolutions, fog, scope boundary, and current Frontier agree with the artifacts.
|
||||||
2. **Claim one ticket.**
|
2. **Claim one ticket.**
|
||||||
Use the user-named ticket when it is actionable, otherwise claim the first Frontier ticket.
|
Use the user-named ticket when it is actionable.
|
||||||
Persist the claim before doing its work.
|
Otherwise take the first Frontier ticket in artifact-identifier order.
|
||||||
Done when exactly one open, unblocked ticket records this session's claim.
|
Persist the claim before doing any work.
|
||||||
|
Done when exactly one unblocked ticket records this session's claim with `status: claimed`.
|
||||||
3. **Resolve by type.**
|
3. **Resolve by type.**
|
||||||
Invoke `research`, `prototype`, or `grill` for those ticket types.
|
Invoke `research`, `prototype`, or `grill` for the corresponding ticket type.
|
||||||
Perform a Task through the capability or human checklist it requires.
|
Perform a Task through the capability or human checklist it requires.
|
||||||
Zoom into related artifacts only as needed rather than loading the whole effort.
|
Load related artifacts only when needed.
|
||||||
Done when the ticket's question has a resolution or the prerequisite Task is complete.
|
Done when the question has a resolution or the prerequisite Task is complete.
|
||||||
4. **Record the resolution.**
|
4. **Record the resolution.**
|
||||||
Persist the result, resolve the ticket, and add its gist and links under the map's Resolutions so far.
|
Persist the canonical result, resolve the ticket, and append its one-line gist and artifact links under the map's **Resolutions so far** according to [`ARTIFACTS.md`](ARTIFACTS.md).
|
||||||
Done when the resolution lives in exactly one canonical place and the map points to it without restating it.
|
Done when the resolution lives in exactly one canonical place and the map points to it without restating it.
|
||||||
5. **Advance the frontier.**
|
5. **Advance the frontier.**
|
||||||
Create tickets surfaced by the resolution according to `ARTIFACTS.md`.
|
Create tickets surfaced by the resolution and wire their blockers.
|
||||||
Graduate newly precise fog, remove invalidated tickets, move beyond-destination work out of scope, and recompute the Frontier.
|
Graduate newly precise fog, remove invalidated tickets, move beyond-destination work out of scope, and recompute the Frontier.
|
||||||
Done when every newly visible question has exactly one home and the map matches all current ticket metadata.
|
Re-read shared artifacts before each write because other sessions may edit the effort concurrently.
|
||||||
|
Done when every newly visible question has exactly one home and the map agrees with all current ticket metadata.
|
||||||
Expect concurrent sessions to edit the same effort.
|
6. **Complete or stop.**
|
||||||
Re-read shared artifacts before each write and reconcile collisions through the vault convention.
|
When no unresolved tickets or fog remain, mark the map complete and stop for an explicit handoff instruction.
|
||||||
|
Otherwise stop.
|
||||||
|
Done when the map records its current lifecycle state and no destination work has begun without permission.
|
||||||
|
|||||||
Reference in New Issue
Block a user