Deprecate inactive skills

This commit is contained in:
2026-08-26 17:01:23 -04:00
parent 9a1d21da4d
commit 9195cf3ee7
21 changed files with 1 additions and 58 deletions

View File

@@ -0,0 +1,100 @@
# Logic Prototype
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.
## When this is the right shape
- "I'm not sure if this state machine handles the edge case where X then Y."
- "Does this data model actually let me represent the case where..."
- "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**.
If the question is "what should this look like" — wrong branch. Use [UI.md](UI.md).
## Process
### 1. State the question
Before writing code, write down what state model and what question you're prototyping.
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, 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
Use whatever the host project uses. 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.
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
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 right shape depends on the question:
- **A pure reducer** — `(state, action) => state`. 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 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.
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.
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
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.
Each frame has two parts, in this order:
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.
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:
1. **Initialise state** — a single in-memory object/struct. Render the first frame on start.
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.
4. **Loop until quit.**
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
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.
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. Evaluate it
In HITL mode, give the user the run command.
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" because those expose bugs in the idea.
Add actions when the feedback needs them.
In AFK mode, run the command yourself and drive the hard cases that answer the stated question.
Record the observations that support the verdict.
Done when the evaluator can exercise the model and the prototype exposes every state transition needed to reach a verdict.
## Production mapping
When the shared [SKILL](SKILL.md) permits production work, lift the validated reducer, machine, or function set into the real module.
Keep the TUI shell on the throwaway branch.
## Anti-patterns
- **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.

View File

@@ -0,0 +1,88 @@
---
name: prototype
description: Build a throwaway prototype to answer a design question. Use when the user wants to sanity-check whether a state model or logic feels right, or explore what a UI should look like.
---
# Prototype
A prototype is **throwaway code that answers one question**.
The question decides the branch.
The interaction mode decides who reaches the verdict.
Use AFK mode when the question has objective observable criteria the agent can test end to end.
Use HITL mode when the verdict depends on human judgment, taste, or UX feel.
## 1. Pick a branch
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 or state model feel right?**
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?**
Follow [`UI.md`](UI.md) to build several radically different UI variants on one route with a URL-controlled switcher.
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.
Done when exactly one branch and one design question govern the prototype.
## Common rules
- **Throwaway from day one.**
Locate the code close to where it would be used, but name it so nobody mistakes it for production.
Follow the project's routing and source-layout conventions rather than inventing a new top-level structure.
- **One command to run.**
Use the project's existing task runner so the user does not need to remember a path or setup sequence.
- **No persistence by default.**
Keep state in memory unless persistence is the question being tested.
Use an unmistakably disposable database or local file when that question requires one.
- **Skip polish.**
Add no tests, production-grade error handling, speculative abstractions, or unrelated cleanup.
- **Surface state.**
Show the full relevant state after every Logic action or UI variant switch.
## 2. Build and reach a verdict
Follow the selected branch through its evaluation step.
In HITL mode, hand the prototype to the user and iterate in response to their feedback.
In AFK mode, run the prototype yourself and evaluate the objective observations against the question.
Do not treat a runnable prototype as the result.
The result is the verdict that answers the design question.
Done when the verdict is explicit, or when the prototype establishes that it did not resolve the question.
## 3. Capture the primary source
Commit the complete prototype to a throwaway branch outside main.
The branch is the primary source.
Resolve the artifact destination before naming the file.
When the caller provides a destination directory, use it exactly.
Otherwise, default to `$(xdg-user-dir DOCUMENTS)/ai-artifacts/projects/<project>` when the AI artifacts vault is available, where `<project>` is the lowercase basename of the current working directory.
If that vault is unavailable, fall back to `./docs` in the current project.
Create the destination directory only when needed.
Before choosing a filename, read the destination's `AGENTS.md`.
Use the naming convention declared there, or infer it from nearby artifacts when the file delegates naming to local context.
Do not assume a counter, numeric prefix, slug shape, or artifact-type suffix unless the destination convention requires it.
If no convention can be determined, choose the least surprising lowercase descriptive Markdown filename and state that the destination did not define a naming convention.
When the caller provides an existing artifact path, use it exactly, do not allocate a filename, and complete that artifact in place.
Otherwise, allocate any identifier required by the destination convention and 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.
When the resolved file is an existing artifact, preserve its workflow metadata and complete the result in that file.
The branch-appropriate evidence is:
- 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 destination convention.
## 4. Fold in the decision when permitted
A planning-only caller 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.

124
deprecated/prototype/UI.md Normal file
View File

@@ -0,0 +1,124 @@
# UI Prototype
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.
If the question is about logic/state rather than what something looks like — wrong branch. Use [LOGIC.md](LOGIC.md).
## When this is the right shape
- "What should this page look like?"
- "I want to see a few options for this dashboard before committing."
- "Try a different layout for the settings screen."
- Any time the user would otherwise spend a day picking between three vague mockups in their head.
## 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 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)
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.
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.
### 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.
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.
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.
In both sub-shapes the floating bottom bar is identical.
## Process
### 1. State the question and pick N
Default to **3 variants**. 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:
> "Three variants of the settings page, switchable via `?variant=`, on the existing `/settings` route."
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
Draft each variant. Hold each one 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).
- 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. 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
Create a single switcher component on the route:
```tsx
// pseudo-code — adapt to the project's framework
const variant = searchParams.get('variant') ?? 'A';
return (
<>
{variant === 'A' && <VariantA {...data} />}
{variant === 'B' && <VariantB {...data} />}
{variant === 'C' && <VariantC {...data} />}
<PrototypeSwitcher variants={['A','B','C']} current={variant} />
</>
);
```
For sub-shape A (existing page): keep all the existing data fetching above the switcher; only the rendered subtree changes per variant.
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
A small fixed-position bar at the bottom-centre of the screen with three pieces:
- **Left arrow** — cycles to the previous variant (wraps around).
- **Variant label** — shows the current variant key and, if the variant exports a name, that name too. e.g. `B — Sidebar layout`.
- **Right arrow** — cycles forward (wraps around).
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.
- Keyboard: `←` and `→` arrow keys also cycle. 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.
- 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. 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. Evaluate it
In HITL mode, surface the URL and the `?variant=` keys.
The user flips through the variants and may combine elements rather than choosing one unchanged.
In AFK mode, open the URL yourself, compare every variant against the stated objective criteria, and record the observations that support the verdict.
Use HITL instead when the decision depends on taste, product judgment, or UX feel.
Done when the evaluator can compare every variant in its host context and the prototype exposes enough contrast to reach a verdict.
## Production mapping
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 B** — promote the winner to a real route and drop the throwaway route and switcher from main.
## Anti-patterns
- **Variants that differ only in colour or copy.** That's a tweak, not a prototype. Real variants disagree about structure.
- **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.
- **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.