Deprecate inactive skills
This commit is contained in:
100
deprecated/prototype/LOGIC.md
Normal file
100
deprecated/prototype/LOGIC.md
Normal 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.
|
||||
Reference in New Issue
Block a user