From 4284f3ec941c685f5d642d0be41e0cbc92078c07 Mon Sep 17 00:00:00 2001 From: diegoitaliait Date: Fri, 28 Aug 2026 19:03:40 +0200 Subject: [PATCH 001/150] Refactor and remove deprecated skills and configurations - Deleted the `mattpocock-writing-great-skills` skill and its associated files, including SKILL.md and openai.yaml. - Updated tests to remove references to the deleted skill and adjusted assertions accordingly. - Added new skills `grill-me` and `grilling` to the resource management. - Enhanced the normalization tests to ensure proper handling of legacy paths and invocation policies. - Improved the test suite to validate the presence and correctness of new skills and their configurations. - Ensured that the internal skill creator uses current entry points and does not reference removed skills. --- .github/INVENTORY.md | 11 +- .github/skills/grill-me/SKILL.md | 49 +-- .github/skills/grill-me/agents/openai.yaml | 6 +- .github/skills/grilling/SKILL.md | 22 ++ .github/skills/grilling/agents/openai.yaml | 3 + .github/skills/internal-grill-me/SKILL.md | 57 ++++ .../internal-grill-me/agents/openai.yaml | 6 + .../skills/internal-skill-creator/SKILL.md | 4 +- .../internal-skill-creator/agents/openai.yaml | 2 +- .../SKILL.md | 58 ++-- ...ng-great-skills-delegated-invocation.patch | 11 - .../references/imported-asset-overrides.yaml | 14 - .../references/managed-resources.yaml | 151 +++++++-- .../scripts/sync_external_resources.py | 65 +++- .../scripts/sync_external_resources_core.py | 311 +++--------------- .../mattpocock-ask-matt/PHASE-BOUNDARIES.md | 55 ++++ .github/skills/mattpocock-ask-matt/SKILL.md | 90 +++++ .../mattpocock-ask-matt/agents/openai.yaml | 5 + .../skills/mattpocock-code-review/SKILL.md | 17 +- .../mattpocock-code-review/agents/openai.yaml | 2 +- .../DESIGN-IT-TWICE.md | 2 +- .../mattpocock-codebase-design/SKILL.md | 9 - .../agents/openai.yaml | 2 +- .../mattpocock-diagnosing-bugs/SKILL.md | 140 ++++++++ .../agents/openai.yaml | 3 + .../scripts/hitl-loop.template.sh | 44 +++ .../mattpocock-domain-modeling/SKILL.md | 9 - .../agents/openai.yaml | 2 +- .../mattpocock-grill-with-docs/SKILL.md | 10 +- .../agents/openai.yaml | 6 +- .github/skills/mattpocock-handoff/SKILL.md | 14 +- .../mattpocock-handoff/agents/openai.yaml | 6 +- .github/skills/mattpocock-implement/SKILL.md | 10 +- .../mattpocock-implement/agents/openai.yaml | 6 +- .../SKILL.md | 12 +- .../agents/openai.yaml | 6 +- .github/skills/mattpocock-prototype/LOGIC.md | 67 ++++ .github/skills/mattpocock-prototype/SKILL.md | 26 ++ .github/skills/mattpocock-prototype/UI.md | 112 +++++++ .../mattpocock-prototype/agents/openai.yaml | 3 + .github/skills/mattpocock-research/SKILL.md | 35 +- .../mattpocock-research/agents/openai.yaml | 6 +- .../SKILL.md | 14 + .../agents/openai.yaml | 3 + .../SKILL.md | 16 +- .../agents/openai.yaml | 6 +- .../issue-tracker-github.md | 2 +- .../issue-tracker-gitlab.md | 2 +- .../issue-tracker-local.md | 19 +- .github/skills/mattpocock-tdd/SKILL.md | 11 +- .../skills/mattpocock-tdd/agents/openai.yaml | 2 +- .github/skills/mattpocock-teach/SKILL.md | 10 +- .../mattpocock-teach/agents/openai.yaml | 6 +- .../mattpocock-to-questionnaire/SKILL.md | 53 +++ .../agents/openai.yaml | 5 + .github/skills/mattpocock-to-spec/SKILL.md | 12 +- .../mattpocock-to-spec/agents/openai.yaml | 6 +- .github/skills/mattpocock-to-tickets/SKILL.md | 12 +- .../mattpocock-to-tickets/agents/openai.yaml | 6 +- .../skills/mattpocock-triage/AGENT-BRIEF.md | 16 +- .../skills/mattpocock-triage/OUT-OF-SCOPE.md | 18 +- .github/skills/mattpocock-triage/SKILL.md | 20 +- .../mattpocock-triage/agents/openai.yaml | 6 +- .github/skills/mattpocock-wait-what/SKILL.md | 7 + .../mattpocock-wait-what/agents/openai.yaml | 5 + .github/skills/mattpocock-wayfinder/SKILL.md | 94 +----- .../mattpocock-wayfinder/agents/openai.yaml | 6 +- .github/skills/mattpocock-wizard/SKILL.md | 44 +++ .../mattpocock-wizard/agents/openai.yaml | 3 + .github/skills/mattpocock-wizard/template.sh | 204 ++++++++++++ .../SKILL-MECHANICS.md | 22 ++ .../mattpocock-writing-for-agents/SKILL.md | 81 +++++ .../agents/openai.yaml | 3 + .../GLOSSARY.md | 201 ----------- .../mattpocock-writing-great-skills/SKILL.md | 91 ----- .../agents/openai.yaml | 3 - .../scripts/test_candidate.py | 211 +++++++----- .../scripts/test_cli.py | 129 +++++++- .../scripts/test_manifest.py | 145 +++++--- ...test_external_resource_catalog_contract.py | 18 + 80 files changed, 1863 insertions(+), 1118 deletions(-) create mode 100644 .github/skills/grilling/SKILL.md create mode 100644 .github/skills/grilling/agents/openai.yaml create mode 100644 .github/skills/internal-grill-me/SKILL.md create mode 100644 .github/skills/internal-grill-me/agents/openai.yaml delete mode 100644 .github/skills/local-agent-sync-external-resources/patches/mattpocock-writing-great-skills-delegated-invocation.patch create mode 100644 .github/skills/mattpocock-ask-matt/PHASE-BOUNDARIES.md create mode 100644 .github/skills/mattpocock-ask-matt/SKILL.md create mode 100644 .github/skills/mattpocock-ask-matt/agents/openai.yaml create mode 100644 .github/skills/mattpocock-diagnosing-bugs/SKILL.md create mode 100644 .github/skills/mattpocock-diagnosing-bugs/agents/openai.yaml create mode 100644 .github/skills/mattpocock-diagnosing-bugs/scripts/hitl-loop.template.sh create mode 100644 .github/skills/mattpocock-prototype/LOGIC.md create mode 100644 .github/skills/mattpocock-prototype/SKILL.md create mode 100644 .github/skills/mattpocock-prototype/UI.md create mode 100644 .github/skills/mattpocock-prototype/agents/openai.yaml create mode 100644 .github/skills/mattpocock-resolving-merge-conflicts/SKILL.md create mode 100644 .github/skills/mattpocock-resolving-merge-conflicts/agents/openai.yaml create mode 100644 .github/skills/mattpocock-to-questionnaire/SKILL.md create mode 100644 .github/skills/mattpocock-to-questionnaire/agents/openai.yaml create mode 100644 .github/skills/mattpocock-wait-what/SKILL.md create mode 100644 .github/skills/mattpocock-wait-what/agents/openai.yaml create mode 100644 .github/skills/mattpocock-wizard/SKILL.md create mode 100644 .github/skills/mattpocock-wizard/agents/openai.yaml create mode 100644 .github/skills/mattpocock-wizard/template.sh create mode 100644 .github/skills/mattpocock-writing-for-agents/SKILL-MECHANICS.md create mode 100644 .github/skills/mattpocock-writing-for-agents/SKILL.md create mode 100644 .github/skills/mattpocock-writing-for-agents/agents/openai.yaml delete mode 100644 .github/skills/mattpocock-writing-great-skills/GLOSSARY.md delete mode 100644 .github/skills/mattpocock-writing-great-skills/SKILL.md delete mode 100644 .github/skills/mattpocock-writing-great-skills/agents/openai.yaml diff --git a/.github/INVENTORY.md b/.github/INVENTORY.md index f783a72c..a5d458ac 100644 --- a/.github/INVENTORY.md +++ b/.github/INVENTORY.md @@ -57,6 +57,7 @@ This file is the exact path inventory for the live GitHub Copilot catalog in thi - `.github/skills/awesome-copilot-secret-scanning/SKILL.md` - `.github/skills/awesome-copilot-security-review/SKILL.md` - `.github/skills/grill-me/SKILL.md` +- `.github/skills/grilling/SKILL.md` - `.github/skills/internal-agent-creator/SKILL.md` - `.github/skills/internal-aws-governance/SKILL.md` - `.github/skills/internal-aws-lambda/SKILL.md` @@ -99,6 +100,7 @@ This file is the exact path inventory for the live GitHub Copilot catalog in thi - `.github/skills/internal-github-strategic/SKILL.md` - `.github/skills/internal-github/SKILL.md` - `.github/skills/internal-go/SKILL.md` +- `.github/skills/internal-grill-me/SKILL.md` - `.github/skills/internal-java-project/SKILL.md` - `.github/skills/internal-java-spring-boot-development/SKILL.md` - `.github/skills/internal-java/SKILL.md` @@ -130,22 +132,29 @@ This file is the exact path inventory for the live GitHub Copilot catalog in thi - `.github/skills/local-agent-sync-install-ai-resources/SKILL.md` - `.github/skills/local-copilot-log-analyzer/SKILL.md` - `.github/skills/local-sync-repos/SKILL.md` +- `.github/skills/mattpocock-ask-matt/SKILL.md` - `.github/skills/mattpocock-code-review/SKILL.md` - `.github/skills/mattpocock-codebase-design/SKILL.md` +- `.github/skills/mattpocock-diagnosing-bugs/SKILL.md` - `.github/skills/mattpocock-domain-modeling/SKILL.md` - `.github/skills/mattpocock-grill-with-docs/SKILL.md` - `.github/skills/mattpocock-handoff/SKILL.md` - `.github/skills/mattpocock-implement/SKILL.md` - `.github/skills/mattpocock-improve-codebase-architecture/SKILL.md` +- `.github/skills/mattpocock-prototype/SKILL.md` - `.github/skills/mattpocock-research/SKILL.md` +- `.github/skills/mattpocock-resolving-merge-conflicts/SKILL.md` - `.github/skills/mattpocock-setup-matt-pocock-skills/SKILL.md` - `.github/skills/mattpocock-tdd/SKILL.md` - `.github/skills/mattpocock-teach/SKILL.md` +- `.github/skills/mattpocock-to-questionnaire/SKILL.md` - `.github/skills/mattpocock-to-spec/SKILL.md` - `.github/skills/mattpocock-to-tickets/SKILL.md` - `.github/skills/mattpocock-triage/SKILL.md` +- `.github/skills/mattpocock-wait-what/SKILL.md` - `.github/skills/mattpocock-wayfinder/SKILL.md` -- `.github/skills/mattpocock-writing-great-skills/SKILL.md` +- `.github/skills/mattpocock-wizard/SKILL.md` +- `.github/skills/mattpocock-writing-for-agents/SKILL.md` - `.github/skills/openai-docs/SKILL.md` - `.github/skills/openai-gh-address-comments/SKILL.md` - `.github/skills/openai-gh-fix-ci/SKILL.md` diff --git a/.github/skills/grill-me/SKILL.md b/.github/skills/grill-me/SKILL.md index 207e836e..b64b3d19 100644 --- a/.github/skills/grill-me/SKILL.md +++ b/.github/skills/grill-me/SKILL.md @@ -1,52 +1,7 @@ --- +disable-model-invocation: true name: grill-me description: A relentless interview to sharpen a plan or design. --- -# Grill Me - -## Referenced skills - -- None. - -## Interview Approach - -Interview me relentlessly about every aspect of this plan, design, or action -context until we reach a shared understanding. Walk down each branch of the -decision tree, resolving dependencies between decisions one-by-one. - -Before asking, inspect the repository, codebase, documentation, or local files for answers that can be recovered from evidence. - -By default, ask the full initial question set in one numbered list. - -Structure the list by decision branch and dependency order. Start with goal and scope, then constraints, architecture or options, risks and failure modes, rollout, and validation as relevant. - -For each numbered question, use this format: Question, Recommendation, Why, and Default if accepted. Make the recommendation detailed enough to explain what you want to decide, why it matters, and what answer you would choose by default. - -Treat your recommendations as accepted unless the user says otherwise. The user may override any recommendation by referencing the question number or giving different direction. - -Do not treat accepted recommendations as the end of the grilling process. If accepted defaults create contradictions, weak assumptions, unresolved risks, or dependent decisions, surface them explicitly. - -After the initial numbered list, ask one question at a time only for unresolved ambiguity, dependent follow-up decisions, or branches that cannot be settled from the user's bulk response. - -A caller may override the follow-up pacing with iterative numbered blocks. When a caller declares that override, replace the default one-at-a-time follow-up with the caller's pacing. - -Do not ask questions that can be answered by exploring the codebase, documentation, or local files. - -End by summarizing the resolved decisions, explicit assumptions, and any -unresolved questions the user chose to accept or defer. - - -## Local guided-question contract - -This repository-owned contract overrides any earlier instruction to ask one question at a time. - -- Ask all currently known questions in numbered bulk question blocks. -- Use `Question`, `Recommendation`, `Why`, and `Default if accepted` for every - numbered question. -- Make `Recommendation` the suggested answer and `Why` its concrete rationale. -- Keep each question, recommendation, and reason brief, clear, and - decision-ready. -- Put unresolved follow-ups in another numbered block. If only one blocking - question remains, present it as a numbered one-item block. - +Run a `/grilling` session. diff --git a/.github/skills/grill-me/agents/openai.yaml b/.github/skills/grill-me/agents/openai.yaml index 79d19f2f..a0b5015b 100644 --- a/.github/skills/grill-me/agents/openai.yaml +++ b/.github/skills/grill-me/agents/openai.yaml @@ -1,3 +1,5 @@ interface: - display_name: "grill-me" - short_description: "Relentless interview to sharpen a plan or design" + display_name: Grill Me + short_description: Sharpen a plan through interview +policy: + allow_implicit_invocation: false diff --git a/.github/skills/grilling/SKILL.md b/.github/skills/grilling/SKILL.md new file mode 100644 index 00000000..95bd01ee --- /dev/null +++ b/.github/skills/grilling/SKILL.md @@ -0,0 +1,22 @@ +--- +name: grilling +description: Grill the user relentlessly about a plan, decision, or idea. Use when the user wants to stress-test their thinking, or uses any 'grill' trigger phrases. +--- + +Interview the user relentlessly until you reach a shared understanding. Map this as a **design tree**: every decision branches into the decisions that hang off it. + +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 the user's answers before the next round. + +Each question should be formatted like so: + +``` +❓ **Q1** - ****: + +➡️ +``` + +Each round the user answers reshapes 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 the user's. When a frontier question needs a fact from the environment (filesystem, tools, etc.), dispatch a sub-agent to find it — don't ask the user for anything you could look up yourself. Don't block on it: a running exploration is an unsettled prerequisite, so only the questions downstream of it wait for the sub-agent to report — ask the rest of the frontier now. The _decisions_ are the user's — put each to them and wait. + +The session is done when the frontier is empty: every branch of the design tree visited, nothing left silently assumed. Do not act on it until the user confirms you have reached a shared understanding. diff --git a/.github/skills/grilling/agents/openai.yaml b/.github/skills/grilling/agents/openai.yaml new file mode 100644 index 00000000..ddbdb961 --- /dev/null +++ b/.github/skills/grilling/agents/openai.yaml @@ -0,0 +1,3 @@ +interface: + display_name: "Grilling" + short_description: "Stress-test thinking a round of questions at a time" diff --git a/.github/skills/internal-grill-me/SKILL.md b/.github/skills/internal-grill-me/SKILL.md new file mode 100644 index 00000000..ca9ed631 --- /dev/null +++ b/.github/skills/internal-grill-me/SKILL.md @@ -0,0 +1,57 @@ +--- +name: internal-grill-me +description: Use only when explicitly invoking the legacy bulk interview contract for a plan or design. +--- + +# Internal Grill Me + +## Referenced skills + +- None. + +## When to use + +- Use only when the user explicitly requests `/internal-grill-me` and its + legacy bulk interview format. + +## Interview Approach + +Interview me relentlessly about every aspect of this plan, design, or action +context until we reach a shared understanding. Walk down each branch of the +decision tree, resolving dependencies between decisions one-by-one. + +Before asking, inspect the repository, codebase, documentation, or local files for answers that can be recovered from evidence. + +By default, ask the full initial question set in one numbered list. + +Structure the list by decision branch and dependency order. Start with goal and scope, then constraints, architecture or options, risks and failure modes, rollout, and validation as relevant. + +For each numbered question, use this format: Question, Recommendation, Why, and Default if accepted. Make the recommendation detailed enough to explain what you want to decide, why it matters, and what answer you would choose by default. + +Treat your recommendations as accepted unless the user says otherwise. The user may override any recommendation by referencing the question number or giving different direction. + +Do not treat accepted recommendations as the end of the grilling process. If accepted defaults create contradictions, weak assumptions, unresolved risks, or dependent decisions, surface them explicitly. + +After the initial numbered list, ask one question at a time only for unresolved ambiguity, dependent follow-up decisions, or branches that cannot be settled from the user's bulk response. + +A caller may override the follow-up pacing with iterative numbered blocks. When a caller declares that override, replace the default one-at-a-time follow-up with the caller's pacing. + +Do not ask questions that can be answered by exploring the codebase, documentation, or local files. + +End by summarizing the resolved decisions, explicit assumptions, and any +unresolved questions the user chose to accept or defer. + + +## Local guided-question contract + +This repository-owned contract overrides any earlier instruction to ask one question at a time. + +- Ask all currently known questions in numbered bulk question blocks. +- Use `Question`, `Recommendation`, `Why`, and `Default if accepted` for every + numbered question. +- Make `Recommendation` the suggested answer and `Why` its concrete rationale. +- Keep each question, recommendation, and reason brief, clear, and + decision-ready. +- Put unresolved follow-ups in another numbered block. If only one blocking + question remains, present it as a numbered one-item block. + diff --git a/.github/skills/internal-grill-me/agents/openai.yaml b/.github/skills/internal-grill-me/agents/openai.yaml new file mode 100644 index 00000000..36e437a1 --- /dev/null +++ b/.github/skills/internal-grill-me/agents/openai.yaml @@ -0,0 +1,6 @@ +interface: + display_name: "Internal Grill Me" + short_description: "Explicit legacy bulk interview contract" + default_prompt: "Use $internal-grill-me to run the explicit legacy bulk interview contract." +policy: + allow_implicit_invocation: false diff --git a/.github/skills/internal-skill-creator/SKILL.md b/.github/skills/internal-skill-creator/SKILL.md index 5cac6495..291861c4 100644 --- a/.github/skills/internal-skill-creator/SKILL.md +++ b/.github/skills/internal-skill-creator/SKILL.md @@ -7,7 +7,7 @@ description: Use when creating, materially revising, replacing, or retiring repo ## Core method -`/mattpocock-writing-great-skills` is the core method for skill authoring and +`/mattpocock-writing-for-agents` is the core method for skill authoring and revision. Load it before drafting. Apply its relevant rules throughout the change instead of repeating them here. @@ -82,7 +82,7 @@ repository validation path are explicit. ### 2. Core authoring and revision -Load `/mattpocock-writing-great-skills` as the core method. Draft or revise the +Load `/mattpocock-writing-for-agents` as the core method. Draft or revise the smallest coherent bundle. Check invocation, description, information hierarchy, retrieval quality, and predictability. Remove duplication, sediment, and no-ops; revise the draft in place instead of only reporting findings. Apply the diff --git a/.github/skills/internal-skill-creator/agents/openai.yaml b/.github/skills/internal-skill-creator/agents/openai.yaml index d038f1fb..b91f1784 100644 --- a/.github/skills/internal-skill-creator/agents/openai.yaml +++ b/.github/skills/internal-skill-creator/agents/openai.yaml @@ -4,4 +4,4 @@ interface: brand_color: "#0E7490" icon_small: "./assets/icon-small.svg" icon_large: "./assets/icon.svg" - default_prompt: "Use $internal-skill-creator to create, revise, replace, or retire a repository-owned skill. Apply /mattpocock-writing-great-skills, prefix cross-skill invocations with `/`, and keep always-loaded surfaces cache-stable and within progressive-disclosure budgets per references/cache-and-token-efficiency.md. Delegate only after the objective, value gate, bounded evidence, constraints, exact write scope, output, acceptance, validation, and budget are fixed; use `read`, `plan`, or `write` only for bounded creator classes. Keep trivial, unresolved, incomplete, unverifiable, and competing-owner work local or blocked. Retain trigger, boundary, policy, scope, retry, independent validation, acceptance, semantic review, and closeout; verify one bound WorkerResult v1, default to one attempt, and retry only with new evidence plus a concrete correction target. When timeout, interruption, executor unavailability, or missing terminal output prevents a worker payload, record a caller-owned LifecycleRecord and create neither a synthetic WorkerResult nor a receipt." + default_prompt: "Use $internal-skill-creator to create, revise, replace, or retire a repository-owned skill. Apply /mattpocock-writing-for-agents, prefix cross-skill invocations with `/`, and keep always-loaded surfaces cache-stable and within progressive-disclosure budgets per references/cache-and-token-efficiency.md. Delegate only after the objective, value gate, bounded evidence, constraints, exact write scope, output, acceptance, validation, and budget are fixed; use `read`, `plan`, or `write` only for bounded creator classes. Keep trivial, unresolved, incomplete, unverifiable, and competing-owner work local or blocked. Retain trigger, boundary, policy, scope, retry, independent validation, acceptance, semantic review, and closeout; verify one bound WorkerResult v1, default to one attempt, and retry only with new evidence plus a concrete correction target. When timeout, interruption, executor unavailability, or missing terminal output prevents a worker payload, record a caller-owned LifecycleRecord and create neither a synthetic WorkerResult nor a receipt." diff --git a/.github/skills/local-agent-sync-external-resources/SKILL.md b/.github/skills/local-agent-sync-external-resources/SKILL.md index 6ceef5ab..07708105 100644 --- a/.github/skills/local-agent-sync-external-resources/SKILL.md +++ b/.github/skills/local-agent-sync-external-resources/SKILL.md @@ -33,6 +33,13 @@ read them from the manifest or the upstream commit. - `apply` performs `plan`, prepares missing snapshots, rejects dirty targets unless `--allow-dirty`, generates and checks one patch, applies once, rebuilds inventory, and reruns scoped validation. +- `--source ` limits any mode to one declared source and may be + repeated. Unknown IDs fail before execution. Plan and apply validate and + replay only overrides whose target belongs to a selected asset. Omitting the + option preserves the complete-catalog behavior. +- `audit --allow-dirty` suppresses only the dirty-target blocker while retaining + manifest and override validation. `apply --allow-dirty` remains an explicit + authorization to replace explained local target changes. ## Pinned Content Only @@ -49,9 +56,14 @@ read them from the manifest or the upstream commit. `canonical_name` values. - `skill_reference_aliases` are source-local and point only at declared canonical names. -- The `mattpocock-skills` source uses the `mattpocock-` prefix. Upstream - `/grilling` is normalized to `grill-me` through a declared source - replacement, not an alias. +- The `mattpocock-skills` source imports all 25 direct `engineering/` and + `productivity/` bundles from the pinned release. Keep `grill-me` and + `grilling` unprefixed; prefix the other 23 canonical names with + `mattpocock-`. +- Redirect Matt consumer references from `/grilling` to `/grill-me` only after + canonical reference rewriting. Exclude the canonical `grill-me` wrapper and + `grilling` engine so the wrapper continues to call its engine without + recursion. - References to undeclared skills remain unchanged and are reported as unresolved dependencies. @@ -64,8 +76,11 @@ read them from the manifest or the upstream commit. - Apply `invocation_policy` generically per asset. Its fields are `copilot.disable_model_invocation` and `codex.allow_implicit_invocation`; do not hardcode per-asset exceptions. -- `superpowers-brainstorming` is the declared exception: keep - `disable-model-invocation: true` in `SKILL.md` and set +- The Matt source declares the upstream 14 user-invoked skills explicitly and + leaves the 11 model-invoked skills unrestricted. Preserve this split in both + runtimes. +- `superpowers-brainstorming` remains an independently declared exception: + keep `disable-model-invocation: true` in `SKILL.md` and set `policy.allow_implicit_invocation: false` in `agents/openai.yaml`. - After refresh, manually verify that no policy-managed skill is implicitly selected in either runtime. @@ -80,38 +95,29 @@ read them from the manifest or the upstream commit. ## Guided Question Contract -- Append a repository-owned contract to `superpowers-brainstorming` and - `grill-me` whenever either canonical skill is managed, regardless of source. +- Append the repository-owned bulk-question contract only to + `superpowers-brainstorming`. - Require numbered bulk question blocks. Every question includes a brief `Recommendation`, `Why`, and `Default if accepted`. - Explicitly override upstream one-question-at-a-time pacing. A single remaining blocker is a numbered one-item block. - Use a marker-based idempotent append, never a context-sensitive replay patch. -## Wayfinder Critical Validation And Grilling Contracts - -- Append two repository-owned contracts to `mattpocock-wayfinder`. -- Before artifact creation or update, `internal-gateway-critical-master` must - challenge the analysis. Counter-validate every material critique against - evidence and constraints, incorporate every supported instruction, and stop - when a supported objection remains unresolved. -- One gate covers one analysis unit and its related content-producing write - batch. The required ticket claim is exempt and remains the first coordination - action. Rerun the critic only after new evidence or a materially supported - revision; never against unchanged evidence. -- Every Wayfinder Grilling ticket and `grill-me` invocation asks numbered bulk - blocks with `Question`, `Recommendation`, `Why`, and `Default if accepted`. -- Both contracts are canonical-name-scoped, marker-based, idempotent, and never - replay patches. - ## Repository-Owned Skill Contracts - Express additive behavior, workspace, and output-path requirements as canonical-name-scoped, marker-based candidate normalizations. - Each normalization replaces its own marked block, is idempotent, and preserves unrelated upstream content. -- Matt Pocock handoff output path and PRD-aware non-duplication wording are - canonical marked normalizations, not replay-patch ownership. +- Retain only the Matt Pocock Handoff, Teach, and Improve Architecture + repository paths. Keep Handoff non-duplication wording as a canonical marked + normalization rather than replay-patch ownership. +- Keep Matt Research output under `tmp/.research/`. Before delegation, the + caller applies a value gate; when delegation is worthwhile, it uses + `/internal-subagent-contract` and retains routing, authority, acceptance, and + validation. +- Do not add Git-autonomy, Wayfinder workspace, Wayfinder critical-validation, + Wayfinder grilling, or `grill-me` guided-question contracts to Matt imports. - Reserve replay patches for irreducible upstream-line edits. Record why a normalization is insufficient before registering an exception. - Register each approved in-place override in @@ -177,6 +183,8 @@ python3 scripts/sync_external_resources.py prepare --workspace ../cloud-strategy python3 scripts/sync_external_resources.py audit --format tsv python3 scripts/sync_external_resources.py plan --workspace ../cloud-strategy.github-external-refresh --format tsv python3 scripts/sync_external_resources.py apply --workspace ../cloud-strategy.github-external-refresh --format tsv +python3 scripts/sync_external_resources.py plan --source mattpocock-skills --workspace ../cloud-strategy.github-external-refresh --format tsv +python3 scripts/sync_external_resources.py apply --source mattpocock-skills --workspace ../cloud-strategy.github-external-refresh --format tsv ``` ## Live Network Benchmark (Separate Authorization Required) diff --git a/.github/skills/local-agent-sync-external-resources/patches/mattpocock-writing-great-skills-delegated-invocation.patch b/.github/skills/local-agent-sync-external-resources/patches/mattpocock-writing-great-skills-delegated-invocation.patch deleted file mode 100644 index 83d2e15a..00000000 --- a/.github/skills/local-agent-sync-external-resources/patches/mattpocock-writing-great-skills-delegated-invocation.patch +++ /dev/null @@ -1,11 +0,0 @@ -diff --git a/.github/skills/mattpocock-writing-great-skills/SKILL.md b/.github/skills/mattpocock-writing-great-skills/SKILL.md -index 0000000..0000000 100644 ---- a/.github/skills/mattpocock-writing-great-skills/SKILL.md -+++ b/.github/skills/mattpocock-writing-great-skills/SKILL.md -@@ -1,5 +1,5 @@ - --- - name: mattpocock-writing-great-skills --description: Reference for writing and editing skills well — the vocabulary and principles that make a skill predictable. -+description: Predictability review and revision stage applied after authoring. Loaded by internal-skill-creator after the Anthropic authoring stage when delegating skill work. - --- - diff --git a/.github/skills/local-agent-sync-external-resources/references/imported-asset-overrides.yaml b/.github/skills/local-agent-sync-external-resources/references/imported-asset-overrides.yaml index 3c02c3c5..66eeb9e4 100644 --- a/.github/skills/local-agent-sync-external-resources/references/imported-asset-overrides.yaml +++ b/.github/skills/local-agent-sync-external-resources/references/imported-asset-overrides.yaml @@ -60,17 +60,3 @@ overrides: baseline_repo_commit: 10cc5e9 validation_note: Stop the refresh if the patch does not apply cleanly; review whether the shortened company-knowledge trigger still covers internal search requests. -- id: mattpocock-writing-great-skills-delegated-invocation - target_path: .github/skills/mattpocock-writing-great-skills/SKILL.md - source_family: mattpocock/skills - lifecycle_mode: post-refresh-patch - apply_strategy: git-apply - approval: explicit-user-counter-validated - reason: Narrow the imported Matt Pocock writing-great-skills description to delegation-oriented - use by internal-skill-creator during the predictability review stage. The - source-wide normalization owns cross-runtime invocation compatibility. - patch_path: patches/mattpocock-writing-great-skills-delegated-invocation.patch - expected_content_hash: 7c285ac1270647ced867cf6d945c2ebf94d3f32794c349ee4a5140d00faf6f6f - baseline_repo_commit: ed37663cc5fbef691ddfecd080dff42f7e7e350d - validation_note: Stop the refresh if the patch does not apply cleanly; review whether - the delegation contract still matches the intended orchestration order. diff --git a/.github/skills/local-agent-sync-external-resources/references/managed-resources.yaml b/.github/skills/local-agent-sync-external-resources/references/managed-resources.yaml index 297b74ad..bba1503c 100644 --- a/.github/skills/local-agent-sync-external-resources/references/managed-resources.yaml +++ b/.github/skills/local-agent-sync-external-resources/references/managed-resources.yaml @@ -92,61 +92,159 @@ sources: canonical_name: superpowers-writing-plans mattpocock-skills: repository: https://github.com/mattpocock/skills.git - ref: ed37663cc5fbef691ddfecd080dff42f7e7e350d + ref: 6acc160e4e0cd062dbbbd7a1b26ae92855edf07e + advertised_ref: v1.2.3 rewrite_skill_references: true backtick_skill_references: - code-review - tdd - to-spec assets: - - upstream: skills/engineering/grill-with-docs - local: .github/skills/mattpocock-grill-with-docs - canonical_name: mattpocock-grill-with-docs - - upstream: skills/engineering/domain-modeling - local: .github/skills/mattpocock-domain-modeling - canonical_name: mattpocock-domain-modeling + - upstream: skills/engineering/ask-matt + local: .github/skills/mattpocock-ask-matt + canonical_name: mattpocock-ask-matt + invocation_policy: + copilot: + disable_model_invocation: true + codex: + allow_implicit_invocation: false + - upstream: skills/engineering/code-review + local: .github/skills/mattpocock-code-review + canonical_name: mattpocock-code-review - upstream: skills/engineering/codebase-design local: .github/skills/mattpocock-codebase-design canonical_name: mattpocock-codebase-design - - upstream: skills/engineering/improve-codebase-architecture - local: .github/skills/mattpocock-improve-codebase-architecture - canonical_name: mattpocock-improve-codebase-architecture + - upstream: skills/engineering/diagnosing-bugs + local: .github/skills/mattpocock-diagnosing-bugs + canonical_name: mattpocock-diagnosing-bugs + - upstream: skills/engineering/domain-modeling + local: .github/skills/mattpocock-domain-modeling + canonical_name: mattpocock-domain-modeling + - upstream: skills/engineering/grill-with-docs + local: .github/skills/mattpocock-grill-with-docs + canonical_name: mattpocock-grill-with-docs + invocation_policy: + copilot: + disable_model_invocation: true + codex: + allow_implicit_invocation: false - upstream: skills/engineering/implement local: .github/skills/mattpocock-implement canonical_name: mattpocock-implement - - upstream: skills/engineering/to-tickets - local: .github/skills/mattpocock-to-tickets - canonical_name: mattpocock-to-tickets + invocation_policy: + copilot: + disable_model_invocation: true + codex: + allow_implicit_invocation: false + - upstream: skills/engineering/improve-codebase-architecture + local: .github/skills/mattpocock-improve-codebase-architecture + canonical_name: mattpocock-improve-codebase-architecture + invocation_policy: + copilot: + disable_model_invocation: true + codex: + allow_implicit_invocation: false + - upstream: skills/engineering/prototype + local: .github/skills/mattpocock-prototype + canonical_name: mattpocock-prototype + - upstream: skills/engineering/research + local: .github/skills/mattpocock-research + canonical_name: mattpocock-research + - upstream: skills/engineering/resolving-merge-conflicts + local: .github/skills/mattpocock-resolving-merge-conflicts + canonical_name: mattpocock-resolving-merge-conflicts + - upstream: skills/engineering/setup-matt-pocock-skills + local: .github/skills/mattpocock-setup-matt-pocock-skills + canonical_name: mattpocock-setup-matt-pocock-skills + invocation_policy: + copilot: + disable_model_invocation: true + codex: + allow_implicit_invocation: false - upstream: skills/engineering/tdd local: .github/skills/mattpocock-tdd canonical_name: mattpocock-tdd - upstream: skills/engineering/to-spec local: .github/skills/mattpocock-to-spec canonical_name: mattpocock-to-spec - - upstream: skills/engineering/setup-matt-pocock-skills - local: .github/skills/mattpocock-setup-matt-pocock-skills - canonical_name: mattpocock-setup-matt-pocock-skills + invocation_policy: + copilot: + disable_model_invocation: true + codex: + allow_implicit_invocation: false + - upstream: skills/engineering/to-tickets + local: .github/skills/mattpocock-to-tickets + canonical_name: mattpocock-to-tickets + invocation_policy: + copilot: + disable_model_invocation: true + codex: + allow_implicit_invocation: false - upstream: skills/engineering/triage local: .github/skills/mattpocock-triage canonical_name: mattpocock-triage - - upstream: skills/engineering/code-review - local: .github/skills/mattpocock-code-review - canonical_name: mattpocock-code-review + invocation_policy: + copilot: + disable_model_invocation: true + codex: + allow_implicit_invocation: false - upstream: skills/engineering/wayfinder local: .github/skills/mattpocock-wayfinder canonical_name: mattpocock-wayfinder - - upstream: skills/engineering/research - local: .github/skills/mattpocock-research - canonical_name: mattpocock-research + invocation_policy: + copilot: + disable_model_invocation: true + codex: + allow_implicit_invocation: false + - upstream: skills/engineering/wizard + local: .github/skills/mattpocock-wizard + canonical_name: mattpocock-wizard + - upstream: skills/productivity/grill-me + local: .github/skills/grill-me + canonical_name: grill-me + invocation_policy: + copilot: + disable_model_invocation: true + codex: + allow_implicit_invocation: false + - upstream: skills/productivity/grilling + local: .github/skills/grilling + canonical_name: grilling - upstream: skills/productivity/handoff local: .github/skills/mattpocock-handoff canonical_name: mattpocock-handoff - - upstream: skills/productivity/writing-great-skills - local: .github/skills/mattpocock-writing-great-skills - canonical_name: mattpocock-writing-great-skills + invocation_policy: + copilot: + disable_model_invocation: true + codex: + allow_implicit_invocation: false - upstream: skills/productivity/teach local: .github/skills/mattpocock-teach canonical_name: mattpocock-teach + invocation_policy: + copilot: + disable_model_invocation: true + codex: + allow_implicit_invocation: false + - upstream: skills/productivity/to-questionnaire + local: .github/skills/mattpocock-to-questionnaire + canonical_name: mattpocock-to-questionnaire + invocation_policy: + copilot: + disable_model_invocation: true + codex: + allow_implicit_invocation: false + - upstream: skills/productivity/wait-what + local: .github/skills/mattpocock-wait-what + canonical_name: mattpocock-wait-what + invocation_policy: + copilot: + disable_model_invocation: true + codex: + allow_implicit_invocation: false + - upstream: skills/productivity/writing-for-agents + local: .github/skills/mattpocock-writing-for-agents + canonical_name: mattpocock-writing-for-agents vercel-labs-skills: repository: https://github.com/vercel-labs/skills.git ref: e173b8c88f2581cfdaa1b6767c6519a08155790e @@ -235,9 +333,6 @@ normalizations: - source: obra-superpowers from: docs/superpowers to: tmp/superpowers - - source: mattpocock-skills - from: /grilling - to: /grill-me watchlist: - source_family: github/awesome-copilot upstream_id: azure-devops-pipelines.instructions.md diff --git a/.github/skills/local-agent-sync-external-resources/scripts/sync_external_resources.py b/.github/skills/local-agent-sync-external-resources/scripts/sync_external_resources.py index b26cc2c3..00c56ef5 100644 --- a/.github/skills/local-agent-sync-external-resources/scripts/sync_external_resources.py +++ b/.github/skills/local-agent-sync-external-resources/scripts/sync_external_resources.py @@ -16,6 +16,7 @@ sys.path.insert(0, SCRIPT_DIR.as_posix()) from sync_external_resources_core import ( # noqa: E402 + ImportedOverride, ManagedAsset, ManagedResources, OverrideResult, @@ -196,7 +197,8 @@ def to_records(self) -> tuple[OutputRecord, ...]: def build_parser() -> argparse.ArgumentParser: parser = argparse.ArgumentParser( - description="Audit, plan, or apply declared external resource refreshes." + description="Audit, plan, or apply declared external resource refreshes.", + allow_abbrev=False, ) parser.add_argument("mode", choices=("prepare", "audit", "plan", "apply")) parser.add_argument("--repo-root", default=".") @@ -207,6 +209,12 @@ def build_parser() -> argparse.ArgumentParser: "--source-root", help="Use prepared source checkouts instead of network fetch.", ) + parser.add_argument( + "--source", + action="append", + dest="sources", + help="Limit the operation to one source ID; repeat to select more than one.", + ) parser.add_argument("--allow-dirty", action="store_true") parser.add_argument("--format", choices=("text", "tsv", "json"), default="text") parser.add_argument( @@ -217,6 +225,46 @@ def build_parser() -> argparse.ArgumentParser: return parser +def _select_resources( + resources: ManagedResources, requested_source_ids: Sequence[str] | None +) -> ManagedResources: + if not requested_source_ids: + return resources + + requested = set(requested_source_ids) + available = {source.source_id for source in resources.sources} + unknown = sorted(requested - available) + if unknown: + raise ValueError(f"unknown source id: {', '.join(unknown)}") + + return ManagedResources( + sources=tuple( + source for source in resources.sources if source.source_id in requested + ), + replacements=tuple( + replacement + for replacement in resources.replacements + if replacement.source in requested + ), + watchlist=resources.watchlist, + ) + + +def _applicable_overrides( + overrides: tuple[ImportedOverride, ...], resources: ManagedResources +) -> tuple[ImportedOverride, ...]: + managed_roots = tuple(asset.local.rstrip("/") for asset in resources.assets) + return tuple( + override + for override in overrides + if any( + override.target_path == root + or override.target_path.startswith(f"{root}/") + for root in managed_roots + ) + ) + + def _run_git(repo_root: Path, args: list[str]) -> subprocess.CompletedProcess[str]: result = subprocess.run( ["git", *args], @@ -425,15 +473,16 @@ def _audit( repo_root: Path, resources: ManagedResources, overrides_path: Path, + allow_dirty: bool, ) -> SyncOutcome: blockers: list[str] = [] dirty = find_dirty_targets(repo_root, resources.assets) - if dirty: + if dirty and not allow_dirty: blockers.append(f"dirty managed targets: {', '.join(dirty)}") validations: list[str] = ["manifest-parsed"] if overrides_path.exists(): - overrides = load_overrides(overrides_path) + overrides = _applicable_overrides(load_overrides(overrides_path), resources) validations.append("overrides-parsed") bundle_root = overrides_path.parent.parent try: @@ -521,7 +570,7 @@ def _plan( override_results: tuple[OverrideResult, ...] = () if overrides_path.exists(): - overrides = load_overrides(overrides_path) + overrides = _applicable_overrides(load_overrides(overrides_path), resources) bundle_root = overrides_path.parent.parent validate_override_patches(overrides, bundle_root) override_results = replay_overrides(candidate, overrides, bundle_root) @@ -582,7 +631,7 @@ def _apply( override_results: tuple[OverrideResult, ...] = () if overrides_path.exists(): - overrides = load_overrides(overrides_path) + overrides = _applicable_overrides(load_overrides(overrides_path), resources) bundle_root = overrides_path.parent.parent validate_override_patches(overrides, bundle_root) override_results = replay_overrides(candidate, overrides, bundle_root) @@ -650,7 +699,9 @@ def run(argv: Sequence[str] | None = None) -> int: if not overrides_path.is_absolute(): overrides_path = repo_root / overrides_path - resources = load_managed_resources(manifest_path) + resources = _select_resources( + load_managed_resources(manifest_path), args.sources + ) if args.mode == "prepare": if not args.workspace: @@ -664,7 +715,7 @@ def run(argv: Sequence[str] | None = None) -> int: elif args.mode == "audit": if args.rebuild_cache: parser.error("--rebuild-cache is only valid for prepare mode") - outcome = _audit(repo_root, resources, overrides_path) + outcome = _audit(repo_root, resources, overrides_path, args.allow_dirty) elif args.mode == "plan": if not args.workspace: parser.error("plan mode requires --workspace") diff --git a/.github/skills/local-agent-sync-external-resources/scripts/sync_external_resources_core.py b/.github/skills/local-agent-sync-external-resources/scripts/sync_external_resources_core.py index b7ad662c..19506eed 100644 --- a/.github/skills/local-agent-sync-external-resources/scripts/sync_external_resources_core.py +++ b/.github/skills/local-agent-sync-external-resources/scripts/sync_external_resources_core.py @@ -614,146 +614,19 @@ def materialize_candidate( allow_implicit_invocation: {allow_implicit_invocation} """ _MATTPOCOCK_SOURCE = "mattpocock-skills" -_MATTPOCOCK_GIT_AUTONOMY_CONTRACT_START = ( - "" -) -_MATTPOCOCK_GIT_AUTONOMY_CONTRACT_END = "" -_MATTPOCOCK_GIT_AUTONOMY_CONTRACT_RE = re.compile( - re.escape(_MATTPOCOCK_GIT_AUTONOMY_CONTRACT_START) - + r".*?" - + re.escape(_MATTPOCOCK_GIT_AUTONOMY_CONTRACT_END), - re.DOTALL, -) -_MATTPOCOCK_GIT_AUTONOMY_CONTRACT = f"""\ -{_MATTPOCOCK_GIT_AUTONOMY_CONTRACT_START} -## Local Git-autonomy contract - -- Keep completed changes in the working tree for user review. -- You may stage only changes owned by the current task when staging helps inspect the exact diff. -- Leave changes uncommitted and unpushed unless the current user explicitly requests the specific commit or push action. -- Keep pre-existing or unrelated user changes out of the index. -{_MATTPOCOCK_GIT_AUTONOMY_CONTRACT_END}""" -_MATTPOCOCK_LEGACY_PATHS = { - ".scratch/": "tmp/.issues/", - ".out-of-scope/": "tmp/.out-of-scope/", - "tmp/handoff/": "tmp/.handoff/", - "./tmp/teach/": "./tmp/.teach/", - "./tmp/codebase-improve/": "./tmp/.codebase-improve/", +_MATTPOCOCK_RETAINED_PATHS = { + ("mattpocock-handoff", "SKILL.md"): (("tmp/handoff/", "tmp/.handoff/"),), + ("mattpocock-teach", "SKILL.md"): (("./tmp/teach/", "./tmp/.teach/"),), + ( + "mattpocock-improve-codebase-architecture", + "HTML-REPORT.md", + ): (("./tmp/codebase-improve/", "./tmp/.codebase-improve/"),), + ( + "mattpocock-improve-codebase-architecture", + "SKILL.md", + ): (("./tmp/codebase-improve/", "./tmp/.codebase-improve/"),), } -_MATTPOCOCK_WAYFINDER_SKILL = "mattpocock-wayfinder" -_MATTPOCOCK_WAYFINDER_WORKSPACE_CONTRACT_START = ( - "" -) -_MATTPOCOCK_WAYFINDER_WORKSPACE_CONTRACT_END = ( - "" -) -_MATTPOCOCK_WAYFINDER_WORKSPACE_CONTRACT_RE = re.compile( - re.escape(_MATTPOCOCK_WAYFINDER_WORKSPACE_CONTRACT_START) - + r".*?" - + re.escape(_MATTPOCOCK_WAYFINDER_WORKSPACE_CONTRACT_END), - re.DOTALL, -) -_MATTPOCOCK_WAYFINDER_WORKSPACE_CONTRACT = f"""\ -{_MATTPOCOCK_WAYFINDER_WORKSPACE_CONTRACT_START} -## Local Wayfinder workspace contract - -This repository-owned contract overrides earlier workspace and output-path -instructions. - -- Keep each Wayfinder analysis unit under `tmp/.wayfinder//`. -- Keep its map at `tmp/.wayfinder//map.md` and its child tickets - under `tmp/.wayfinder//issues/`. -- Keep analysis, research findings, prototypes, and supporting assets inside the - same active Wayfinder workspace. -{_MATTPOCOCK_WAYFINDER_WORKSPACE_CONTRACT_END}""" -_MATTPOCOCK_WAYFINDER_CRITICAL_CONTRACT_START = ( - "" -) -_MATTPOCOCK_WAYFINDER_CRITICAL_CONTRACT_END = ( - "" -) -_MATTPOCOCK_WAYFINDER_CRITICAL_CONTRACT_RE = re.compile( - re.escape(_MATTPOCOCK_WAYFINDER_CRITICAL_CONTRACT_START) - + r".*?" - + re.escape(_MATTPOCOCK_WAYFINDER_CRITICAL_CONTRACT_END), - re.DOTALL, -) -_MATTPOCOCK_WAYFINDER_CRITICAL_CONTRACT = f"""\ -{_MATTPOCOCK_WAYFINDER_CRITICAL_CONTRACT_START} -## Local critical-validation contract - -Apply one critical-validation gate to one analysis unit. One analysis unit is a -charting batch, one claimed ticket's resolution batch, or a proposal batch for -a research or prototype artifact. The gate covers the entire batch of -content-producing writes derived from unchanged analysis; do not rerun it before -each artifact in that batch. - -The required ticket claim remains the first coordination action and is exempt -from this gate because it reserves work without publishing analysis or decision -content. - -1. Form the analysis and proposed decisions as internal working state. -2. Invoke `/internal-gateway-critical-master` once to challenge that analysis. -3. Counter-validate every material critique against the destination, repository - evidence, explicit constraints, success criteria, and anti-scope. Do not - accept an unsupported or conflicting instruction merely because the critic - proposed it. -4. Update the analysis by following every supported instruction from the critic. - Record rejected instructions and their evidence internally. -5. If a supported material objection remains unresolved, stop the artifact - batch. Do not rerun the critic against unchanged evidence; first obtain new - evidence or make a materially supported revision. -6. Run another critical challenge only when new evidence or that supported - revision changes a material claim. Once supported objections are resolved or - recorded as an explicit accepted risk, create the whole related artifact - batch without another gate while the analysis remains unchanged. - -Place the gate at these lifecycle boundaries: - -- While charting, run it after naming the destination and mapping the frontier, - immediately before creating the map and its ticket batch. -- While working a map, claim the ticket first. Run the gate after resolving the - ticket in working state and before the resolution comment, closure, - Decisions-so-far update, or newly surfaced ticket batch. -- Before producing a research or prototype artifact, challenge its proposal as - one unit. Treat the resulting findings or human reaction as new evidence that - requires a fresh gate only before a later decision-artifact batch. -{_MATTPOCOCK_WAYFINDER_CRITICAL_CONTRACT_END}""" -_MATTPOCOCK_WAYFINDER_GRILLING_CONTRACT_START = ( - "" -) -_MATTPOCOCK_WAYFINDER_GRILLING_CONTRACT_END = ( - "" -) -_MATTPOCOCK_WAYFINDER_GRILLING_CONTRACT_RE = re.compile( - re.escape(_MATTPOCOCK_WAYFINDER_GRILLING_CONTRACT_START) - + r".*?" - + re.escape(_MATTPOCOCK_WAYFINDER_GRILLING_CONTRACT_END), - re.DOTALL, -) -_MATTPOCOCK_WAYFINDER_GRILLING_CONTRACT = f"""\ -{_MATTPOCOCK_WAYFINDER_GRILLING_CONTRACT_START} -## Local Wayfinder grilling contract - -This contract applies to every Grilling ticket and every `/grill-me` or -upstream `/grilling` invocation made while charting or working a map. It -overrides any earlier one-question-at-a-time instruction. - -- Ask all currently known questions together in one numbered bulk block, - ordered by decision dependency. -- For every numbered question, include `Question`, `Recommendation`, `Why`, and - `Default if accepted`. -- Make `Recommendation` the suggested answer and `Why` the concrete reason for - that suggestion. Treat the default as accepted unless the user overrides it. -- Put newly discovered or unresolved follow-up questions together in another - numbered bulk block. If only one blocking question remains, use a numbered - one-item block. -{_MATTPOCOCK_WAYFINDER_GRILLING_CONTRACT_END}""" -_MATTPOCOCK_WAYFINDER_LEGACY_BRANCH_RE = re.compile( - r"captur(?:e|ing)\s+(?:its\s+)?findings\s+on\s+a\s+throwaway\s+" - r"`research/`\s+branch", - re.IGNORECASE, -) +_MATTPOCOCK_GRILLING_REDIRECT_EXCLUSIONS = frozenset({"grill-me", "grilling"}) _MATTPOCOCK_RESEARCH_SKILL = "mattpocock-research" _MATTPOCOCK_RESEARCH_WORKSPACE_CONTRACT_START = ( "" @@ -793,38 +666,19 @@ def materialize_candidate( {_MATTPOCOCK_RESEARCH_DELEGATION_CONTRACT_START} ## Local research-delegation contract -This repository-owned contract replaces the generic background-agent -instruction for research execution. - -- Delegate every research run to the `internal-luna-executor` subagent. -- Give Luna a self-contained brief with the question, context, primary-source - and citation requirements, output path, and validation expectations. -- Luna must research the question and write the single Markdown report directly - to the requested path. The caller verifies the result and does not repeat the - research or write a second report. -- Verify that the report exists, is non-empty, and includes source citations. -- If `internal-luna-executor` is unavailable or cannot complete the brief, - report a blocker instead of switching to another agent. -- This contract applies only where the named agent is available. Other runtimes - must report that the required executor is unsupported. +The caller owns a value gate before delegating research. Delegate only when a +bounded worker is likely to improve evidence quality, reduce material context +cost, or preserve useful parallel progress compared with direct research. + +- When the value gate passes, load `/internal-subagent-contract` and issue one + bounded brief with the question, context, primary-source and citation + requirements, output path, and validation expectations. +- The caller retains routing, authority, acceptance, and final validation. +- When delegation adds no clear value or no suitable worker is available, + research directly instead of manufacturing a delegation requirement. +- In either path, verify that the report exists, is non-empty, and includes + source citations. {_MATTPOCOCK_RESEARCH_DELEGATION_CONTRACT_END}""" -_MATTPOCOCK_RESEARCH_DESCRIPTION_START = ( - "# local-sync:research-description:start" -) -_MATTPOCOCK_RESEARCH_DESCRIPTION_END = "# local-sync:research-description:end" -_MATTPOCOCK_RESEARCH_DESCRIPTION_CONTRACT_RE = re.compile( - r"(?ms)^[ \t]*" - + re.escape(_MATTPOCOCK_RESEARCH_DESCRIPTION_START) - + r".*?^[ \t]*" - + re.escape(_MATTPOCOCK_RESEARCH_DESCRIPTION_END) - + r"[ \t]*$" -) -_MATTPOCOCK_RESEARCH_DESCRIPTION_LINE_RE = re.compile( - r"(?m)^(?P[ \t]*)short_description:.*$" -) -_MATTPOCOCK_RESEARCH_DESCRIPTION = ( - "Research from high-trust sources via Luna" -) _MATTPOCOCK_HANDOFF_SKILL = "mattpocock-handoff" _MATTPOCOCK_HANDOFF_WORKSPACE_CONTRACT_START = ( "" @@ -848,7 +702,7 @@ def materialize_candidate( - Save handoff documents under `tmp/.handoff/`. - Do not duplicate content already captured in other artifacts (PRDs, plans, ADRs, issues, commits, diffs). Reference them by path or URL instead. {_MATTPOCOCK_HANDOFF_WORKSPACE_CONTRACT_END}""" -_GUIDED_QUESTION_SKILLS = frozenset({"superpowers-brainstorming", "grill-me"}) +_GUIDED_QUESTION_SKILLS = frozenset({"superpowers-brainstorming"}) _GUIDED_QUESTION_CONTRACT_START = "" _GUIDED_QUESTION_CONTRACT_END = "" _GUIDED_QUESTION_CONTRACT_RE = re.compile( @@ -942,51 +796,30 @@ def _enforce_guided_question_contract(content: str) -> str: ) -def _normalize_mattpocock_legacy_paths(content: str) -> str: - for legacy_path, canonical_path in _MATTPOCOCK_LEGACY_PATHS.items(): - legacy_pattern = re.compile( - r"(? str: + for legacy_path, canonical_path in _MATTPOCOCK_RETAINED_PATHS.get( + (canonical_name, relative_path), () + ): + legacy_pattern = re.compile(r"(? str: - return _MATTPOCOCK_WAYFINDER_LEGACY_BRANCH_RE.sub( - "keeping findings in the caller-owned Wayfinder workspace", - content, - ) - - -def _enforce_mattpocock_git_autonomy_contract(content: str) -> str: - return _enforce_marked_contract( - content, - _MATTPOCOCK_GIT_AUTONOMY_CONTRACT_RE, - _MATTPOCOCK_GIT_AUTONOMY_CONTRACT, - ) - - -def _enforce_mattpocock_wayfinder_workspace_contract(content: str) -> str: - return _enforce_marked_contract( - content, - _MATTPOCOCK_WAYFINDER_WORKSPACE_CONTRACT_RE, - _MATTPOCOCK_WAYFINDER_WORKSPACE_CONTRACT, - ) - - -def _enforce_mattpocock_wayfinder_critical_contract(content: str) -> str: - return _enforce_marked_contract( - content, - _MATTPOCOCK_WAYFINDER_CRITICAL_CONTRACT_RE, - _MATTPOCOCK_WAYFINDER_CRITICAL_CONTRACT, - ) - - -def _enforce_mattpocock_wayfinder_grilling_contract(content: str) -> str: - return _enforce_marked_contract( +def _redirect_mattpocock_grilling_consumers( + canonical_name: str, + content: str, +) -> str: + if canonical_name in _MATTPOCOCK_GRILLING_REDIRECT_EXCLUSIONS: + return content + return _SLASH_SKILL_REF_RE.sub( + lambda match: "/grill-me" + if match.group("name") == "grilling" + else match.group(0), content, - _MATTPOCOCK_WAYFINDER_GRILLING_CONTRACT_RE, - _MATTPOCOCK_WAYFINDER_GRILLING_CONTRACT, ) @@ -1006,26 +839,6 @@ def _enforce_mattpocock_research_delegation_contract(content: str) -> str: ) -def _enforce_mattpocock_research_description(content: str) -> str: - def replace_description(match: re.Match[str]) -> str: - indent = match.groupdict().get("indent") or " " - return "\n".join( - ( - f"{indent}{_MATTPOCOCK_RESEARCH_DESCRIPTION_START}", - f'{indent}short_description: "{_MATTPOCOCK_RESEARCH_DESCRIPTION}"', - f"{indent}{_MATTPOCOCK_RESEARCH_DESCRIPTION_END}", - ) - ) - - if _MATTPOCOCK_RESEARCH_DESCRIPTION_CONTRACT_RE.search(content): - return _MATTPOCOCK_RESEARCH_DESCRIPTION_CONTRACT_RE.sub( - replace_description, content, count=1 - ) - return _MATTPOCOCK_RESEARCH_DESCRIPTION_LINE_RE.sub( - replace_description, content, count=1 - ) - - def _enforce_mattpocock_handoff_workspace_contract(content: str) -> str: return _enforce_marked_contract( content, @@ -1181,6 +994,10 @@ def normalize_candidate( ), content, ) + if asset.source == _MATTPOCOCK_SOURCE: + content = _redirect_mattpocock_grilling_consumers( + asset.canonical_name, content + ) backtick_references = backtick_references_by_source.get(asset.source, {}) if backtick_references: content = _BACKTICK_SKILL_REF_RE.sub( @@ -1193,14 +1010,11 @@ def normalize_candidate( ) if asset.source == _MATTPOCOCK_SOURCE: - content = _normalize_mattpocock_legacy_paths(content) - if ( - asset.canonical_name == _MATTPOCOCK_WAYFINDER_SKILL - and file_path == asset_dir / "SKILL.md" - ): - content = _normalize_mattpocock_wayfinder_legacy_instruction( - content - ) + content = _normalize_mattpocock_retained_paths( + asset.canonical_name, + file_path.relative_to(asset_dir).as_posix(), + content, + ) if ( asset.canonical_name in _GUIDED_QUESTION_SKILLS @@ -1218,14 +1032,6 @@ def normalize_candidate( and file_path.parent == asset_dir ): content = _enforce_codebase_improve_workspace_contract(content) - if ( - asset.source == _MATTPOCOCK_SOURCE - and asset.canonical_name == _MATTPOCOCK_WAYFINDER_SKILL - and file_path == asset_dir / "SKILL.md" - ): - content = _enforce_mattpocock_wayfinder_workspace_contract(content) - content = _enforce_mattpocock_wayfinder_critical_contract(content) - content = _enforce_mattpocock_wayfinder_grilling_contract(content) if ( asset.source == _MATTPOCOCK_SOURCE and asset.canonical_name == _MATTPOCOCK_RESEARCH_SKILL @@ -1233,23 +1039,12 @@ def normalize_candidate( ): content = _enforce_mattpocock_research_workspace_contract(content) content = _enforce_mattpocock_research_delegation_contract(content) - if ( - asset.source == _MATTPOCOCK_SOURCE - and asset.canonical_name == _MATTPOCOCK_RESEARCH_SKILL - and file_path == asset_dir / "agents/openai.yaml" - ): - content = _enforce_mattpocock_research_description(content) if ( asset.source == _MATTPOCOCK_SOURCE and asset.canonical_name == _MATTPOCOCK_HANDOFF_SKILL and file_path == asset_dir / "SKILL.md" ): content = _enforce_mattpocock_handoff_workspace_contract(content) - if ( - asset.source == _MATTPOCOCK_SOURCE - and file_path == asset_dir / "SKILL.md" - ): - content = _enforce_mattpocock_git_autonomy_contract(content) for replacement in replacements_by_source.get(asset.source, []): content = content.replace(replacement.old, replacement.new) diff --git a/.github/skills/mattpocock-ask-matt/PHASE-BOUNDARIES.md b/.github/skills/mattpocock-ask-matt/PHASE-BOUNDARIES.md new file mode 100644 index 00000000..55f4f1ae --- /dev/null +++ b/.github/skills/mattpocock-ask-matt/PHASE-BOUNDARIES.md @@ -0,0 +1,55 @@ +# Phase boundaries + +A **phase** is a chunk of work inside a session — the grilling, the implementation, the QA. The definition is fuzzy on purpose: a phase ends when you think *"ok, we're done with that"*. + +The **phase boundary** is the gap between two phases, and it is the only place this decision belongs. Mid-phase there is no decision to make — continue, or split the work that's left into subagents. Compacting mid-phase makes the agent lose the thread. + +## The five options + +| Option | What it does | +| ------------ | --------------------------------------------------------------- | +| **Continue** | Stay in the session. No context switch at all. | +| **`/clear`** | Empty the context window and start from nothing. | +| **`/mattpocock-handoff`** | Write a portable markdown file and seed a session anywhere with it. | +| **Subagent** | Send the task to its own context window and get a report back. | +| **`/compact`** | Compress this context and seed a fresh session with the summary. | + +## The tree + +Work top to bottom at the boundary. The first **yes** wins. + +**1. Can you continue in this session?** Two things make the answer yes: the next phase needs this phase as a **primary source**, or you have enough [smart zone](https://www.aihero.dev/ai-coding-dictionary/smart-zone) left (~150k tokens) for the next phase to fit. Grilling → implementation is the standard yes: the implementation wants the reasoning verbatim, not a summary of it. Continue costs nothing and loses nothing, so rule it out before anything else. + +**2. Is the context irrelevant to what comes next?** Is everything in this session — the exploration, the decisions, the dead ends — disposable? If so, **`/clear`**. It is the cheapest move on the board: it takes no time and hands back the whole window. `/clear` also isn't terminal — the old session stays resumable. + +The cost of getting this wrong is one-way. Clear a *relevant* context and you lose the **why** behind what you built, and no amount of reading the diff back gets it returned. + +**3. Do you need to hand off?** `/mattpocock-handoff` is narrow. You need it only when you are: + +- swapping to a **new harness** (Claude → Codex), +- moving to a **new directory** or repo, +- sending the work to a **colleague**, +- or forking a side task you found **mid-phase** without derailing what you're doing. + +That list is the whole clause. What `/mattpocock-handoff` buys is **portability** — a file that travels. If nothing is travelling, you don't need it. + +**4. Can the task be done AFK?** Is it scoped tightly enough to run with you away from the keyboard, no steering? Then send it to a **subagent** and leave this session untouched. Automated review is the standard case: the agent reads the diff and reports, and you aren't needed while it does. + +**5. Otherwise, `/compact`.** Relevant context, same harness, same directory, and you need to stay in the loop — this is where the tree lands, and it lands here often. Pass it an instruction (`/compact we're going to QA this area`) so the summary keeps what the next phase needs. + +`/compact` is the **default, not the first reach**. It sits at the bottom because the four questions above it are all cheaper or more precise. The failure mode when people start here is a fresh session that is confidently wrong about a decision the summary flattened. + +## Primary and secondary sources + +Every move except **Continue** turns a **primary source** into a **secondary source** — the session as it happened, replaced by a summary of it. The trade is always the same shape: + +| Source | Information | Noise | Room to move | +| --------------------------------- | ----------- | ----- | ------------ | +| Primary (Continue) | Full | Lots | Little | +| Secondary (`/compact`, `/mattpocock-handoff`) | Lossy | Less | Lots | + +This is why question 1 comes first. You only pay the lossiness when staying costs more than it saves. + +## These are judgement calls + +The questions are not objective — each has taste in it, and the same boundary can go two ways on two days. The value is in asking them **in order**, at the boundary rather than in the middle of the work. diff --git a/.github/skills/mattpocock-ask-matt/SKILL.md b/.github/skills/mattpocock-ask-matt/SKILL.md new file mode 100644 index 00000000..6b673de1 --- /dev/null +++ b/.github/skills/mattpocock-ask-matt/SKILL.md @@ -0,0 +1,90 @@ +--- +disable-model-invocation: true +name: mattpocock-ask-matt +description: Ask which skill or flow fits your situation. A router over the skills in this repo. +--- + +# Ask Matt + +You don't remember every skill, so ask. + +A **flow** is a path through the skills. Most paths run along one **main flow**, and two **on-ramps** merge onto it. Everything else is standalone, or a vocabulary layer that runs underneath. + +## The main flow: idea → ship + +The route most work travels. You have an idea and want it built. + +1. **`/mattpocock-grill-with-docs`** — sharpen the idea by interview. Start here whenever you are **working in a working directory**: it's stateful, retaining what it learns in `CONTEXT.md` and ADRs. (No working directory? Use `/grill-me` — see Standalone. Both run the same `/grill-me` primitive; `grill-with-docs` is the one that leaves a paper trail, which makes it the better of the two whenever a repo is there to leave it in.) +2. **Branch — can you settle every question in conversation?** If a question needs a runnable answer (state, business logic, a UI you have to see), detour through a prototype, bridged by **`/mattpocock-handoff`** in both directions (a prototype lives in its own directory, which is exactly what `/mattpocock-handoff` is for — see Phase boundaries): + - **`/mattpocock-handoff`** out, then open a fresh session against that file, + - **`/mattpocock-prototype`** to answer the question with throwaway code, + - **`/mattpocock-handoff`** back what you learned, and reference it from the original idea thread. +3. **Branch — is this a multi-session build?** + - **Yes** → **`/mattpocock-to-spec`** (turn the thread into a spec), then **`/mattpocock-to-tickets`** to split it into tracer-bullet tickets, each declaring its **blocking edges**. On a local tracker that's one file per ticket under `.scratch//issues/`, worked blockers-first by hand; on a real tracker the edges become native blocking links, so any ticket whose blockers are done can be grabbed — kick off **`/mattpocock-implement`** per ticket, **`/clear`ing context between each one**. Each ticket is self-contained, so the last one's context is disposable. + - **No** → **`/mattpocock-implement`** right here, in the same context window. + + Either way, **`/mattpocock-implement`** builds each issue by driving **`/mattpocock-tdd`** internally — one red-green slice at a time — then closes out by running **`/mattpocock-code-review`**, a two-axis review (Standards + Spec) of the diff, before committing. Reach for **`/mattpocock-tdd`** on its own when you just want to build a concrete behaviour test-first without a full spec, and **`/mattpocock-code-review`** on its own whenever you want to review a branch or PR against a fixed point. + +### Context hygiene + +Keep steps 1–3 in **one unbroken context window** — don't compact or clear until after `/mattpocock-to-tickets` — so the grilling, spec, and tickets all build on the same thinking. Each `/mattpocock-implement` then starts fresh, working from the ticket. + +The limit on this is the **[smart zone](https://www.aihero.dev/ai-coding-dictionary/smart-zone)**: the window (~150k tokens on state-of-the-art models) within which the model still reasons sharply. If a session approaches it before `/mattpocock-to-tickets`, don't push on degraded — `/compact` at the nearest phase boundary and carry on (see Phase boundaries). + +## On-ramps + +A starting situation that generates work, then merges onto the main flow. + +- **Bugs and requests piling up** → **`/mattpocock-triage`**. It moves issues through triage roles and produces agent-ready issues, which **`/mattpocock-implement`** later picks up. + + Triage is only for issues **you didn't create** — bug reports, incoming feature requests, anything that arrives raw. Tickets that `/mattpocock-to-tickets` produced are already agent-ready, so **don't triage them**. + +- **Something's broken** → **`/mattpocock-diagnosing-bugs`**. For the hard ones: the bug that resists a first glance, the intermittent flake, the regression that crept in between two known-good states. It refuses to theorise until it has a **tight feedback loop** — one command that already goes red on *this* bug — then fixes with a regression test. Its post-mortem hands off to **`/mattpocock-improve-codebase-architecture`** when the real finding is that there's no good seam to lock the bug down. + +- **A huge, foggy effort — a greenfield project or a huge feature build, too big for one session** → **`/mattpocock-wayfinder`**, the most cognitively demanding flow here. When the way from here to the destination isn't visible yet, it charts a **shared map** of **decision tickets** on the issue tracker and resolves them one at a time — producing **decisions, not deliverables** — until the fog is pushed back and the way is clear. Where **`/mattpocock-grill-with-docs`** sharpens an idea you can hold in one session, wayfinder is for the idea you can't — and it's slower and denser, so save it for exactly that, never a well-scoped feature. + + When the map clears, **it hands off, it doesn't build**: merge onto the main flow at **`/mattpocock-to-spec`**, which collapses the map's linked decisions into a buildable plan, then `/mattpocock-to-tickets` and `/mattpocock-implement` as usual. Looping the map straight into `/mattpocock-implement` skips that collapse and throws the linked detail away — go straight to `/mattpocock-implement` only when the effort turned out genuinely small. + +## Codebase health + +Not feature work — upkeep. + +- **`/mattpocock-improve-codebase-architecture`** — run whenever you have a spare moment to keep the codebase good for agents to operate in. It surfaces **deepening opportunities**; picking one _generates an idea_ you can take into the main flow at `/mattpocock-grill-with-docs`. It's the survey that finds the candidates; **`/mattpocock-codebase-design`** (below) is the bench you design the chosen one on. + +## Vocabulary underneath + +Two model-invoked references that run *beneath* the other skills — each the single source of truth for its vocabulary. Reach for them directly when the **words**, not the process, are the problem; or let the skills above pull them in. + +- **`/mattpocock-domain-modeling`** — sharpen the project's *domain* language: challenge a fuzzy term, resolve an overloaded word ("account" doing three jobs), record a hard-to-reverse decision as an ADR. It's the active discipline `/mattpocock-grill-with-docs` drives to keep `CONTEXT.md` a clean glossary. +- **`/mattpocock-codebase-design`** — the deep-module vocabulary (module, interface, depth, seam, adapter, leverage, locality) for designing a module's *shape*: a lot of behaviour behind a small interface at a clean seam. `/mattpocock-tdd` and `/mattpocock-improve-codebase-architecture` both speak it. + +## Phase boundaries + +A **phase** is a chunk of work inside a session — the grilling, the implementation, the QA. At the **boundary** between two of them you have five options, and picking between them is the fuzziest decision in this whole map: + +- **Continue** — stay put. Costs nothing, loses nothing. +- **`/clear`** — empty the window, when nothing here matters to what's next. +- **`/mattpocock-handoff`** — write a portable markdown file. Narrow: only for a **new harness**, a **new directory**, a **colleague**, or forking a side task **mid-phase**. What it buys is portability. +- **Subagent** — send a tightly-scoped task to its own window and get a report back. +- **`/compact`** — compress this context and seed a fresh session with it. The **default**, at the bottom of the tree rather than the first reach. + +Read [PHASE-BOUNDARIES.md](PHASE-BOUNDARIES.md) for the ordered tree — the five questions, the reasoning behind each branch, and why the primary-source cost makes **Continue** the one to rule out first. Make the decision **at** a boundary; mid-phase, continue or split the rest into subagents. + +## Standalone + +Off the main flow entirely. + +- **`/grill-me`** — the same relentless interview as `/mattpocock-grill-with-docs`, but **stateless**: it saves nothing locally and builds no `CONTEXT.md`. Reach for it when you are **not working in a working directory** — sharpening a plan, a design, a piece of writing, anything with no repo under it. If you are in a working directory, use `/mattpocock-grill-with-docs` instead: it runs the same interview and leaves a paper trail, so it is strictly the better one. +- **`/grill-me`** — the interview primitive itself: rounds, the frontier, facts are the agent's job and decisions are yours. `/grill-me` and `/mattpocock-grill-with-docs` are the two named ways in, and `/mattpocock-triage`, `/mattpocock-wayfinder` and `/mattpocock-improve-codebase-architecture` all run it internally. Reach for it directly only when you want the interview with no wrapper around it. +- **`/mattpocock-resolving-merge-conflicts`** — work an in-progress merge or rebase conflict hunk by hunk, resolving by **intent** traced to each side's primary source rather than by picking lines, then finish the operation. It never runs `--abort`. Standalone and off every flow: reach for it when you are already mid-conflict. +- **`/mattpocock-prototype`** — a small, throwaway program that answers one design question: does this state model feel right, or what should this UI look like. Throwaway is a constraint on how the code is written, not a promise to destroy it: the answer folds into the real code, and the prototype itself is kept as a **primary source** on a `prototype/` branch out of main, pointed at from the implementation issue. It's the detour in step 2 of the main flow, but reach for it any time a design question is hard to settle on paper. +- **`/mattpocock-research`** — delegate reading legwork to a **background agent**: it investigates a question against **primary sources**, then leaves a cited Markdown file in the repo. Keep working while it reads. The file it produces is something to take *into* the main flow at `/mattpocock-grill-with-docs` — research feeds the thinking, it doesn't replace it. +- **`/mattpocock-to-questionnaire`** — when the thing blocking you isn't in your head or the codebase but in **someone else's**, this writes them a questionnaire to fill in. It's the inverse of `/grill-me`: instead of interviewing you about the subject, it interviews you about the **send** — who it's going to, what you need back — and aims the questions at the gap. What comes back is material for `/mattpocock-grill-with-docs` or `/mattpocock-to-spec`. +- **`/mattpocock-wizard`** — for the steps only a **human** can take: provisioning infrastructure, setting up credentials or CI secrets, clicking through an unfamiliar third-party dashboard, running a one-off migration or cutover. It generates an interactive bash script that opens each URL, captures each value, and writes it into `.env` and GitHub secrets — so the procedure stops being something you re-explain to an agent every time. Model-invoked, so the agent reaches for it the moment it hits a wall only you can pass. If the agent could just do it itself, it should; this is for where a human is genuinely in the loop. +- **`/mattpocock-wait-what`** — the corrective for a message that didn't land. Use it mid-conversation, inside any other skill, and the agent re-pitches what it just said with the context you were missing, in plain English, using the `CONTEXT.md` vocabulary. It works after the fact; `/mattpocock-grill-with-docs` is the upfront cure, because a shared language agreed early is what stops the jargon arriving at all. +- **`/mattpocock-teach`** — learn a concept over multiple sessions, using the current directory as a stateful workspace. +- **`/mattpocock-writing-for-agents`** — reference for writing documents agents consume: skills, AGENTS.md, pointed-at docs. + +## Precondition + +**`/mattpocock-setup-matt-pocock-skills`** — run before your first engineering flow to configure the issue tracker, triage labels, and doc layout the other skills assume. Custom issue trackers also work. diff --git a/.github/skills/mattpocock-ask-matt/agents/openai.yaml b/.github/skills/mattpocock-ask-matt/agents/openai.yaml new file mode 100644 index 00000000..10835f32 --- /dev/null +++ b/.github/skills/mattpocock-ask-matt/agents/openai.yaml @@ -0,0 +1,5 @@ +interface: + display_name: Ask Matt + short_description: Find the right skill or workflow +policy: + allow_implicit_invocation: false diff --git a/.github/skills/mattpocock-code-review/SKILL.md b/.github/skills/mattpocock-code-review/SKILL.md index c055b6bd..375195a9 100644 --- a/.github/skills/mattpocock-code-review/SKILL.md +++ b/.github/skills/mattpocock-code-review/SKILL.md @@ -1,12 +1,12 @@ --- name: mattpocock-code-review -description: Review the changes since a fixed point (commit, branch, tag, or merge-base) along two axes — Standards (does the code follow this repo's documented coding standards?) and Spec (does the code match what the originating issue/PRD asked for?). Runs both reviews in parallel sub-agents and reports them side by side. Use when the user wants to review a branch, a PR, work-in-progress changes, or asks to "review since X". +description: Review the changes since a fixed point (commit, branch, tag, or merge-base) along two axes — Standards (does the code follow this repo's documented coding standards?) and Spec (does the code match what the originating issue/spec asked for?). Runs both reviews in parallel sub-agents and reports them side by side. Use when the user wants to review a branch, a PR, work-in-progress changes, or asks to "review since X". --- Two-axis review of the diff between `HEAD` and a fixed point the user supplies: - **Standards** — does the code conform to this repo's documented coding standards? -- **Spec** — does the code faithfully implement the originating issue / PRD / spec? +- **Spec** — does the code faithfully implement the originating issue / spec? Both axes run as **parallel sub-agents** so they don't pollute each other's context, then this skill aggregates their findings. @@ -28,7 +28,7 @@ Look for the originating spec, in this order: 1. Issue references in the commit messages (`#123`, `Closes #45`, GitLab `!67`, etc.) — fetch via the workflow in `docs/agents/issue-tracker.md`. 2. A path the user passed as an argument. -3. A PRD/spec file under `docs/`, `specs/`, or `tmp/.issues/` matching the branch name or feature. +3. A spec file under `docs/`, `specs/`, or `.scratch/` matching the branch name or feature. 4. If nothing is found, ask the user where the spec is. If they say there isn't one, the **Spec** sub-agent will skip and report "no spec available". ### 3. Identify the standards sources @@ -57,8 +57,6 @@ Each smell reads *what it is* → *how to fix*; match it against the diff: ### 4. Spawn both sub-agents in parallel -Send a single message with two `Agent` tool calls. Use the `general-purpose` subagent for both. - **Standards sub-agent prompt** — include: - The full diff command and commit list. @@ -87,12 +85,3 @@ A change can pass one axis and fail the other: - Code that does exactly what the issue asked but breaks the project's conventions → **Spec pass, Standards fail.** Reporting them separately stops one axis from masking the other. - - -## Local Git-autonomy contract - -- Keep completed changes in the working tree for user review. -- You may stage only changes owned by the current task when staging helps inspect the exact diff. -- Leave changes uncommitted and unpushed unless the current user explicitly requests the specific commit or push action. -- Keep pre-existing or unrelated user changes out of the index. - diff --git a/.github/skills/mattpocock-code-review/agents/openai.yaml b/.github/skills/mattpocock-code-review/agents/openai.yaml index d40a5766..9076774b 100644 --- a/.github/skills/mattpocock-code-review/agents/openai.yaml +++ b/.github/skills/mattpocock-code-review/agents/openai.yaml @@ -1,3 +1,3 @@ interface: - display_name: "mattpocock-code-review" + display_name: "Code Review" short_description: "Review a diff on standards and spec" diff --git a/.github/skills/mattpocock-codebase-design/DESIGN-IT-TWICE.md b/.github/skills/mattpocock-codebase-design/DESIGN-IT-TWICE.md index 49a7c42a..8419ad6f 100644 --- a/.github/skills/mattpocock-codebase-design/DESIGN-IT-TWICE.md +++ b/.github/skills/mattpocock-codebase-design/DESIGN-IT-TWICE.md @@ -18,7 +18,7 @@ Show this to the user, then immediately proceed to Step 2. The user reads and th ### 2. Spawn sub-agents -Spawn 3+ sub-agents in parallel using the Agent tool. Each must produce a **radically different** interface for the deepened module. +Spawn 3+ sub-agents in parallel. Each must produce a **radically different** interface for the deepened module. Prompt each sub-agent with a separate technical brief (file paths, coupling details, dependency category from [DEEPENING.md](DEEPENING.md), what sits behind the seam). The brief is independent of the user-facing problem-space explanation in Step 1. Give each agent a different design constraint: diff --git a/.github/skills/mattpocock-codebase-design/SKILL.md b/.github/skills/mattpocock-codebase-design/SKILL.md index 7c113668..6b25bedb 100644 --- a/.github/skills/mattpocock-codebase-design/SKILL.md +++ b/.github/skills/mattpocock-codebase-design/SKILL.md @@ -112,12 +112,3 @@ Good interfaces make testing natural: - **Deepening a cluster given its dependencies** — see [DEEPENING.md](DEEPENING.md): dependency categories, seam discipline, and replace-don't-layer testing. - **Exploring alternative interfaces** — see [DESIGN-IT-TWICE.md](DESIGN-IT-TWICE.md): spin up parallel sub-agents to design the interface several radically different ways, then compare on depth, locality, and seam placement. - - -## Local Git-autonomy contract - -- Keep completed changes in the working tree for user review. -- You may stage only changes owned by the current task when staging helps inspect the exact diff. -- Leave changes uncommitted and unpushed unless the current user explicitly requests the specific commit or push action. -- Keep pre-existing or unrelated user changes out of the index. - diff --git a/.github/skills/mattpocock-codebase-design/agents/openai.yaml b/.github/skills/mattpocock-codebase-design/agents/openai.yaml index 3cec9480..3180715e 100644 --- a/.github/skills/mattpocock-codebase-design/agents/openai.yaml +++ b/.github/skills/mattpocock-codebase-design/agents/openai.yaml @@ -1,3 +1,3 @@ interface: - display_name: "mattpocock-codebase-design" + display_name: "Codebase Design" short_description: "Vocabulary for deep-module design" diff --git a/.github/skills/mattpocock-diagnosing-bugs/SKILL.md b/.github/skills/mattpocock-diagnosing-bugs/SKILL.md new file mode 100644 index 00000000..ead56981 --- /dev/null +++ b/.github/skills/mattpocock-diagnosing-bugs/SKILL.md @@ -0,0 +1,140 @@ +--- +name: mattpocock-diagnosing-bugs +description: Diagnosis loop for hard bugs and performance regressions. Use when the user says "diagnose"/"debug this", or reports something broken/throwing/failing/slow. +--- + +# Diagnosing Bugs + +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. + +## Phase 1 — Build a feedback loop + +**This is the skill.** Everything else is mechanical. If you have a **tight** pass/fail signal for the bug — one that goes red on _this_ bug — you will find the cause; bisection, hypothesis-testing, and instrumentation all just consume it. If you don't have one, no amount of staring at code will save you. + +Spend disproportionate effort here. **Be aggressive. Be creative. Refuse to give up.** + +### Ways to construct one — try them in roughly this order + +1. **Failing test** at whatever seam reaches the bug — unit, integration, e2e. +2. **Curl / HTTP script** against a running dev server. +3. **CLI invocation** with a fixture input, diffing stdout against a known-good snapshot. +4. **Headless browser script** (Playwright / Puppeteer) — drives the UI, asserts on DOM/console/network. +5. **Replay a captured trace.** Save a real network request / payload / event log to disk; replay it through the code path in isolation. +6. **Throwaway harness.** Spin up a minimal subset of the system (one service, mocked deps) that exercises the bug code path with a single function call. +7. **Property / fuzz loop.** If the bug is "sometimes wrong output", run 1000 random inputs and look for the failure mode. +8. **Bisection harness.** If the bug appeared between two known states (commit, dataset, version), automate "boot at state X, check, repeat" so you can `git bisect run` it. +9. **Differential loop.** Run the same input through old-version vs new-version (or two configs) and diff outputs. +10. **HITL bash script.** Last resort. If a human must click, drive _them_ with `scripts/hitl-loop.template.sh` so the loop is still structured. Captured output feeds back to you. + +Build the right feedback loop, and the bug is 90% fixed. + +### Tighten the loop + +Treat the loop as a product. Once you have _a_ loop, **tighten** it: + +- Can I make it faster? (Cache setup, skip unrelated init, narrow the test scope.) +- Can I make the signal sharper? (Assert on the specific symptom, not "didn't crash".) +- Can I make it more deterministic? (Pin time, seed RNG, isolate filesystem, freeze network.) + +A 30-second flaky loop is barely better than no loop; a 2-second deterministic one is tight — a debugging superpower. + +### Non-deterministic bugs + +The goal is not a clean repro but a **higher reproduction rate**. Loop the trigger 100×, parallelise, add stress, narrow timing windows, inject sleeps. A 50%-flake bug is debuggable; 1% is not — keep raising the rate until it's debuggable. + +### 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 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** (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). +- [ ] **Fast** — seconds, not minutes. +- [ ] **Agent-runnable** — you can run it unattended; a human in the loop only via `scripts/hitl-loop.template.sh`. + +If you catch yourself reading code to build a theory before this command exists, **stop — jumping straight to a hypothesis is the exact failure this skill prevents.** No red-capable command, no Phase 2. + +## Phase 2 — Reproduce + minimise + +Run the loop. Watch it go red — the bug appears. + +Confirm: + +- [ ] The loop produces the failure mode the **user** described — not a different failure that happens to be nearby. Wrong bug = wrong fix. +- [ ] The failure is reproducible across multiple runs (or, for non-deterministic bugs, reproducible at a high enough rate to debug against). +- [ ] You have captured the exact symptom (error message, wrong output, slow timing) so later phases can verify the fix actually addresses it. + +### Minimise + +Once it's red, shrink the repro to the **smallest scenario that still goes red**. Cut inputs, callers, config, data, and steps **one at a time**, re-running the loop after each cut — keep only what's load-bearing for the failure. + +Why bother: a minimal repro shrinks the hypothesis space in Phase 3 (fewer moving parts left to suspect) and becomes the clean regression test in Phase 5. + +Done when **every remaining element is load-bearing** — removing any one of them makes the loop go green. + +Do not proceed until you have reproduced **and** minimised. + +## Phase 3 — Hypothesise + +Generate **3–5 ranked hypotheses** before testing any of them. Single-hypothesis generation anchors on the first plausible idea. + +Each hypothesis must be **falsifiable**: state the prediction it makes. + +> Format: "If is the cause, then will make the bug disappear / will make it worse." + +If you cannot state the prediction, the hypothesis is a vibe — discard or sharpen it. + +**Show the ranked list to the user before testing.** They often have domain knowledge that re-ranks instantly ("we just deployed a change to #3"), or know hypotheses they've already ruled out. Cheap checkpoint, big time saver. Don't block on it — proceed with your ranking if the user is AFK. + +## Phase 4 — Instrument + +Each probe must map to a specific prediction from Phase 3. **Change one variable at a time.** + +Tool preference: + +1. **Debugger / REPL inspection** if the env supports it. One breakpoint beats ten logs. +2. **Targeted logs** at the boundaries that distinguish hypotheses. +3. Never "log everything and grep". + +**Tag every debug log** with a unique prefix, e.g. `[DEBUG-a4f2]`. Cleanup at the end becomes a single grep. Untagged logs survive; tagged logs die. + +**Perf branch.** For performance regressions, logs are usually wrong. Instead: establish a baseline measurement (timing harness, `performance.now()`, profiler, query plan), then bisect. Measure first, fix second. + +## Phase 5 — Fix + regression test + +Write the regression test **before the fix** — but only if there is a **correct seam** for it. + +A correct seam is one where the test exercises the **real bug pattern** as it occurs at the call site. If the only available seam is too shallow (single-caller test when the bug needs multiple callers, unit test that can't replicate the chain that triggered the bug), a regression test there gives false confidence. + +**If no correct seam exists, that itself is the finding.** Note it. The codebase architecture is preventing the bug from being locked down. Flag this for the next phase. + +If a correct seam exists: + +1. Turn the minimised repro into a failing test at that seam. +2. Watch it fail. +3. Apply the fix. +4. Watch it pass. +5. Re-run the Phase 1 feedback loop against the original (un-minimised) scenario. + +## Phase 6 — Cleanup + post-mortem + +Required before declaring done: + +- [ ] Original repro no longer reproduces (re-run the Phase 1 loop) +- [ ] Regression test passes (or absence of seam is documented) +- [ ] All `[DEBUG-...]` instrumentation removed (`grep` the prefix) +- [ ] Throwaway prototypes deleted (or moved to a clearly-marked debug location) +- [ ] The hypothesis that turned out correct is stated in the commit / PR message — so the next debugger learns + +**Then ask: what would have prevented this bug?** If the answer involves architectural change (no good test seam, tangled callers, hidden coupling) hand off to the `/mattpocock-improve-codebase-architecture` skill with the specifics. Make the recommendation **after** the fix is in, not before — you have more information now than when you started. diff --git a/.github/skills/mattpocock-diagnosing-bugs/agents/openai.yaml b/.github/skills/mattpocock-diagnosing-bugs/agents/openai.yaml new file mode 100644 index 00000000..a13a755a --- /dev/null +++ b/.github/skills/mattpocock-diagnosing-bugs/agents/openai.yaml @@ -0,0 +1,3 @@ +interface: + display_name: "Diagnosing Bugs" + short_description: "Diagnose hard bugs and regressions" diff --git a/.github/skills/mattpocock-diagnosing-bugs/scripts/hitl-loop.template.sh b/.github/skills/mattpocock-diagnosing-bugs/scripts/hitl-loop.template.sh new file mode 100644 index 00000000..43daedd1 --- /dev/null +++ b/.github/skills/mattpocock-diagnosing-bugs/scripts/hitl-loop.template.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# Human-in-the-loop reproduction loop. +# Copy this file, edit the steps below, and run it. +# The agent runs the script; the user follows prompts in their terminal. +# +# Usage: +# bash hitl-loop.template.sh +# +# Two helpers: +# step "" → show instruction, wait for Enter +# capture VAR "" → show question, read response into VAR +# +# At the end, captured values are printed as KEY=VALUE for the agent to parse. +# +# `capture` prints its value back to the terminal, where the agent reads it — so +# capture observations, and leave signing in to the user as a `step`. + +set -euo pipefail + +step() { + printf '\n>>> %s\n' "$1" + read -r -p " [Enter when done] " _ +} + +capture() { + local var="$1" question="$2" answer + printf '\n>>> %s\n' "$question" + read -r -p " > " answer + printf -v "$var" '%s' "$answer" +} + +# --- edit below --------------------------------------------------------- + +step "Open the app at http://localhost:3000 and sign in." + +capture ERRORED "Click the 'Export' button. Did it throw an error? (y/n)" + +capture ERROR_MSG "Paste the error message (or 'none'):" + +# --- edit above --------------------------------------------------------- + +printf '\n--- Captured ---\n' +printf 'ERRORED=%s\n' "$ERRORED" +printf 'ERROR_MSG=%s\n' "$ERROR_MSG" diff --git a/.github/skills/mattpocock-domain-modeling/SKILL.md b/.github/skills/mattpocock-domain-modeling/SKILL.md index d558ec0a..4dc6a570 100644 --- a/.github/skills/mattpocock-domain-modeling/SKILL.md +++ b/.github/skills/mattpocock-domain-modeling/SKILL.md @@ -72,12 +72,3 @@ Only offer to create an ADR when all three are true: 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). - - -## Local Git-autonomy contract - -- Keep completed changes in the working tree for user review. -- You may stage only changes owned by the current task when staging helps inspect the exact diff. -- Leave changes uncommitted and unpushed unless the current user explicitly requests the specific commit or push action. -- Keep pre-existing or unrelated user changes out of the index. - diff --git a/.github/skills/mattpocock-domain-modeling/agents/openai.yaml b/.github/skills/mattpocock-domain-modeling/agents/openai.yaml index 21953f36..7f1522d2 100644 --- a/.github/skills/mattpocock-domain-modeling/agents/openai.yaml +++ b/.github/skills/mattpocock-domain-modeling/agents/openai.yaml @@ -1,3 +1,3 @@ interface: - display_name: "mattpocock-domain-modeling" + display_name: "Domain Modeling" short_description: "Build and sharpen a domain model" diff --git a/.github/skills/mattpocock-grill-with-docs/SKILL.md b/.github/skills/mattpocock-grill-with-docs/SKILL.md index f4a8179f..2e2160db 100644 --- a/.github/skills/mattpocock-grill-with-docs/SKILL.md +++ b/.github/skills/mattpocock-grill-with-docs/SKILL.md @@ -1,15 +1,7 @@ --- +disable-model-invocation: true name: mattpocock-grill-with-docs description: A relentless interview to sharpen a plan or design, which also creates docs (ADR's and glossary) as we go. --- Run a `/grill-me` session, using the `/mattpocock-domain-modeling` skill. - - -## Local Git-autonomy contract - -- Keep completed changes in the working tree for user review. -- You may stage only changes owned by the current task when staging helps inspect the exact diff. -- Leave changes uncommitted and unpushed unless the current user explicitly requests the specific commit or push action. -- Keep pre-existing or unrelated user changes out of the index. - diff --git a/.github/skills/mattpocock-grill-with-docs/agents/openai.yaml b/.github/skills/mattpocock-grill-with-docs/agents/openai.yaml index 00bbd6a9..0f9fceab 100644 --- a/.github/skills/mattpocock-grill-with-docs/agents/openai.yaml +++ b/.github/skills/mattpocock-grill-with-docs/agents/openai.yaml @@ -1,3 +1,5 @@ interface: - display_name: "mattpocock-grill-with-docs" - short_description: "Grill a design and write its docs" + display_name: Grill with Docs + short_description: Grill a design and write its docs +policy: + allow_implicit_invocation: false diff --git a/.github/skills/mattpocock-handoff/SKILL.md b/.github/skills/mattpocock-handoff/SKILL.md index 1cdc9795..7d42bedc 100644 --- a/.github/skills/mattpocock-handoff/SKILL.md +++ b/.github/skills/mattpocock-handoff/SKILL.md @@ -1,14 +1,15 @@ --- +disable-model-invocation: true name: mattpocock-handoff description: Compact the current conversation into a handoff document for another agent to pick up. argument-hint: "What will the next session be used for?" --- -Write a handoff document summarising the current conversation so a fresh agent can continue the work. Save it under `tmp/.handoff/` in the current workspace, creating that directory if needed. +Write a handoff document summarising the current conversation so a fresh agent can continue the work. Save to the temporary directory of the user's OS - not the current workspace. Include a "suggested skills" section in the document, which suggests skills that the agent should invoke. -Do not duplicate content already captured in other artifacts (PRDs, plans, ADRs, issues, commits, diffs). Reference them by path or URL instead. +Do not duplicate content already captured in other artifacts (specs, plans, ADRs, issues, commits, diffs). Reference them by path or URL instead. Redact any sensitive information, such as API keys, passwords, or personally identifiable information. @@ -23,12 +24,3 @@ instructions. - Save handoff documents under `tmp/.handoff/`. - Do not duplicate content already captured in other artifacts (PRDs, plans, ADRs, issues, commits, diffs). Reference them by path or URL instead. - - -## Local Git-autonomy contract - -- Keep completed changes in the working tree for user review. -- You may stage only changes owned by the current task when staging helps inspect the exact diff. -- Leave changes uncommitted and unpushed unless the current user explicitly requests the specific commit or push action. -- Keep pre-existing or unrelated user changes out of the index. - diff --git a/.github/skills/mattpocock-handoff/agents/openai.yaml b/.github/skills/mattpocock-handoff/agents/openai.yaml index 44f16185..72c9396a 100644 --- a/.github/skills/mattpocock-handoff/agents/openai.yaml +++ b/.github/skills/mattpocock-handoff/agents/openai.yaml @@ -1,3 +1,5 @@ interface: - display_name: "mattpocock-handoff" - short_description: "Compact a conversation into a handoff" + display_name: Handoff + short_description: Compact a conversation into a handoff +policy: + allow_implicit_invocation: false diff --git a/.github/skills/mattpocock-implement/SKILL.md b/.github/skills/mattpocock-implement/SKILL.md index 0d245cf7..5bc34897 100644 --- a/.github/skills/mattpocock-implement/SKILL.md +++ b/.github/skills/mattpocock-implement/SKILL.md @@ -1,4 +1,5 @@ --- +disable-model-invocation: true name: mattpocock-implement description: "Implement a piece of work based on a spec or set of tickets." --- @@ -12,12 +13,3 @@ Run typechecking regularly, single test files regularly, and the full test suite Once done, use /mattpocock-code-review to review the work. Commit your work to the current branch. - - -## Local Git-autonomy contract - -- Keep completed changes in the working tree for user review. -- You may stage only changes owned by the current task when staging helps inspect the exact diff. -- Leave changes uncommitted and unpushed unless the current user explicitly requests the specific commit or push action. -- Keep pre-existing or unrelated user changes out of the index. - diff --git a/.github/skills/mattpocock-implement/agents/openai.yaml b/.github/skills/mattpocock-implement/agents/openai.yaml index e2b2d0d8..d783e497 100644 --- a/.github/skills/mattpocock-implement/agents/openai.yaml +++ b/.github/skills/mattpocock-implement/agents/openai.yaml @@ -1,3 +1,5 @@ interface: - display_name: "mattpocock-implement" - short_description: "Build work from a spec or tickets" + display_name: Implement + short_description: Build work from a spec or tickets +policy: + allow_implicit_invocation: false diff --git a/.github/skills/mattpocock-improve-codebase-architecture/SKILL.md b/.github/skills/mattpocock-improve-codebase-architecture/SKILL.md index 6417f908..82ab3dc5 100644 --- a/.github/skills/mattpocock-improve-codebase-architecture/SKILL.md +++ b/.github/skills/mattpocock-improve-codebase-architecture/SKILL.md @@ -1,4 +1,5 @@ --- +disable-model-invocation: true name: mattpocock-improve-codebase-architecture description: Scan a codebase for deepening opportunities, present them as a visual HTML report, then grill through whichever one you pick. --- @@ -23,7 +24,7 @@ This command is _informed_ by the project's domain model and built on a shared d Read the project's domain glossary (`CONTEXT.md`) 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: +Then spawn a sub-agent to walk the codebase. Don't follow rigid heuristics — explore organically and note where you experience friction: - Where does understanding one concept require bouncing between many small modules? - Where are modules **shallow** — interface nearly as complex as the implementation? @@ -80,12 +81,3 @@ instructions. diagrams, analysis, working state, and supporting files inside it. - Do not create codebase-improvement artifacts outside the active workspace. - - -## Local Git-autonomy contract - -- Keep completed changes in the working tree for user review. -- You may stage only changes owned by the current task when staging helps inspect the exact diff. -- Leave changes uncommitted and unpushed unless the current user explicitly requests the specific commit or push action. -- Keep pre-existing or unrelated user changes out of the index. - diff --git a/.github/skills/mattpocock-improve-codebase-architecture/agents/openai.yaml b/.github/skills/mattpocock-improve-codebase-architecture/agents/openai.yaml index 5f88ad97..44f5805b 100644 --- a/.github/skills/mattpocock-improve-codebase-architecture/agents/openai.yaml +++ b/.github/skills/mattpocock-improve-codebase-architecture/agents/openai.yaml @@ -1,3 +1,5 @@ interface: - display_name: "mattpocock-improve-codebase-architecture" - short_description: "Find and grill architecture improvements" + display_name: Improve Codebase Architecture + short_description: Find and grill architecture improvements +policy: + allow_implicit_invocation: false diff --git a/.github/skills/mattpocock-prototype/LOGIC.md b/.github/skills/mattpocock-prototype/LOGIC.md new file mode 100644 index 00000000..5f5a3fd5 --- /dev/null +++ b/.github/skills/mattpocock-prototype/LOGIC.md @@ -0,0 +1,67 @@ +# Logic Prototype + +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. So it speaks their 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 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). + +## Process + +### 1. State the question + +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 — make the question explicit so it can be checked later, whether the user is watching now or returning to it AFK. + +### 2. Isolate the logic in a portable module + +Put the actual logic — the bit that's answering the question — in a single `