From 5d871235fd721caddb5330538ee44de87cd0d822 Mon Sep 17 00:00:00 2001 From: marquesds Date: Mon, 13 Jul 2026 11:46:20 -0300 Subject: [PATCH] feat(skills): port adr-writing and context-gathering from audio-processor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit audio-processor's .agents/ harness had two generic skills that were missing from the upstream style harness: - adr-writing: SMART + STAR ADR format for architecture decisions that outlive a single PR. Generalized from the audio-processor version — service-specific subsystems and examples replaced with generic ones. - context-gathering: gather repo/Linear/Datadog/Notion/Slack/Git evidence before asking questions during requirements work. ai-contribution-disclosure was also considered but excluded — it was removed from style in a prior commit (c1cb68d) and the audio-processor copy is identical to what was deleted, so re-adding it would revert that decision. Catalog rows and eval cases added for both skills. Lint and tests pass. --- source/evals/skill-routing.yml | 15 ++++ source/rules/skills-catalog.md | 2 + source/skills/adr-writing.md | 136 +++++++++++++++++++++++++++++ source/skills/context-gathering.md | 61 +++++++++++++ 4 files changed, 214 insertions(+) create mode 100644 source/skills/adr-writing.md create mode 100644 source/skills/context-gathering.md diff --git a/source/evals/skill-routing.yml b/source/evals/skill-routing.yml index 483e472..fed2ee9 100644 --- a/source/evals/skill-routing.yml +++ b/source/evals/skill-routing.yml @@ -58,6 +58,21 @@ cases: do_not_load: - tdd + - id: adr-for-service-split + prompt: Write an ADR for moving the WebSocket runtime out of the monolith into a dedicated service. + load: + - adr-writing + - context-gathering + - requirements-crushing + do_not_load: + - bug-first-debugging + + - id: gather-context-before-asking + prompt: Before I ask the team about the retry policy, what context should I gather? + load: + - context-gathering + do_not_load: + - tdd - id: python-idiom-choice prompt: Should this Python service use a namedtuple, TypedDict, or dataclass for config records? load: diff --git a/source/rules/skills-catalog.md b/source/rules/skills-catalog.md index a7c73fb..d9a31dd 100644 --- a/source/rules/skills-catalog.md +++ b/source/rules/skills-catalog.md @@ -37,6 +37,7 @@ guidance intact. Exception: skills whose topic is the language or format itself | Skill ID | Load when | |----------|-----------| | accessibility-and-inclusive-ui | building or reviewing a frontend UI; adding a form, modal, or interactive widget; auditing keyboard or screen-reader support | +| adr-writing | creating or updating ADRs for architecture decisions using the SMART + STAR ADR format; load context-gathering and requirements-crushing first | | agents-md-checklists | authoring an AGENTS.md file for a project | | ai-collaboration-hygiene | reviewing AI-generated code before merging; deciding what to delegate to AI; setting AI contribution policy | | api-and-interface-design | designing or changing a public interface, port, or API | @@ -51,6 +52,7 @@ guidance intact. Exception: skills whose topic is the language or format itself | centralized-ui-components | building UI components; enforcing one catalog source before page use | | code-review-and-quality | reviewing a diff or PR across six axes | | code-simplification | reducing complexity in tested code, one change at a time | +| context-gathering | gathering project context before requirements work; checking Linear, Datadog, Notion, Slack, docs, and repo history when available | | compile-time-feature-flags | making a dependency or integration optional at build time; shipping a minimal variant without heavy optional deps | | concurrency-correctness | writing or reviewing concurrent code; shared state; locks | | data-privacy-and-retention | handling PII, retention limits, or right-to-erasure | diff --git a/source/skills/adr-writing.md b/source/skills/adr-writing.md new file mode 100644 index 0000000..ed4edae --- /dev/null +++ b/source/skills/adr-writing.md @@ -0,0 +1,136 @@ +--- +id: adr-writing +kind: skill +title: ADR Writing +description: > + Create or update ADRs for architecture decisions using the SMART + STAR ADR + format. Use for decisions that outlive a single PR: service boundaries, + provider strategy, storage/retention choices, rollout architecture, tenancy + model, or any decision with material trade-offs. +applies_when: + - creating or updating an ADR for an architecture decision + - a decision has material trade-offs that outlive a single PR + - writing an ADR using the SMART + STAR format +agents: + claude: { kind: skill } + cursor: { kind: skill } + codex: { section: skills } + goose: { section: skills } + openclaw: { section: skills } + opencode: { kind: skill } + pi: { section: skills } + vibe: { kind: skill } +--- + +# ADR Writing + +Use for architecture decisions that outlive a single PR: service boundaries, +provider strategy, storage/retention choices, rollout architecture, tenancy +model, or any decision with material trade-offs. + +This skill depends on `context-gathering` and `requirements-crushing`. +Do not draft from memory. Gather evidence first, then crush requirements into a +Ready-to-Decide brief, then write the ADR from that evidence. + +Format follows the STAR/SMART ADR pattern from +`msfidelis/staff-plus-star-method-ards` (`template/ADR-STAR.md`). + +## File Location + +```text +docs/adr/NNNN-kebab-title.md +``` + +If the project has no `docs/adr/` yet, create it with a short `README.md` index. +Do not bury ADRs in `.specs/`; specs can reference ADRs, but ADRs are durable +project documentation. + +## Required Inputs + +Before writing the ADR, run: + +1. `context-gathering` to collect repo docs/code, Linear, Datadog, Notion, Slack, + and Git/GitHub context when available. +2. `requirements-crushing` to produce a concise brief with Why, scope, + constraints, success metrics, rollout, rollback, tests, and open questions. + +The ADR must be filled from those inputs. If a field cannot be filled, write +`TBD` only while status is `Proposed`, and include the exact missing evidence +needed to graduate to `Accepted`. + +Minimum evidence to collect: + +- Current code path and owning modules/packages. +- Existing docs/runbooks/secrets that will drift if the decision lands. +- Baseline metrics or an explicit measurement plan. +- Known incidents, product asks, or stakeholder context. +- Privacy, tenant isolation, provider, cost, and operability constraints. +- Alternatives already tried or rejected. + +## Required Frontmatter + +```yaml +--- +id: ADR-YYYY-NNN +title: "" +status: Proposed | Accepted | Rejected | Obsolete +authors: [] +date: YYYY-MM-DD +subsystem: [] +related: [Linear-..., RFC#..., ADR-..., PR#..., Datadog-...] +tags: [] +--- +``` + +Use `Proposed` while discussing. Use `Accepted` only after human approval. Keep +obsolete/superseded ADRs as history; do not rewrite past decisions to hide churn. + +## Required Body Sections + +1. **Context** — current situation, why change is needed now. Include audience, + symptoms, current topology, baseline metrics (p95/p99, incidents, SLO, cost + with window and source), and constraints (privacy, tenancy, budget, compliance). +2. **Objective — SMART (Task)** — specific, measurable, achievable, relevant, + time-bound goals: behavior, latency/reliability, privacy/isolation, blast + radius, cost, measurement plan. +3. **Decision** — state the decision. Include a small Mermaid diagram when it + clarifies the data/control flow. +4. **Alternatives Considered** — each alternative and why rejected. +5. **Consequences** — positive and negative (trade-offs, debt, operational burden). +6. **Implementation And Rollout Plan** — steps plus rollback. +7. **Success Metrics And Observability** — RED metrics, boundary spans, + privacy/tenant checks, provider health, minimum alerts. +8. **Results — STAR** — Situation (before baseline), Task (SMART goals), + Action (what was done), Result (after-window deltas, side effects, follow-up). + +## Rules + +- Cite evidence. Use Datadog/Linear/Slack/Notion/repo links when available. +- Every major field must trace back to gathered context or the requirements brief. +- Baseline metrics can be `TBD` only while status is `Proposed`; `Accepted` ADRs need a measurement plan at minimum. +- Do not set status to `Accepted` while unresolved questions remain in the requirements brief. +- Every ADR must name trade-offs, rollout, rollback, and observability. +- Privacy/tenancy decisions must call out who can access sensitive data and how cross-tenant access is prevented. + +## GOOD + +ADR for "move WebSocket runtime out of the monolith into a dedicated service" +cites the current p95 latency from Datadog, the related incident link, the +Linear issue, and the Slack decision thread. The brief was crushed first. +Trade-offs, rollout, rollback, and observability are all filled. Status is +`Proposed` until human approval. + +## BAD + +ADR drafted from memory with `TBD` in every baseline field, no evidence links, +no alternatives, and status set to `Accepted` by the agent. The decision cannot +be reviewed because there is nothing to check against. + +## Red Flags + +- ADR written from memory without `context-gathering` and `requirements-crushing`. +- Status set to `Accepted` without human approval or while questions remain. +- No alternatives considered. +- No trade-offs, rollback, or observability section. +- Privacy/tenancy decision that does not call out access and isolation. +- ADR buried in `.specs/` instead of `docs/adr/`. diff --git a/source/skills/context-gathering.md b/source/skills/context-gathering.md new file mode 100644 index 0000000..fb23d3f --- /dev/null +++ b/source/skills/context-gathering.md @@ -0,0 +1,61 @@ +--- +id: context-gathering +kind: skill +title: Context Gathering +description: > + Gather evidence before asking questions. Use before requirements work to + collect repo, Linear, Datadog, Notion, Slack, and history context when + available. If a source is unavailable, record that and continue. +applies_when: + - starting requirements work and external context may exist + - before asking questions that gathered evidence could answer + - preparing a brief that should cite real evidence, not assumptions +agents: + claude: { kind: skill } + cursor: { kind: skill } + codex: { section: skills } + goose: { section: skills } + openclaw: { section: skills } + opencode: { kind: skill } + pi: { section: skills } + vibe: { kind: skill } +--- + +# Context Gathering + +Gather evidence before asking questions. Use only integrations available to the +current agent. If a source is unavailable, record that and continue. + +Order: + +1. Repo-local docs/code: `README.md`, `RUNBOOK.md`, `docs/`, tests, + nearby feature packages, and recent diffs. +2. Linear if integrated: issue, parent, comments, labels, project, acceptance criteria. +3. Datadog if integrated: logs, monitors, incidents, dashboards, traces, error rates. +4. Notion if integrated: product docs, RFCs, specs, meeting notes. +5. Slack if integrated: relevant channels, threads, incident or decision context. +6. Git/GitHub if useful: recent commits, PRs, review comments. + +Output concise evidence, contradictions, unknowns, and the questions that remain. +Do not ask questions already answered by gathered context. + +## GOOD + +Before drafting a brief for "add retry to the payment endpoint", the agent reads +the existing endpoint code, finds a related Linear issue with a linked incident, +checks Datadog for the error rate, and notes that Slack thread #payments already +decided on exponential backoff. The brief cites all of this and asks only the one +remaining question: target p99. + +## BAD + +The agent immediately asks "what is the retry policy?" without reading the code, +checking the issue, or looking at the incident — wasting the human's time on a +question the evidence already answers. + +## Red Flags + +- Asking a question that the repo, issue tracker, or telemetry already answers. +- Skipping a source because it "might not have anything" instead of checking. +- Listing every fact found instead of concise evidence, contradictions, and unknowns. +- Treating an unavailable integration as a blocker instead of recording the gap.