diff --git a/.agents/workflow.md b/.agents/workflow.md index 55463d72..c819da7d 100644 --- a/.agents/workflow.md +++ b/.agents/workflow.md @@ -11,6 +11,6 @@ A private `.agents/workflow.local.md` takes precedence when present. Run - **Specs**: `.agents/specs/` - **High-level designs**: `docs/design/` - **Tickets**: GitHub Issues in `jinyeow/dotfiles` -- **Labels**: `spec-ready`, `design-ready`, `triaged`, `ready`, `needs-info`, `wontfix` +- **Labels**: `spec-ready`, `design-ready`, `triaged`, `ready`, `ready-for-human`, `needs-info`, `wontfix` - **Domain docs**: single-context layout with root `CONTEXT.md` and `docs/adr/` - **Wayfinding**: GitHub parent/child issues for maps; use `wayfinder:map`, `wayfinder:research`, `wayfinder:prototype`, `wayfinder:grilling`, and `wayfinder:task`; use GitHub's native blocking relationships; frontier means open, unblocked, unassigned child issues; claim by assigning the issue to the implementing developer. diff --git a/README.md b/README.md index 75822196..04130b29 100644 --- a/README.md +++ b/README.md @@ -104,8 +104,9 @@ Not sure which one fits? Run `/router` — a manual index that maps these as flo | Skill | Source | Purpose | |---|---|---| -| `grill-with-docs` | mattpocock/skills | Stateful grilling against the domain model; updates `CONTEXT.md`/ADRs inline | -| `grilling` | mattpocock/skills | Stateless relentless-interview primitive to stress-test a plan | +| `grill-with-docs` | mattpocock/skills | Thin pointer invoking `grilling` and `domain-modeling` together | +| `grilling` | mattpocock/skills | Relentless-interview primitive to stress-test a plan, in batched frontier rounds | +| `domain-modeling` | mattpocock/skills | Challenge terminology against `CONTEXT.md`, sharpen fuzzy language, record ADRs | | `prototype` | mattpocock/skills | Throwaway prototype for a state/logic question or UI exploration | | `to-spec` | mattpocock/skills | Turn the conversation into a spec | | `to-hld` | local | Turn the discussion into a high-level design doc — decisions + mermaid | diff --git a/ai-agents/README.md b/ai-agents/README.md index 183a3c9b..ea38a833 100644 --- a/ai-agents/README.md +++ b/ai-agents/README.md @@ -52,15 +52,18 @@ own `SKILL.md` frontmatter, trimmed to one line. Claude-native skills live in `. - **`council-code`** — Thin council alias for technical designs, ADRs, APIs, and approach documents. - **`council-doc`** — Thin council alias for presentations, proposals, and important documents. - **`council-plan`** — Thin council alias for project plans, roadmaps, and migrations. +- **`critique-plan`** *(trial)* — Stress-test a drafted plan against the project's domain model before any code is written: terminology drift, wrong bounded context, ADR contradictions, bad dependency edges, reinvented concepts. Adapted from [ayoubben18/ab-method](https://github.com/ayoubben18/ab-method) (MIT). - **`deep-review`** — Heavy multi-dimension cross-model code review of a branch diff or PR, the opt-in deep pass, not the default. - **`diagnosing-bugs`** — Diagnosis loop for hard bugs and performance regressions. - **`dispatch-implement`** — Dispatch one subagent per ticket to run `/implement` on it. +- **`domain-modeling`** — Build and sharpen a project's domain model: challenge terminology against `CONTEXT.md`, sharpen fuzzy language, and record ADRs as decisions crystallise. - **`fix-findings`** — Apply fixes for findings produced by quick-review or deep-review. -- **`grilling`** — Interview the user relentlessly about a plan or design until reaching shared understanding, resolving each branch of the decision tree. -- **`grill-with-docs`** — Grilling session that challenges your plan against the existing domain model, sharpens terminology, and updates documentation (CONTEXT.md, ADRs) inline as decisions crystallise. +- **`grilling`** — Interview the user relentlessly about a plan or design until reaching shared understanding, resolving each branch of the decision tree in batched frontier rounds. +- **`grill-with-docs`** — Thin pointer invoking `grilling` and `domain-modeling` together for a grilling session that also updates documentation (CONTEXT.md, ADRs) inline as decisions crystallise. - **`health`** — Manual engineering health audit of your agent setup: Claude/Codex config drift, hooks, MCP, skills, memory and skill supply-chain security, and AI-maintainability drift. - **`i-have-adhd`** — Shape output for a reader with ADHD: lead with the next action, number multi-step work, restate state across turns, suppress tangents, give specific time estimates, make wins visible. `disable-model-invocation: true` — invoke explicitly with `/i-have-adhd`; stays on until "stop adhd mode". Adapted from [ayghri/i-have-adhd](https://github.com/ayghri/i-have-adhd) (MIT). - **`implement`** — Implement a piece of work from a spec or set of tickets: TDD at agreed seams, review, then commit. +- **`implement-spec`** — Implement a whole spec as one pull request, working the ticket frontier with concurrent implementer subagents until every ticket lands, then review and open the PR. - **`improve-codebase-architecture`** — Find deepening opportunities in a codebase, informed by the domain language in CONTEXT.md and the decisions in docs/adr/. - **`jj`** — Use when working in a Jujutsu (jj) repository: making/describing changes, syncing with a remote, rewriting history, managing bookmarks or workspaces, or recovering via the op log. - **`linkedin-jobs`** — Read LinkedIn job alert emails and recruiter InMails, extract role details, and present them as structured cards grouped by inferred category. @@ -74,6 +77,7 @@ own `SKILL.md` frontmatter, trimmed to one line. Claude-native skills live in `. - **`redraft`** — Scrap the current fix and redo it properly, using everything learned while building the mediocre version. - **`refactor-agents-md`** — Refactor an AGENTS.md file to follow progressive disclosure: split it into a minimal root file plus linked category files. - **`resolving-merge-conflicts`** — Use when you need to resolve an in-progress git merge/rebase conflict. +- **`retro`** — Conduct a retrospective on a coding session, surfacing improvements to the agent's environment (docs, checks, conventions) rather than to the code itself. - **`review-ado-pr`** — Review an Azure DevOps pull request locally, end-to-end. - **`review-fix-loop`** — Iterative review-fix cycle for a branch or PR. - **`review-me`** — Interrogate the user on the current diff as an adversarial reviewer and withhold the PR until they pass. diff --git a/ai-agents/SKILL-OWNERSHIP.md b/ai-agents/SKILL-OWNERSHIP.md index 1f12eac0..28fa1064 100644 --- a/ai-agents/SKILL-OWNERSHIP.md +++ b/ai-agents/SKILL-OWNERSHIP.md @@ -25,8 +25,10 @@ is the orchestrating session's own top-level `sandbox_mode` — which may itself findings-store write path on Codex hosts remains an open gap. `storm-research` is portable too, as of #172 resolving the #95 spike below: its five expert-lens prompts and citation-verifier fan-out need only parallel dispatch with distinct per-child prompts, no -per-child tool scoping, on Pi via `pi-subagents`' `subagent({ tasks: [...] })` reusing the -builtin `researcher` agent; see `ai-agents/skills/storm-research/DISPATCH.md`. `walkthrough` +per-child tool scoping. At the pinned `pi-subagents@0.60.0` this is `subagent({ workflowScript: +"return runs.all([...])" })` reusing the builtin `researcher` agent — the top-level +`tasks: [...]` call shape this note previously named was removed upstream at 0.41.0; see +`ai-agents/skills/storm-research/DISPATCH.md`. `walkthrough` is portable too, as of #91: its `~/.claude/learner-profile.md` path now resolves to the runtime's own config home (`~/.claude/`, `~/.codex/`, `~/.pi/agent/`); its stale `.claude/tickets.md`/`.claude/specs/*.md` reference was corrected to the current @@ -45,7 +47,22 @@ all three runtimes, but only Claude Code's dispatch is wired (the `Agent` tool, `isolation: "worktree"` for parallel children so they do not race one shared `.git/index`); on Codex CLI (`[agents.implementer]` + `spawn_agent`, #211) and Pi (`pi-subagents`, #212) the skill stops and reports instead of dispatching until those tickets land. Parallel dispatch is gated off -in favor of sequential-only until #213 confirms the base flow against real usage. +in favor of sequential-only until #213 confirms the base flow against real usage. `implement-spec` +is portable too: it only orchestrates calls into `to-spec`, `to-tickets`, `dispatch-implement`, +`review-fix-loop`, and `to-pullrequest` — all already portable or tracked as such — so it carries +no runtime-specific mechanics of its own. It inherits `dispatch-implement`'s current Claude-Code- +only dispatch and sequential-only gate at each frontier batch until that skill's own blockers +clear. `critique-plan` +is portable too, and new: it dispatches one isolated read-only subagent to critique a drafted +plan against the domain model, reusing `domain-modeling`'s `CONTEXT.md`/`ADR-FORMAT.md`/ +`CONTEXT-FORMAT.md` conventions rather than a runtime-specific mechanism. Marked trial in +`ai-agents/README.md` — adapted from +[ayoubben18/ab-method](https://github.com/ayoubben18/ab-method) (MIT); not yet a settled +convention. `domain-modeling` is portable too, split out of `grill-with-docs` to match +[mattpocock/skills](https://github.com/mattpocock/skills)' current design: the CONTEXT.md/ADR +discipline stands on its own, independently model-invocable, while `grilling` (also +mattpocock/skills) carries the interview mechanics and `grill-with-docs` is now a thin pointer +skill invoking both. No runtime-specific mechanism involved. ## Portable support (`ai-agents/skills/_shared/`) diff --git a/ai-agents/skills/critique-plan/SKILL.md b/ai-agents/skills/critique-plan/SKILL.md new file mode 100644 index 00000000..477b9578 --- /dev/null +++ b/ai-agents/skills/critique-plan/SKILL.md @@ -0,0 +1,86 @@ +--- +name: critique-plan +description: Stress-test a drafted plan against the project's domain model before any code is written — terminology drift, wrong bounded context, ADR contradictions, bad dependency edges, reinvented concepts. Use before implementing from a spec or ticket set, or when the user asks to critique, pressure-test, or sanity-check a plan against the domain model. +metadata: + status: trial +--- + +# Critique Plan (pre-implementation) + +Stress-test a drafted plan against the project's domain model before any code is written. This +skill produces pushbacks, not suggestions — it never gold-plates a plan that is already sound. + +Silence is the expected outcome. A plan that speaks the canonical language and respects the +documented decisions gets a one-line "No objections." Do not manufacture concerns to look +thorough. + +"The plan" is whatever came out of `to-spec` or `to-tickets`, a set of tickets already on the +tracker, or whatever the user pastes in standalone. + +## Process + +### 1. Load the domain model + +Read only what exists; skip missing files silently — don't flag them or offer to create them. +Look for `CONTEXT.md` (or `CONTEXT-MAP.md` plus each context's own `CONTEXT.md`, per +[domain-modeling](../domain-modeling/SKILL.md#file-structure)) and `docs/adr/`. + +If neither exists, say so in one line and stop — there is no domain model to critique against. + +### 2. Spin up one read-only domain critic + +Dispatch a single isolated, read-only subagent with the plan verbatim and the files from step 1. +It returns pushbacks as text and edits nothing. Isolating it keeps the critique out of the +planning session's context. Its brief: + +Fire only on a genuine conflict, one of: + +- **Terminology drift** — the plan names a concept differently from the glossary/`CONTEXT.md`, or + reuses a canonical term for a new meaning. +- **Wrong bounded context** — work placed in the wrong context, or a unit that straddles a + documented boundary. +- **Contradicts an ADR** — reverses a recorded decision and the friction is real enough to reopen + it. Cite `ADR-NNNN`. +- **Bad dependency edge** (ticket set) — a "blocked by" edge crosses a context boundary the wrong + way, two "independent" tickets share a domain concept, or a ticket is mis-scoped (an epic, or + several tickets dressed as one). +- **Reinvents a named concept** — introduces a new abstraction for something the domain model + already names. + +For each, return: **What** (the ticket/decision in question), **Conflicts with** (the exact +term / `CONTEXT.md` section / `ADR-NNNN`), **Why it matters** (concrete cost, not taste), +**Suggested resolution**. + +Example pushback: "Ticket 3 calls it `archiveOrder`, but the glossary defines archiving as +retention only — this ticket also stops billing, which is Cancellation. Rename to `cancelOrder` +so the code matches the domain, or the two concepts will blur across the codebase." + +A deliberately deferred decision the plan already marks as such (a stated placeholder, an +explicit TBD) is not a gap to flag — the user chose to defer it. Fire on it only if the +placeholder itself conflicts with the domain model: it contradicts an ADR, or it quietly +redefines a canonical term. + +Out of scope for this critic: implementation quality, performance, tests, code style, "you could +also…" ideas — anything not anchored in the domain model. Those belong to `spec-review` (does the +diff match the spec) or `quick-review`/`deep-review` (code quality), which run after +implementation. With nothing anchored, the critic returns exactly: +`No objections — the plan is consistent with the domain model.` + +### 3. Surface pushbacks — advisory, never blocking + +Bring the pushbacks back into the planning session. The user resolves each their own way: + +- **Accept** → amend the plan (rename, re-scope, fix the edge, move contexts) right there. +- **Dismiss** → drop it. If the dismissal rests on a load-bearing reason a future planner would + need in order not to re-raise it, offer to record an ADR using + [domain-modeling's ADR-FORMAT.md](../domain-modeling/ADR-FORMAT.md). Skip ephemeral ("not now") + and self-evident reasons. + +When a resolution sharpens a term, update `CONTEXT.md` inline using +[domain-modeling's CONTEXT-FORMAT.md](../domain-modeling/CONTEXT-FORMAT.md). + +If the critic returned "No objections," say so in one line and move on. Don't pad it. + +`grilling`/`domain-modeling` is a full interactive re-grill of the design; `critique-plan` is a +single-pass, silent-by-default gate — one critic, real conflicts only, then straight back to the +workflow. diff --git a/ai-agents/skills/deep-review/DISPATCH.md b/ai-agents/skills/deep-review/DISPATCH.md index 8055ae18..b17c2d01 100644 --- a/ai-agents/skills/deep-review/DISPATCH.md +++ b/ai-agents/skills/deep-review/DISPATCH.md @@ -43,8 +43,8 @@ use; no change from current behavior. ### Pi (`pi-subagents`) Express the allowlist as the child agent's `tools:` frontmatter — confirmed present at the -pinned `pi-subagents@0.40.0` (`RunnerSubagentStep.tools?: string[]`, shipped source, -`package/src/runs/shared/parallel-utils.ts`; also `agent-serializer.ts:10,58-63`). A dimension +pinned `pi-subagents@0.60.0` (`RunnerSubagentStep.tools?: string[]`, shipped source, +`package/src/runs/shared/parallel-utils.ts:44`; also `agent-serializer.ts:11,67-72`). A dimension with `no` in "Reads beyond diff?" gets `tools: read, grep`; one with `yes` gets `tools: read, grep, glob`. Never include `bash`, `edit`, or `write` — a reviewer that needs to mutate anything is out of contract. @@ -151,19 +151,23 @@ adapter, not one of the seven dimension workers. ## Dispatch call shape (Pi) -Two shapes exist in the pinned `pi-subagents@0.40.0` source: an ad-hoc multi-call in one turn, -and the scripted `runs.all`/`workflowScript` batch API. **This skill uses ad-hoc multi-call**, -matching what `council` already exercises in practice (`council`'s `CRITIQUE` step: "Launch all -charter seats as fresh isolated workers, together when parallel dispatch is available" — no -scripted workflow). Rationale: +At the pinned `pi-subagents@0.60.0`, two shapes exist for launching several children: an ad-hoc +multi-call in one turn (repeated single-child `subagent({ agent, task })` calls), and the +scripted `runs.all`/`workflowScript` batch API. As of 0.41.0, the package removed the older +top-level `tasks: [...]` array shape entirely — `workflowScript` is now the only way to batch +children in a single tool call — but ad-hoc multi-call was never affected by that removal, since +it never used `tasks[]`. **This skill uses ad-hoc multi-call**, matching what `council` already +exercises in practice (`council`'s `CRITIQUE` step: "Launch all charter seats as fresh isolated +workers, together when parallel dispatch is available" — no scripted workflow). Rationale: - Consistency — `deep-review`/`quick-review` compose with `council`'s contract; diverging to a scripted API for one skill and ad-hoc for the rest adds a second dispatch idiom for no functional gain. -- Evidence asymmetry — the `tools:` scoping field and the parallel-batch *mechanism* are - confirmed in the pinned 0.40.0 shipped source; the exact `runs.all()` call-site spelling is - confirmed only against newer (0.44.0) docs, not source-verified at the pin. Ad-hoc multi-call - avoids depending on the unverified spelling. +- Evidence asymmetry no longer applies at the current pin — the `tools:` scoping field, the + parallel-batch mechanism, and the `runs.all()` call-site spelling (`docs/workflows.md:38,88-92` + at the pinned 0.60.0) are all now confirmed directly in the pinned version's own shipped + source and docs, not inferred from a newer version. Ad-hoc multi-call remains the choice for + the consistency reason above, not because the scripted shape is unverified. This is **source-verified against the pinned version, not executed as a live smoke test** — no live Pi session was driven interactively in this session to confirm ad-hoc multi-call actually @@ -265,8 +269,10 @@ way whether `config_file` honors per-role `sandbox_mode`. `findings-schema.md` requires reviewer/verifier/fixer workers to **return** results — never write the store themselves. Under Pi, a child's `outputMode` defaults to `"inline"` -(`package/src/api/preflight.ts:398` at the pinned 0.40.0: `outputMode: input.outputMode ?? -"inline"`), meaning the child's result resolves back to the caller as text rather than being +(`package/src/shared/settings.ts:387` at the pinned 0.60.0: `task.outputMode ?? config.outputMode +?? "inline"`), meaning the child's result resolves back to the caller as text rather than being written to a file by the child. This holds the invariant by default — the orchestrator stays -the sole writer as long as dispatch never sets `outputMode: "file-only"`. Do not set it for -reviewer, verifier, or fixer children. +the sole writer as long as dispatch never sets `outputMode: "file-only"` and no project/user +`subagents` config sets a global `outputMode: "file-only"` default (the added +`config.outputMode` term at this version); this repo's `pi/settings.json` sets no such config. +Do not set it for reviewer, verifier, or fixer children. diff --git a/ai-agents/skills/diagnosing-bugs/SKILL.md b/ai-agents/skills/diagnosing-bugs/SKILL.md index 3ab904c5..71d31345 100644 --- a/ai-agents/skills/diagnosing-bugs/SKILL.md +++ b/ai-agents/skills/diagnosing-bugs/SKILL.md @@ -9,6 +9,12 @@ A discipline for hard bugs. Skip phases only when explicitly justified. When exploring the codebase, read `CONTEXT.md` (if it exists) to get a clear mental model of the relevant modules, and check ADRs in the area you're touching. +## Redact + +This skill has you show commands, outputs and captured artifacts. **Redact every secret first**: write `` in its place. Build loops against env vars, so the credential stays in the environment rather than in what you show. Captured artifacts carry auth headers: quote only the lines that carry the signal. + +If the redacted output is not enough to diagnose the bug, say so and ask the user. + ## Hard stops Hard bugs are lost by rationalising instead of testing. Treat each of these as a signal to stop and do the disciplined thing: @@ -72,11 +78,11 @@ The goal is not a clean repro but a **higher reproduction rate**. Loop the trigg ### When you genuinely cannot build a loop -Stop and say so explicitly. List what you tried. Ask the user for: (a) access to whatever environment reproduces it, (b) a captured artifact (HAR file, log dump, core dump, screen recording with timestamps), or (c) permission to add temporary production instrumentation. Do **not** proceed to hypothesise without a loop. +Stop and say so explicitly. List what you tried. Ask the user for: (a) access to whatever environment reproduces it, (b) a redacted captured artifact (HAR file, log dump, core dump, screen recording with timestamps), or (c) permission to add temporary production instrumentation. Do **not** proceed to hypothesise without a loop. ### Completion criterion — a tight loop that goes red -Phase 1 is done when the loop is **tight** and **red-capable**: you can name **one command** — a script path, a test invocation, a curl — that you have **already run at least once** (paste the invocation and its output), and that is: +Phase 1 is done when the loop is **tight** and **red-capable**: you can name **one command** — a script path, a test invocation, a curl — that you have **already run at least once** (show the invocation and its output, redacted), and that is: - [ ] **Red-capable** — it drives the actual bug code path and asserts the **user's exact symptom**, so it can go red on this bug and green once fixed. Not "runs without erroring" — it must be able to _catch this specific bug_. - [ ] **Deterministic** — same verdict every run (flaky bugs: a pinned, high reproduction rate, per above). diff --git a/ai-agents/skills/grill-with-docs/ADR-FORMAT.md b/ai-agents/skills/domain-modeling/ADR-FORMAT.md similarity index 100% rename from ai-agents/skills/grill-with-docs/ADR-FORMAT.md rename to ai-agents/skills/domain-modeling/ADR-FORMAT.md diff --git a/ai-agents/skills/grill-with-docs/CONTEXT-FORMAT.md b/ai-agents/skills/domain-modeling/CONTEXT-FORMAT.md similarity index 100% rename from ai-agents/skills/grill-with-docs/CONTEXT-FORMAT.md rename to ai-agents/skills/domain-modeling/CONTEXT-FORMAT.md diff --git a/ai-agents/skills/domain-modeling/SKILL.md b/ai-agents/skills/domain-modeling/SKILL.md new file mode 100644 index 00000000..70711d2d --- /dev/null +++ b/ai-agents/skills/domain-modeling/SKILL.md @@ -0,0 +1,74 @@ +--- +name: domain-modeling +description: Build and sharpen a project's domain model. Use when discussing codebase terminology, writing or editing a CONTEXT.md, or recording or editing an ADR. +--- + +# Domain Modeling + +Actively build and sharpen the project's domain model as you design. This is the *active* discipline: challenging terms, inventing edge-case scenarios, and writing the glossary and decisions down the moment they crystallise. (Merely *reading* `CONTEXT.md` for vocabulary is not this skill — that's a one-line habit any skill can do. This skill is for when you're changing the model, not just consuming it.) + +## File structure + +Most repos have a single context: + +``` +/ +├── CONTEXT.md +├── docs/ +│ └── adr/ +│ ├── 0001-event-sourced-orders.md +│ └── 0002-postgres-for-write-model.md +└── src/ +``` + +If a `CONTEXT-MAP.md` exists at the root, the repo has multiple contexts. The map points to where each one lives: + +``` +/ +├── CONTEXT-MAP.md +├── docs/ +│ └── adr/ ← system-wide decisions +├── src/ +│ ├── ordering/ +│ │ ├── CONTEXT.md +│ │ └── docs/adr/ ← context-specific decisions +│ └── billing/ +│ ├── CONTEXT.md +│ └── docs/adr/ +``` + +Create files lazily — only when you have something to write. If no `CONTEXT.md` exists, create one when the first term is resolved. If no `docs/adr/` exists, create it when the first ADR is needed. + +## During the session + +### Challenge against the glossary + +When the user uses a term that conflicts with the existing language in `CONTEXT.md`, call it out immediately. "Your glossary defines 'cancellation' as X, but you seem to mean Y — which is it?" + +### Sharpen fuzzy language + +When the user uses vague or overloaded terms, propose a precise canonical term. "You're saying 'account' — do you mean the Customer or the User? Those are different things." + +### Discuss concrete scenarios + +When domain relationships are being discussed, stress-test them with specific scenarios. Invent scenarios that probe edge cases and force the user to be precise about the boundaries between concepts. + +### Cross-reference with code + +When the user states how something works, check whether the code agrees. If you find a contradiction, surface it: "Your code cancels entire Orders, but you just said partial cancellation is possible — which is right?" + +### Update CONTEXT.md inline + +When a term is resolved, update `CONTEXT.md` right there. Don't batch these up — capture them as they happen. Use the format in [CONTEXT-FORMAT.md](./CONTEXT-FORMAT.md). + +`CONTEXT.md` should be totally devoid of implementation details. Do not treat `CONTEXT.md` as a spec, a scratch pad, or a repository for implementation decisions. It is a glossary and nothing else. + +### Offer ADRs sparingly + +Only offer to create an ADR when all three are true: + +1. **Hard to reverse** — the cost of changing your mind later is meaningful +2. **Surprising without context** — a future reader will wonder "why did they do it this way?" +3. **The result of a real trade-off** — there were genuine alternatives and you picked one for specific reasons + +If any of the three is missing, skip the ADR. Use the format in [ADR-FORMAT.md](./ADR-FORMAT.md). diff --git a/ai-agents/skills/grill-with-docs/SKILL.md b/ai-agents/skills/grill-with-docs/SKILL.md index 1ac707c7..5665edaf 100644 --- a/ai-agents/skills/grill-with-docs/SKILL.md +++ b/ai-agents/skills/grill-with-docs/SKILL.md @@ -4,82 +4,6 @@ description: Grilling session that challenges your plan against the existing dom disable-model-invocation: true --- - +Run a [`grilling`](../grilling/SKILL.md) session — the relentless, frontier-round interview to reach shared understanding. While you grill, run [`domain-modeling`](../domain-modeling/SKILL.md) alongside it, so the project's domain docs (`CONTEXT.md`, ADRs) get maintained inline as decisions crystallise. -Run a `/grilling` session — the same relentless, one-question-at-a-time interview to reach shared understanding. While you grill, actively maintain the project's domain docs as decisions crystallise, per the discipline below. - - - - - -## Domain awareness - -During codebase exploration, also look for existing documentation: - -### File structure - -Most repos have a single context: - -``` -/ -├── CONTEXT.md -├── docs/ -│ └── adr/ -│ ├── 0001-event-sourced-orders.md -│ └── 0002-postgres-for-write-model.md -└── src/ -``` - -If a `CONTEXT-MAP.md` exists at the root, the repo has multiple contexts. The map points to where each one lives: - -``` -/ -├── CONTEXT-MAP.md -├── docs/ -│ └── adr/ ← system-wide decisions -├── src/ -│ ├── ordering/ -│ │ ├── CONTEXT.md -│ │ └── docs/adr/ ← context-specific decisions -│ └── billing/ -│ ├── CONTEXT.md -│ └── docs/adr/ -``` - -Create files lazily — only when you have something to write. If no `CONTEXT.md` exists, create one when the first term is resolved. If no `docs/adr/` exists, create it when the first ADR is needed. - -## During the session - -### Challenge against the glossary - -When the user uses a term that conflicts with the existing language in `CONTEXT.md`, call it out immediately. "Your glossary defines 'cancellation' as X, but you seem to mean Y — which is it?" - -### Sharpen fuzzy language - -When the user uses vague or overloaded terms, propose a precise canonical term. "You're saying 'account' — do you mean the Customer or the User? Those are different things." - -### Discuss concrete scenarios - -When domain relationships are being discussed, stress-test them with specific scenarios. Invent scenarios that probe edge cases and force the user to be precise about the boundaries between concepts. - -### Cross-reference with code - -When the user states how something works, check whether the code agrees. If you find a contradiction, surface it: "Your code cancels entire Orders, but you just said partial cancellation is possible — which is right?" - -### Update CONTEXT.md inline - -When a term is resolved, update `CONTEXT.md` right there. Don't batch these up — capture them as they happen. Use the format in [CONTEXT-FORMAT.md](./CONTEXT-FORMAT.md). - -`CONTEXT.md` should be totally devoid of implementation details. Do not treat `CONTEXT.md` as a spec, a scratch pad, or a repository for implementation decisions. It is a glossary and nothing else. - -### Offer ADRs sparingly - -Only offer to create an ADR when all three are true: - -1. **Hard to reverse** — the cost of changing your mind later is meaningful -2. **Surprising without context** — a future reader will wonder "why did they do it this way?" -3. **The result of a real trade-off** — there were genuine alternatives and you picked one for specific reasons - -If any of the three is missing, skip the ADR. Use the format in [ADR-FORMAT.md](./ADR-FORMAT.md). - - +Invoke both skills together: `grilling` for the interview mechanics, `domain-modeling` for the docs discipline. diff --git a/ai-agents/skills/grilling/SKILL.md b/ai-agents/skills/grilling/SKILL.md index 497b4f34..ccf2211e 100644 --- a/ai-agents/skills/grilling/SKILL.md +++ b/ai-agents/skills/grilling/SKILL.md @@ -1,13 +1,45 @@ --- name: grilling -description: Interview the user relentlessly about a plan or design until reaching shared understanding, resolving each branch of the decision tree. Use when the user wants to stress-test a plan before building, get grilled on their design, or uses any "grill" trigger phrase. +description: Interview the user relentlessly about a plan or design until reaching shared understanding, resolving each branch of the decision tree in batched rounds. Use when the user wants to stress-test a plan before building, get grilled on their design, or uses any "grill" trigger phrase. disable-model-invocation: true --- -Interview me relentlessly about every aspect of this plan until we reach a shared understanding. Walk down each branch of the design tree, resolving dependencies between decisions one-by-one. For each question, provide your recommended answer. +Interview me relentlessly until we reach a shared understanding. Map this as a **design tree**: every decision branches into the decisions that hang off it. -Ask the questions one at a time, waiting for feedback on each question before continuing. Asking multiple questions at once is bewildering. +Work the tree in **rounds**. The **frontier** is every decision whose prerequisites are already settled — the questions you can ask now without guessing at answers you haven't heard yet. Ask the whole frontier in one round: number each question and give your recommended answer. Then wait for my answers before the next round. -If a *fact* can be found by exploring the codebase, look it up rather than asking me. The *decisions*, though, are mine — put each one to me and wait for my answer. +Format a round like so: -Do not enact the plan until I confirm we have reached a shared understanding. +``` +❓ **Q1** - ****: + +➡️ + +--- + +❓ **Q2** - ****: + +➡️ +``` + +Each round my answers reshape the tree: settled decisions push the frontier outward and unblock questions that depended on them. Recompute the frontier and ask the next round. A question whose answer depends on another question still open in this round belongs to a later round, not this one. + +Finding *facts* is your job, never mine. When a frontier question needs a fact from the environment (filesystem, tools, etc.), dispatch a subagent to find it; don't ask me for anything you could look up yourself. Don't block the round on it — a running exploration is an unsettled prerequisite, so only the questions downstream of it wait; ask the rest of the frontier now. The *decisions* are mine — put each one to me and wait for my answer. + +## Decision status + +Track every open branch of the tree under one of three states: + +- **Resolved** — I gave an explicit answer, captured verbatim or faithfully paraphrased. Never mark a decision resolved from my silence, from a follow-up that moved past it, or from your own recommended answer standing unchallenged. No answer means the decision stays open. +- **Open** — asked, not yet answered. +- **Needs codebase check** — a fact, not a decision; dispatched to a subagent, pending its result. + +## Session end + +The session is done when the frontier is empty: every branch of the design tree visited, nothing left silently assumed. Before handing off to implementation, give a short wrap-up: + +- **Agreed decisions** — the resolved list, one line each. +- **Open risks** — anything resolved with caveats, or a resolved decision worth flagging for revisit later. +- **Next decision needed** — if the session is cutting short with the frontier not actually empty, name what's still open. + +Do not act on any of this until I confirm we have reached a shared understanding. diff --git a/ai-agents/skills/implement-spec/SKILL.md b/ai-agents/skills/implement-spec/SKILL.md new file mode 100644 index 00000000..8c464c0a --- /dev/null +++ b/ai-agents/skills/implement-spec/SKILL.md @@ -0,0 +1,60 @@ +--- +name: implement-spec +description: Implement a whole spec as one pull request — work the ticket frontier with concurrent implementer subagents until every ticket lands, then review and open the PR. +disable-model-invocation: true +--- + +# Implement Spec + +Takes a spec and its tickets (`to-spec` + `to-tickets`, or their tracker equivalents) and lands +the whole thing as a single PR. The tickets are not a checklist — they are a task graph with +blocking edges, so there is always a **frontier** (`to-tickets`, `wayfinder`) of tickets ready to +grab. This skill drives that frontier to empty, then reviews and opens the PR. + +This is an orchestrator, not an implementer: `dispatch-implement` already owns per-ticket +mechanics (parallel-vs-sequential judgment, per-child model pick, worktree isolation, cherry-pick +integration onto the branch) — this skill calls it per batch rather than reimplementing any of +that. Keep prompts to subagents sparse: point at the spec, the tickets, and prior commits rather +than restating their content. + +## Steps + +1. **Read the spec and tickets.** Resolve their location from `.agents/workflow.local.md` when + present, otherwise `.agents/workflow.md` (`.agents/specs/.md` + `.agents/tickets.md` by + default, or the configured tracker). Read enough to see the full task graph — which tickets + block which — not just the first frontier. + +2. **Explore first, if a ticket needs it (optional).** When a ticket depends on unfamiliar + codebase areas or external documentation, delegate that reading to a background research + agent before implementation starts. Have it save its notes to a file outside the repo so every + later subagent can read it by path — a context pointer, not something repeated in each + subagent's prompt. + +3. **Branch and open a draft PR.** Create the branch per `AGENTS.md` → "Git worktrees" if this + repo uses that layout, then run `/to-pullrequest` to open it as a draft that closes the spec + issue and its tickets (GitHub linking keywords, or the tracker's native relationship). + +4. **Work the frontier to empty.** While any ticket remains open: run `/dispatch-implement` with + every ticket in the current frontier in one call — it judges which can run in parallel, isolates + parallel children in their own worktree, and integrates each onto the branch. Once a batch + lands, recompute the frontier (the tickets it just unblocked) and dispatch again. Repeat until + no ticket remains. + +5. **Review the whole branch.** With every ticket closed, run `/review-fix-loop` on the branch — + this catches cross-ticket issues no single ticket's implementer could see. + +6. **Mark the PR ready for review.** `to-pullrequest` stops at PR creation, so undraft directly: + `gh pr ready ` (GitHub) or `az repos pr update --id --draft false` (Azure DevOps). + +7. **Report** the PR URL, the tickets landed, and any ticket that had to be resolved outside the + normal frontier flow (rescoped, split, or dropped as out of scope). + +## Related + +- `to-spec`, `to-tickets` — produce the spec and task graph this skill consumes. +- `dispatch-implement` — owns the per-batch subagent mechanics (parallel judgment, worktree + isolation, cherry-pick integration); this skill only decides which tickets go in each batch. +- `review-fix-loop` — the whole-branch quality gate before the PR goes up for review. +- `to-pullrequest` — opens the draft PR; this skill undrafts it directly once review passes. +- `wayfinder` — the frontier/task-graph vocabulary this skill reuses, for planning work larger + than one spec. diff --git a/ai-agents/skills/improve-codebase-architecture/SKILL.md b/ai-agents/skills/improve-codebase-architecture/SKILL.md index d0ad951c..e0be21dc 100644 --- a/ai-agents/skills/improve-codebase-architecture/SKILL.md +++ b/ai-agents/skills/improve-codebase-architecture/SKILL.md @@ -32,6 +32,11 @@ This skill is _informed_ by the project's domain model. The domain language give ### 1. Explore +**Scope before you scan: YAGNI.** Deepening a module pays off by making future changes to it easier, so put extra weight on the parts of the codebase that have recently changed. Decide where to look before you look: + +- If the user named a direction (a module, a subsystem, a pain point), take it, and skip the inference below. +- Otherwise, walk back a good stretch of the commit history (`git log --oneline`) to find the codebase's hot spots, the files and areas that keep coming up, and let those paths pull your attention first. If the changes are scattered with no clear hot spot, widen the net. + Read the project's domain glossary and any ADRs in the area you're touching first. Then use the Agent tool with `subagent_type=Explore` to walk the codebase. Don't follow rigid heuristics — explore organically and note where you experience friction: @@ -75,7 +80,7 @@ Once the user picks a candidate, drop into a grilling conversation. Walk the des Side effects happen inline as decisions crystallize: -- **Naming a deepened module after a concept not in `CONTEXT.md`?** Add the term to `CONTEXT.md` — same discipline as `/grill-with-docs` (see [CONTEXT-FORMAT.md](../grill-with-docs/CONTEXT-FORMAT.md)). Create the file lazily if it doesn't exist. +- **Naming a deepened module after a concept not in `CONTEXT.md`?** Add the term to `CONTEXT.md` — same discipline as `/domain-modeling` (see [CONTEXT-FORMAT.md](../domain-modeling/CONTEXT-FORMAT.md)). Create the file lazily if it doesn't exist. - **Sharpening a fuzzy term during the conversation?** Update `CONTEXT.md` right there. -- **User rejects the candidate with a load-bearing reason?** Offer an ADR, framed as: _"Want me to record this as an ADR so future architecture reviews don't re-suggest it?"_ Only offer when the reason would actually be needed by a future explorer to avoid re-suggesting the same thing — skip ephemeral reasons ("not worth it right now") and self-evident ones. See [ADR-FORMAT.md](../grill-with-docs/ADR-FORMAT.md). +- **User rejects the candidate with a load-bearing reason?** Offer an ADR, framed as: _"Want me to record this as an ADR so future architecture reviews don't re-suggest it?"_ Only offer when the reason would actually be needed by a future explorer to avoid re-suggesting the same thing — skip ephemeral reasons ("not worth it right now") and self-evident ones. See [ADR-FORMAT.md](../domain-modeling/ADR-FORMAT.md). - **Want to explore alternative interfaces for the deepened module?** Use the parallel "design it twice" pattern — see [codebase-design's DESIGN-IT-TWICE.md](../codebase-design/DESIGN-IT-TWICE.md). diff --git a/ai-agents/skills/prototype/LOGIC.md b/ai-agents/skills/prototype/LOGIC.md index 526ecb18..603ab263 100644 --- a/ai-agents/skills/prototype/LOGIC.md +++ b/ai-agents/skills/prototype/LOGIC.md @@ -1,79 +1,67 @@ # 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. +A single, self-contained HTML file (a **shareable demo**) that lets anyone drive a state model by clicking buttons. 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. + +Because it's one file with nothing to install, you can hand it to a non-developer (a designer, a PM, a domain expert) and let them feel the model for themselves, in their own language, not the code's. ## 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**. +- Anything where someone wants to **press buttons and watch state change**. -If the question is "what should this look like" — wrong branch. Use [UI.md](UI.md). +If the question is "what should this look like," this is the 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. 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. - -### 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. +Before writing code, write down what state model and what question you're prototyping. One paragraph, at the top of the demo (in a visible intro, not just a comment). A logic prototype that answers the wrong question is pure waste, so make the question explicit so it can be checked later, whether the user is watching now or returning to it AFK. -### 3. Isolate the logic in a portable module +### 2. 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. +Put the actual logic (the bit that's answering the question) in a single `