diff --git a/CHANGELOG.md b/CHANGELOG.md index 609b212..ff397ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- **`/ratchet:map` — the pre-build fog gate.** The loop had no pre-build ambiguity pass: + `/ratchet:cut` attacks assumptions, but nothing walked the codebase's tacit knowledge + before building. `/ratchet:map` walks high-uncertainty work (aperture A3–A4, unfamiliar + terrain, "I'll know it when I see it" taste, reference ports) through the four + unknown-quadrants — known knowns (settled ground with `file:line` evidence), known + unknowns (one blast-radius-ordered question at a time), unknown knowns (tacit taste + surfaced by putting concrete options in front of the user), unknown unknowns (a swept + landmine field) — and hands over one durable four-quadrant map, a build plan, and a + copy-paste implementation prompt before any code is written. CLI-backed + (`artifact kind:"unknown-map"`, decisions, assumptions, open loops), so its open items + drain `ratchet score confidence` until closed; no schema change. Method grafted from + dzhng/skills `explore-unknowns`, expressed in ratchet's own vocabulary. Aperture + auto-routing (scoring the task straight into the map) is deferred to a follow-up. + ## [0.5.0] - 2026-07-04 — Receipt 0.2 gated proof; 0.3 gated the *seam* of that proof; 0.4 metered the *depth* of the loop. @@ -213,7 +229,7 @@ Initial public release. - Single-plugin marketplace manifest so the repo installs directly as a Claude Code plugin. - Zero-dependency smoke test suites for the state engine and the evolution helpers. -[Unreleased]: https://github.com/TheLucidTech/torque-loop/compare/v0.4.0...HEAD +[Unreleased]: https://github.com/TheLucidTech/torque-loop/compare/v0.5.0...HEAD [0.4.0]: https://github.com/TheLucidTech/torque-loop/compare/v0.3.0...v0.4.0 [0.3.0]: https://github.com/TheLucidTech/torque-loop/compare/v0.2.0...v0.3.0 [0.2.0]: https://github.com/TheLucidTech/torque-loop/compare/v0.1.0...v0.2.0 diff --git a/README.md b/README.md index 346ae5f..2d66d15 100644 --- a/README.md +++ b/README.md @@ -187,6 +187,7 @@ when it isn't. In Codex, ask it to use the matching Torque Loop skill, for examp | --- | --- | | `/ratchet:ignite` | Run the full consequence loop on any messy task. | | `/ratchet:lock` | Convert vague input into a locked, executable target. | +| `/ratchet:map` | Map the fog before building — walk the four unknown-quadrants, hand over a durable map. | | `/ratchet:auction` | Rank the real blockers by leverage; pick the one bottleneck. | | `/ratchet:cut` | Attack the hidden assumptions before you invest. | | `/ratchet:mechanism` | Name the one mechanism under a confusing situation. | @@ -201,6 +202,13 @@ when it isn't. In Codex, ask it to use the matching Torque Loop skill, for examp | `/ratchet:status` | Read the current ratchet state. | | `/ratchet:loop` | Repeat build → attack → patch → compile until it holds. | +> **When to reach for `/ratchet:map`.** High-uncertainty work — aperture **A3–A4**, +> unfamiliar terrain, reference-implementation ports, or "I'll know it when I see it" +> taste. Walk the four unknown-quadrants (known knowns · known unknowns · unknown knowns · +> unknown unknowns) and hand over the map *before* `/ratchet:build`; at **A4**, stop after +> the map until constraints are locked. What you deliver is the map, not a build — a wrong +> assumption caught on the map is a one-line fix; caught mid-build it is a rewrite. + ### Specialized | Command | Purpose | diff --git a/reference/PROMPTS.md b/reference/PROMPTS.md index d594c2d..9be3185 100644 --- a/reference/PROMPTS.md +++ b/reference/PROMPTS.md @@ -13,6 +13,7 @@ prompt is the load-bearing intent — fix the skill. | --- | --- | | `/ratchet:ignite` | Master Ignition Prompt (consequence engine) | | `/ratchet:lock` | 1 · The Target Is Not The Topic | +| `/ratchet:map` | The Fog Map (four-quadrant unknowns walk) | | `/ratchet:auction` | 2 · The Friction Auction | | `/ratchet:cut` | 3 · The Assumption Guillotine | | `/ratchet:mechanism` | 4 · The Mechanism Knife | @@ -124,6 +125,45 @@ Choose the target and make it operational. --- +## The Fog Map → `/ratchet:map` + +The pre-build twin of the target lock: where `/ratchet:lock` says *infer and move*, the +Fog Map says *don't build on a high-blast-radius guess*. Run it when uncertainty earns it +(aperture A3–A4, unfamiliar terrain, "know it when I see it" taste, a reference port). +Method grafted from the `explore-unknowns` skill; expressed here in ratchet's own +vocabulary — general mechanism, own words — the same graft discipline as the aperture dial. + +```text +Map the fog before you build. + +Given this task and its codebase: + +[PASTE CONTEXT] + +Do not build yet. Scan the terrain first — existing, half-built, and reverted work — +then walk four quadrants in order, naming the current one: + +1. Known knowns — state the settled ground, each fact cited to file:line. Mark every + assumption separately and say you will treat it as true until I correct it. +2. Known unknowns — ask ONE question at a time, widest-impact first. Give lettered options + with a recommended answer so I react in a few characters. Close each by: + user answer | territory (you researched it, show question + finding) | OPEN (+ what unblocks it). +3. Unknown knowns — surface my tacit taste and context. Don't make me imagine it; put + something concrete in front of me to react to (sample data, a throwaway mock, competing + design directions). Record what each reaction reveals. +4. Unknown unknowns — sweep for landmines: wrong-by-default data, stale denormalizations, + unwritten conventions, prior attempts that were abandoned or rolled back (and the reason + they died), latent bugs on this path. Each as a card: evidence (file:line) → why it bites + → what it changes → decided | OPEN | sharp-edge. + +Then hand over ONE page: the four-quadrant map (OPEN items stay on the map, not in chat), +a tweakable build plan ordered by what might change, and a copy-paste implementation prompt. + +What you deliver is the map, not a build. Stop when I have it. +``` + +--- + ## 2 · The Friction Auction → `/ratchet:auction` ```text diff --git a/skills/map/SKILL.md b/skills/map/SKILL.md new file mode 100644 index 0000000..82b5c22 --- /dev/null +++ b/skills/map/SKILL.md @@ -0,0 +1,138 @@ +--- +name: map +description: Map the fog before you build. Use when uncertainty is high (aperture A3–A4), the terrain is unfamiliar, the taste is "I'll know it when I see it", or you are porting a reference implementation. Walks the task through four unknown-quadrants — known knowns (settled ground with file evidence), known unknowns (one blast-radius-ordered question at a time), unknown knowns (tacit taste surfaced by putting something concrete in front of the user), and unknown unknowns (a swept landmine field) — then hands over one durable four-quadrant map, a tweakable build plan, and a copy-paste implementation prompt. What you deliver is the map, not a build; you do not write code until it is handed over. +--- + +# /ratchet:map — the fog-of-war gate + +When uncertainty is high, the expensive mistake is a confident build in the wrong +direction. `/ratchet:lock` says: infer the missing value, name the assumption, move. That +is correct for low-uncertainty work. This command is its counterweight for the +high-uncertainty case — it maps the terrain *before* the build, so a wrong assumption is a +one-line correction on paper instead of a rewrite three PRs deep. **What you deliver is the +map, not a build.** You do not write code until it is handed over. + +> Method grafted from the `explore-unknowns` skill; expressed in ratchet's own vocabulary — +> general mechanism, own words, backed by ratchet state. (Same graft discipline as the +> aperture dial.) + +Two moves make the walk work: + +- **Show, don't ask.** Never make the user describe intent from a blank page. Put something + concrete in front of them — a sample, a throwaway mock, a few competing directions — and + let them point at it. Recognition is cheap; invention is expensive. +- **Pre-draft their reply.** Close each turn with lettered options answerable in a few + characters, so the user reacts instead of composing. + +## Step 0 — Load state, then scan the terrain + +``` +ratchet status +ratchet snapshot repo +``` + +Scan first. Gather what already exists, what is half-built, and what was tried and +reverted — *before* you open your mouth. Serial questions on unread terrain waste the +user's attention. + +## Procedure + +Walk the four quadrants **in order**, naming the current one. Disclose material findings +the moment you hit them; never close a quadrant off-screen. + +1. **Known knowns — settle the ground.** State the facts, each cited to `file:line`. Mark + every assumption *separately* and say you will treat it as true until corrected, so a + wrong premise gets caught now instead of after the build. + +2. **Known unknowns — one question at a time.** Ask the single highest-blast-radius + question first (the answer that reshapes the most), not a wall of them. Give lettered + options with a **recommended** answer. Close each question exactly one way, in front of + the user: **user answer**, **territory** (you researched it, then show question + + finding), or **OPEN** (deferred, with what would unblock it). + +3. **Unknown knowns — extract the tacit.** The user cannot articulate what they don't know + they know. Do not ask abstractly. Put something concrete in their hands — sample data, a + throwaway mock, three or four incompatible renderings of the same thing — and let the + reaction expose the taste. Probe the offhand context: the downstream consumer, the + runtime it lands in, the acceptance bar of whoever owns it next. Record what each + reaction changes. + +4. **Unknown unknowns — sweep for landmines.** Hunt the silent failure modes a shallow read + misses: wrong-by-default data, stale denormalizations, **unwritten conventions** the code + enforces but no doc records, **prior attempts that were abandoned or rolled back — the + reason they died is usually the trap you are about to re-hit**, and latent bugs this path + inherits. Worst first. Each as a card: + + ``` + evidence: why it bites: what it changes: + status: decided | OPEN | sharp-edge + ``` + +5. **Hand over the map.** One page, all four quadrants. OPEN items live **on the map**, not + buried in chat. Add a tweakable build plan ordered by *what might change* (judgment calls + first, routine work compressed at the bottom) and a copy-paste implementation prompt. + Then stop — implementation is a separate engagement. + +## Output contract + +``` +QUADRANT WALK: current · coverage · stopped for user reaction? + +KNOWN KNOWNS: +- — evidence: +- — treated as true until challenged + +KNOWN UNKNOWNS: +- Q: | recommend: | closed by: user | territory | OPEN | unblocks: + +UNKNOWN KNOWNS: +- tacit constraint: | reshaped the target: + +UNKNOWN UNKNOWNS: +- landmine: | evidence: | why it bites: | changes: | status: decided | OPEN | sharp-edge + +HANDOVER MAP: path <.ratchet/unknowns-map.md> · OPEN items · build plan +IMPLEMENTATION PROMPT: +``` + +## Serialize + +The map is durable state, not scrollback. Record it so the next context resumes cold: + +``` +ratchet artifact add '{"kind":"unknown-map","title":"unknowns map: ","status":"handoff","path":".ratchet/unknowns-map.md","holes":[""]}' +ratchet state append decisions '{"choice":"","rejected":"","tripwire":""}' +ratchet state append assumptions '{"text":"","killTest":"","status":"untested"}' +ratchet state append openLoops '{"text":"OPEN: — unblocks: ","status":"open"}' +ratchet state set phase cut +ratchet state set nextCommand "/ratchet:build" +``` + +Real landmines that are actual failures (not just sharp edges) are defects, not notes: + +``` +ratchet defect add '{"severity":"high","summary":""}' +``` + +The map's OPEN loops, untested assumptions, and artifact holes all drain +`ratchet score confidence` on purpose — an unclosed unknown is tracked pressure, not a +forgotten one. The score cannot read ship-ready while the fog is still on the board. + +## Meter — when to reach for this + +Run `/ratchet:map` when the aperture earns it, not on a reversible one-liner: + +``` +ratchet score aperture '{"ambiguity":_,"terrain":_,"taste":_,"blastRadius":_,"reversibility":_}' +``` + +- **A0–A2** → don't. `/ratchet:lock` + infer-and-build is the right, anti-ceremony move. +- **A3** → map the fog, then build. +- **A4** → map the fog, hand over the plan/options, and **stop** — do not build until + constraints are locked. + +Also reach for it directly (whatever the score) on a reference-implementation port, an +"I'll know it when I see it" request, or a mid-build deviation that needs capturing. + +Next: when the map is handed over and the user picks the build plan → `/ratchet:build`. +At A4, lock the open constraints first (`/ratchet:lock`) and stop before building. diff --git a/test/plugin-shape.test.js b/test/plugin-shape.test.js index e0ac609..c774ede 100644 --- a/test/plugin-shape.test.js +++ b/test/plugin-shape.test.js @@ -137,4 +137,13 @@ ok('README does not mention removed command names', () => { assert.ok(!readme.includes('/ratchet:ratchet-evolve'), 'no stale /ratchet:ratchet-evolve in README'); }); +ok('the /ratchet:map fog gate is wired into the prompt catalog', () => { + // The generic loops above already force skills/map to carry frontmatter and be + // listed in the README. PROMPTS.md sync is otherwise untested, so guard it here: + // the map skill exists AND its canonical intent lives in the prompt source of truth. + assert.ok(skillDirs.includes('map'), 'skills/map exists'); + const prompts = read('reference/PROMPTS.md'); + assert.ok(prompts.includes('/ratchet:map'), 'PROMPTS.md references /ratchet:map'); +}); + process.stdout.write(`\n${passed} passed\n`);