| name | intent-shape |
| description | Externalize the felt-shape of a project — the inviolate gestalt beneath the features — using three sections and two modes, then plant the first primitive (seed) to bridge shape to a concrete artifact. Use upstream of implementation: cold-start when shape isn't articulated, warm when a decision is in front of you. Trigger on 'intent-shape', 'felt-shape', 'parti', 'I am stuck on [project]', 'what is this project actually for', 'shape is not crisp', 'probe me on this'. Do not trigger for implementation, debugging, or feature work. |
Intent-shape
A practice for externalizing the felt-shape of a project — the inviolate thing it's for — into a transmissible document, then sharpening it through use. Not a spec. Not a deliverable. A decision surface that matures as you build.
Modes
Cold start — shape isn't externalized yet. Draft the three sections. Mark sections [hazy] where you're uncertain; hazy is fine. Use the Adversary question (in Inviolates below) to generate inviolates when stuck.
Warm — shape exists, decision is in front of you. Apply the three sections to the decision: does it serve the intent-shape, violate an inviolate, or pattern-match to an anti-shape?
Existing codebase — code is already on disk. Determine the intent-shape first (cold-start moves), independent of what's there. The code is evidence, not authority — read it to provoke the architect's felt-shape, not to derive it. Then run the Gap audit below.
Gap audit (existing codebase only)
After the three sections are drafted, walk the codebase and produce a gap report. Four buckets:
- Missing — the shape demands it; the code lacks it. (Capability, surface, or quality the parti implies but isn't there.)
- Violating — code that breaks an inviolate. Name the file/area and which inviolate it crosses.
- Anti-shape drift — code that pattern-matches to a named anti-shape. The temptation already won here.
- Scaffolding masquerading as shape — code written like it's load-bearing intent but is actually replaceable. Candidate for removal, swap, or relegation to the scaffolding register.
For each entry: file/area, one-line gap, one-line implication. No fixes — this is a diagnostic. The architect decides what to repair, what to accept, and whether any gap is actually the shape telling you the document is wrong (update the doc instead of the code).
Test: every gap entry must trace to a specific line in the intent-shape document (parti clause, inviolate #, or anti-shape bullet). Untraceable gaps are aesthetic preferences — drop them or promote them into the document first.
The three sections
1. Intent-shape
One paragraph. Present tense. Written from inside the user's experience. Opens with the parti — a single sentence compression of the whole you'd say at a party. The rest unpacks what being inside that sentence feels like.
Test: can you say the parti in one breath? Does the rest make the parti feel inevitable?
2. Inviolates
Three to five things that must be true for the intent-shape to land. Each names what it would kill — not what it values, but what it forbids. Violations are kill-the-decision level.
Generative question: If someone wanted to ruin this while keeping all the features, what would they change? Those are your inviolates.
Test: for each inviolate, name a concrete thing it would kill. Hypotheticals only → aspiration, not inviolate. Cut or sharpen.
Subtraction check: imagine violating each inviolate. The project survives some — those aren't real inviolates. "Survives" means the felt experience still lands, not just that features still work.
3. Anti-shapes
Specific failure modes, each pointing at a real temptation. Grows over time. Each entry earns its place by naming a pull you've actually felt, not a generic warning.
Test: could a stranger read this list and recognize the specific temptations this project has? Generic warnings are filler.
Seeds — the first primitive
The three sections bound the work: the parti is why the garden exists, the inviolates are the depth of the soil, the anti-shapes are the fence. All of it is shape — what the thing is, what would kill it, what to avoid. None of it is the thing you plant. The seed is the first positive, generative atom: a primitive — a verb, a unit, a capability — that the artifact composes outward from. It is the bridge from bounded shape to concrete artifact.
Plant one seed, not the whole packet. The temptation is to enumerate the full primitive set up front — every verb, every motion, the mature composable system. That is felting in disguise (see Disciplines): naming all the seeds is designing the grown tool before anything is in the ground. Name the first seed only — the smallest primitive that, grown alone, would prove the thesis. The rest are named later, each earned by the previous seed's growth, never pre-enumerated.
Finding the first seed:
- Positive, not constraint. A seed is something you build and use — a move, not a rule. If it reads like an inviolate or an anti-shape, it's not a seed.
- Traces to the parti. Planting it grows toward the felt-shape, not sideways.
- Survives every inviolate. If building it crosses an inviolate, it's the wrong seed.
- Usually the load-bearing experiment — the hardest-to-fake primitive, the one whose success proves structure-plus-this beats the baseline. The first seed is normally the riskiest, not the easiest; the easy primitives are scaffolding that grows around it later.
Test: if this one primitive existed and nothing else did, would the result be unmistakably the new kind of thing? If it merely improves the baseline, it's a feature, not the first seed. (Go big, ship small: the vision is the whole garden; the first seed is one plant that proves the soil grows it.)
The first seed becomes the first frontier for charting the path. Seeds feed the path; walking the path grows the plant.
Handoff — charting the path
Intent-shape ends at the bounded shape and the first seed. It does not chart the build path — that is a separate practice, kept separate so this skill stays focused on what the thing is.
Once the shape is bounded enough that decisions flow (see Readiness signal) and the first seed is named, hand off to the explore-latent skill if available. It consumes this document, fans scout subagents to propose whole candidate paths toward the target, narrows them against these inviolates and anti-shapes, and walks the path one validated step at a time — feeding reality back here (warm mode) whenever a poke proves the shape wrong.
If explore-latent isn't available, build directly from the first seed, returning here whenever a decision needs the shape.
Probes
When a decision is in front of you, apply the three sections to it:
- Does it serve or blur the intent-shape?
- Does it violate an inviolate?
- Does it pattern-match to an anti-shape?
Each probe gets one of three outcomes:
- Document rules clearly — note verdict, no update needed
- Document is ambiguous — architect decides; decision becomes a document update
- Architect can't decide — shape isn't crisp on that axis; back to felting
Shape-probe option: for web-shaped artifacts, proto-buddy can generate a disposable visual sketch to test felt-shape before committing to a build path. Treat it as a probe: predicted/observed/gap, then update the document or discard the sketch.
The shape interrogation loop (autonomous until convergence)
When: after cold-start drafting — always. This is the primary sharpening mechanism, not an optional move. Run it on every new shape before handing off to explore-latent.
How:
- Fire
Workflow({scriptPath: '<skills>/intent-shape/workflows/shape-interrogator.js', args: {doc, round: 0}}). Returns a curated batch: {questions, new_count, summary, held_concerns, poke_candidates}. Each question has {question, choices:[{label, what_changes}], anchor, concern}. The batch is capped at 10 questions, drawn from the 1-3 hottest concern clusters and ordered so same-concern questions sit adjacent — depth over breadth; answering costs the architect real effort. Concerns the sift noticed but deferred come back by name in held_concerns[] — they are the raw material for later rounds, not losses.
- Write the batch + current docText to a payload JSON file. Run the shape-board:
node /path/to/thought-wright/skills/shape-board/serve.mjs <payload.json> > <result.json>
Run backgrounded — it serves :3335, opens the browser, blocks until the architect submits. Returns {dispositions, escalated}.
- Apply dispositions to the shape doc — each
{q, picks[]} may carry multiple selected labels; apply each accepted pick to the target section (the anchor field identifies which element). Skip = no change. Custom = apply free text to the target section. Never restructure; only update content.
- Route escalated[] — each question the architect hit
e on goes to a Workshop transform (thought-wright adjudicates choice A vs B or forks into framings). Apply the Workshop result back to the doc.
- Accrue the asked-ledger — after each round, extend
asked_ledger[] with every served question and its disposition (pick | skip | custom). Pass this into the next shape-interrogator call so the sift agent avoids re-serving skipped tensions.
- Compute dirty elements — diff the doc before and after applying dispositions. Any element whose text changed gets its anchor key added to
dirty_element_ids[]. Pass this to the next round.
- Re-fire shape-interrogator with
{doc: updatedDoc, round: round+1, dirty_element_ids, asked_ledger}.
- Stop (doc-delta convergence) — when the total chars changed across two consecutive rounds is below
N (suggested: 50 chars) and held_concerns is empty. new_count==0 is NOT a reliable stop signal — lenses generate infinite questions; doc stability is the true convergence indicator. If the doc has converged but held_concerns is non-empty, fire ONE flush round with dirty_element_ids omitted (full re-probe) so deferred concerns on settled elements get their turn; stop after it regardless of what it returns.
What the board does: each pick commits immediately (live-disposition). Left column shows the shape doc with pending diffs per resolved section. anchor is a display-only label showing which doc element a card probes. Keyboard: 1-5 pick, s skip, c customize, e escalate, ↑↓ move cards.
Poke candidates (poke_candidates[] in the interrogator return) are empirical questions that feel-tests can resolve but conversation cannot. Surface these separately — offer them to the architect as a poke/prototype list (feed into a proto-buddy run), not as board cards.
Front-load: inviolate wording and seed specificity propagate directly into flight-time auto-decisions. The sharper the letter-to-purpose here, the fewer expensive mid-flight corrections.
Guards:
- The loop never restructures the doc — only updates content within existing sections.
- A new inviolate surfaced by a pick is added to the Inviolates section; it becomes a dirty element on the next round.
- Zero accepted dispositions → no dirty elements → next round probes nothing → immediate convergence. This is correct behavior, not a bug.
Phase 2 — Logical consistency check
Run this once after the interrogation loop converges, before handing off to explore-latent. Invoke /logic-check with the finalized shape as the premise set.
Formalize:
- Parti → the goal claim (one-line: what the shape asserts it will produce)
- Each inviolate → a constraint (must hold; violation kills the decision)
- Each anti-shape → a forbidden pattern (what the project must not become)
Three questions to check:
- Contradiction — can all inviolates hold simultaneously? Mutually exclusive inviolates mean the shape is internally broken before a single line is built.
- Goal–constraint tension — does the parti require violating any inviolate? (e.g. parti implies real-time sync; inviolate says no external network calls)
- Redundancy — does any inviolate logically imply another? Redundant constraints add no force; consolidate or keep both explicitly for emphasis — but decide.
Gate: if /logic-check fires its fuzzy-premise gate (the element is qualitative, not a discrete fact + rule), skip that element cleanly — note which ones were too fuzzy to formalize. Do not force a formalization that misrepresents the reasoning; a bad formalization is worse than no check.
Outcomes:
consistent — shape is coherent; proceed to Phase 3
contradiction — surface the conflicting pair to the architect; resolve before handoff
redundant — flag the redundant inviolate; architect decides merge vs keep-for-emphasis
Phase 3 — Stamp to CLAUDE.md
Once Phase 2 returns consistent, write the distilled shape to the project's CLAUDE.md. No fluff — parti paragraph + inviolate one-liners only:
## Shape — <project name>
<parti paragraph, verbatim from the doc>
**Inviolates:**
- <inviolate 1, compressed to one line — the constraint, not the explanation>
- <inviolate 2>
...
No anti-shapes. No open questions. No scaffolding register. Just what the thing is and what would kill it. This is the persistent context that every future session in this project reads cold — keep it tight enough to be useful at a glance.
Append under an existing ## Shape block if one exists; create it if not. Do not touch anything else in CLAUDE.md.
Readiness signal
No done state. The shape matures; it doesn't complete. You're ready to hand off when the interrogation loop has converged and Phase 2 returns consistent (or all contradictions are resolved). Update the doc when implementation reveals something the shape missed.
Anti-skill check: if you've opened this document more than the codebase this week, you're felting instead of building. The exit isn't a stable rubric — it's a swing. Take it.
Scaffolding register (optional)
An aggressive list of what is not the intent-shape: frameworks, mechanics, platform, pricing, color, strategy — anything replaceable, in service, no emotional attachment.
Test: could the architect say "any of this could be different tomorrow and the project would still be itself"? If something would actually break the shape if changed, it's a missed inviolate. Move it up.
Disciplines
The document is in service of the shape, not the other way around. If writing isn't making the shape clearer, stop writing and go feel the shape.
Resist methodology trap. Three sections. Don't grow them out of cleverness — grow them out of use.
Plant one seed. Naming the whole primitive set up front is felting. Name the first seed — the smallest primitive that alone proves the thesis — and earn each next seed by the last one's growth.
Scaffolding is generous. When in doubt, mark it scaffolding. Projects rarely break from the architect being too willing to let things go.
The architect is responsible for intent, not preferences. If you can't articulate what an inviolate is in service of, it's a preference. Put it in the scaffolding register.
Output
A single markdown file per project, structured per assets/template.md. Changelog optional — add it if iteration cycles are producing document changes worth tracking.
For worked examples across different domains, see references/examples/.