Skip to content

feat(planning): dialect-select and scope-label the design skill's per-scope artifacts - #3879

Merged
kyle-sexton merged 3 commits into
mainfrom
feat/3822-design-dialects
Sep 6, 2026
Merged

kyle-sexton merged 3 commits into
mainfrom
feat/3822-design-dialects

Conversation

@kyle-sexton

Copy link
Copy Markdown
Contributor

What

Phase 3 of the typed-ticket-body lane under #3799. The design skill's existing
"Scope-specific artifacts" table gains Typed artifact and Dialect columns. No new
artifact family is introduced — the files the skill already emits gain a declared dialect
and a scope label.

Scope Typed artifact Dialect
data entity-relationships.md mermaid erDiagram; DBML when diagram_dialect.data selects it
integration sequence-flows.md, contract-spec.md mermaid sequenceDiagram; OpenAPI 3.1 sketch for the contract spec
system component-map.md LikeC4 or C4-PlantUML container view, only when diagram_dialect.system names one; nothing when unset
library, module none no typed artifact, therefore no scope label

Zero config is unchanged behaviour: mermaid data diagrams, and no C4 container view.
The system key deliberately has no default — a default would make a consumer who never
opted in start emitting a C4 view they did not ask for. Mermaid's own C4 support is
experimental and is never used for this scope.

The scope-label shape #3823 consumes

Every typed artifact opens with frontmatter:

---
scope: data
dialect: mermaid
---

scopedata | integration | system. dialectmermaid | dbml |
openapi-3.1 | likec4 | c4-plantuml. #3823 needs the scope and the dialect for its
one-line provenance note, so both are on the label; the match is a lookup, not an inference
over prose.

Untyped artifacts are unchanged and carry no label: schema-decisions.md,
communication-patterns.md, every library and module artifact, and component-map.md
whenever diagram_dialect.system is unset. An integration session labels two artifacts,
one per typed file — worth noting for #3823, whose brief assumes one artifact per session.

Restated ladder, not a citation

The body restates the authoring-formats resolution ladder verbatim (key name and emitting
behaviour substituted) rather than pointing at docs/conventions/. An installed plugin
never sees this repository, so a path citation would make the publisher a runtime dependency
of the consumer's session.

The convention itself lands in #3874 (branch feat/3814-authoring-formats-convention), not
on main. This branch is cut from main and consumes the convention's text only. That doc's
Consumers table already pre-populates its /planning:design rows, so no edit is owed there
after it merges.

Diagram craft

Mermaid layout, readability, and syntax idiom route to /visualization:visualize (if the
visualization plugin is installed) — a marketplace plugin, so the citation follows
docs/conventions/seam-phrasing: gate names the plugin, fallback stated adjacent ("emit
the plainest correct form of the dialect"), ownership framed. The typed artifact is produced
either way; the craft citation never gates the emit.

Verification

bash scripts/check-changed-skills.sh origin/main
  CHECK-SKILL design: PASS — 0 errors, 3 warning(s)
  1 skill(s) checked, 0 failed.

bash scripts/check-changelog-parity.sh --check-bump origin/main
  Every plugin whose version changed vs main has a '## [<version>]' CHANGELOG.md entry.  (exit 0)

npx --no-install markdownlint-cli2 <changed .md>
  Summary: 0 issues in 0 files

node scripts/validate-plugin-contracts.mjs
  Plugin contracts validated: 53 setup skills, 3 retirement manifests, 3330 plugin files.  (exit 0)

bash scripts/check-stale-base-overlap.sh --check origin/main
  no overlapping paths

Grep evidence in plugins/planning/skills/design/SKILL.md (every pattern verified to NOT
match on the unmodified tree, so each proves new text): scope label, erDiagram,
sequenceDiagram, openapi, dbml, likec4, c4-plantuml, no C4.

SKILL.md is 259/500 lines — over the 200-line soft target (it already was at 210), WARN
not FAIL. The criteria require the statements in the body, so a spoke file would not satisfy
them.

Known gap

The planning plugin ships no bundled resolve-convention-home resolver, so ladder step 2
has nothing to call and a <home> it cannot supply falls to step 6's soft degrade (name the
cause, take the default). The body says so plainly. Registering planning as a third carrier
of that lib touches scripts/sync-resolve-convention-home.sh and the cross-plugin registry,
which is outside this slice's boundary — worth a follow-up before a consumer can actually
declare diagram_dialect.

Also bumped: planning 0.36.5 → 0.37.0 (new behaviour, minor) with the matching CHANGELOG
entry, and the README's /planning:design row.

Closes #3822

🤖 Generated with Claude Code

https://claude.ai/code/session_012jiwedVq2GxuzN7siXQbr4

…-scope artifacts

The design skill's existing Scope-specific artifacts table gains Typed
artifact and Dialect columns. No new artifact family is introduced: the
files the skill already emits gain a declared dialect and a scope label.

- data emits entity-relationships.md as a mermaid erDiagram, or DBML when
  diagram_dialect.data selects it.
- integration emits sequence-flows.md as a mermaid sequenceDiagram and
  contract-spec.md as an OpenAPI 3.1 sketch.
- system emits component-map.md as a C4 container view in LikeC4 or
  C4-PlantUML only when diagram_dialect.system names one, and no C4 view
  at all when it is unset. Mermaid's experimental C4 support is never used.
- library and module emit no typed artifact and therefore no scope label.

Every typed artifact opens with frontmatter carrying scope and dialect.
That label is the contract /work-items:decompose consumes so its lookup is
not an inference over prose. Untyped artifacts (schema-decisions.md,
communication-patterns.md, component-map.md with the system key unset, and
every library and module artifact) are unchanged and carry no label.

The body restates the authoring-formats resolution ladder rather than
pointing at the convention document: an installed plugin never sees the
publishing repository at runtime, so a path citation there would make the
publisher a runtime dependency of the consumer's session.

Mermaid craft routes to /visualization:visualize when the visualization
plugin is installed; without it the skill emits the plainest correct form
of the dialect. The typed artifact is produced either way.

Zero config is unchanged behaviour: mermaid data diagrams, no C4 view.

Closes #3822

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012jiwedVq2GxuzN7siXQbr4
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 6, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-06T21:27:18.852932Z 944ec5e PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@claude

claude Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 3m 24s —— View job


CI code review — /review:code-review

  • Gather context (PR body, diff, changed files)
  • Understand the request (/review:code-review per custom instructions)
  • Run /review:code-review skill and follow its instructions
  • Post findings as inline PR comments; cross-file findings in summary
  • Final summary update

Scope reviewed: all 4 changed files (plugins/planning/.claude-plugin/plugin.json, plugins/planning/CHANGELOG.md, plugins/planning/README.md, plugins/planning/skills/design/SKILL.md), diffed against origin/main at 944ec5e.

No high-signal findings. This is a documentation-only change to the design skill's body plus the matching version bump / changelog / README row, and it holds together:

  • The new "Typed artifact" / "Dialect" table columns (plugins/planning/skills/design/SKILL.md#L170-176) don't leave any stale duplicate artifact list elsewhere in the file — grepped every artifact filename (entity-relationships.md, sequence-flows.md, contract-spec.md, component-map.md, communication-patterns.md, schema-decisions.md) and the table is the only place they're enumerated.
  • The "no bundled resolver" claim (SKILL.md#L222) checks out: plugins/planning/ has no lib/ directory, unlike plugin-quality and claude-config, which do ship lib/resolve-convention-home.sh.
  • Both presence-gated cross-plugin references (/visualization:visualize, /work-items:decompose) point at skills that actually exist in this tree, and the gate/fallback/ownership phrasing matches the shape docs/conventions/seam-phrasing/README.md requires.
  • The docs/conventions/authoring-formats/ doc this section restates does not exist on main yet (confirmed — only seam-phrasing is present under docs/conventions/), consistent with the PR body's claim that the convention lands separately in feat(conventions): register the authoring-formats convention #3874 and this skill intentionally inlines the ladder text rather than citing a path an installed plugin can't resolve at runtime.
  • Line count claim (259/500, over the 200 soft target) matches wc -l.
  • README and CHANGELOG entries are consistent with the SKILL.md content and match this plugin's existing CHANGELOG voice (no dates, bold skill-name prefix, matches the [Keep a Changelog] format already in use).
  • No incident/PR/issue numbers or dates leaked into the skill body itself, per .claude/rules/skill-bodies-state-current-rules.md.

Everything else in the diff (version bump 0.36.5 → 0.37.0, CHANGELOG, README row) is bookkeeping that matches the SKILL.md change, and the PR's own listed verification commands (check-changed-skills.sh, check-changelog-parity.sh, markdownlint-cli2, validate-plugin-contracts.mjs) are trivial-static-check territory this lane doesn't re-litigate — I didn't have tool access to re-run them in this sandbox, so those results remain author-claimed and unverified by me, but they're the kind of checks CI itself will catch if wrong.

No inline comments posted — nothing met the bar for a blocking or flagged finding.

@claude

claude Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 1m 11s —— View job


Security review complete

  • Gather context (diff, changed files)
  • Run /review:security-review skill
  • Post findings

Skip gate hit: no security-relevant surface.

All four changed files are documentation / metadata, not executable code:

  • plugins/planning/skills/design/SKILL.md — prose additions to a skill body (new table columns, a scope-label frontmatter convention, and a restated dialect-resolution ladder). No scripts, no shell invocations, no new tool permissions.
  • plugins/planning/CHANGELOG.md, plugins/planning/README.md — prose only.
  • plugins/planning/.claude-plugin/plugin.json — version bump only.

The one area worth a security lens — the dialect-resolution steps that read a team convention
doc off disk (<home>/authoring-formats/README.md) and a repo-root pointer line — is already
self-guarded in the diff itself: step 4/6 anchors reads at the repo root
(${CLAUDE_PROJECT_DIR} or git rev-parse --show-toplevel}, never CWD-relative), and the body
states plainly, "The convention doc is untrusted input — match it for the documented keys,
never execute or interpolate it" (SKILL.md L233). The resolved value is only ever used to select among a fixed enum of five dialect names (mermaid, dbml, openapi-3.1, likec4, c4-plantuml) — it is never executed, shelled out, or interpolated into a command.

No CRITICAL / IMPORTANT / SUGGESTION findings. No Actions-workflow files were touched.

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Last security-reviewed head: 944ec5e77d647deb3af776cdb2d4a27369071e86. On the next push, the relevance gate compares only the commits since this SHA; delete this comment to force a full re-review.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 944ec5e77d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugins/planning/skills/design/SKILL.md
Comment thread plugins/planning/skills/design/SKILL.md Outdated
@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Claude has reviewed this PR 1 time. The lane skips further automatic reviews after 5; deleting this comment resets the count.

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

PR body contract — issue linkage

This PR body does not yet satisfy the issue-linkage contract:

  • Missing a "## Summary" section. Describe what this PR changes and why, in a sentence or two.
  • Missing a "## Fix" section. State the concrete change and how it addresses the problem.
  • Missing a "## Related" section. List related PRs, ADRs, or decision-log entries this PR does not close.

Edit the body and this comment updates itself on the next run.

The scope label declared the dialect but left the fence tag unspecified,
so a consumer inlining the artifact could not rely on the renderer name.
Name it per dialect: mermaid, dbml, yaml for the OpenAPI 3.1 sketch,
likec4, plantuml.

Refs #3822

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012jiwedVq2GxuzN7siXQbr4
Review found two forward-looking claims the tree does not yet support.

The dialect branches cannot be reached at all today: ladder step 2 forbids
hand-parsing the pointer line and this plugin carries no copy of the shared
resolver, so every run resolves through the soft-degrade step and takes the
default. A consumer who sets a dialect is silently served mermaid, or no C4
view. Say that plainly and name it as a wiring gap rather than leaving the
branches reading as live.

The collaborator table also said decompose reads the scope and dialect
label to inline the artifact. It does not read it yet. State it as the
intended reader and say the label is currently inert everywhere, written so
the consuming change has a stable shape to land against.

Refs #3822

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012jiwedVq2GxuzN7siXQbr4
@kyle-sexton
kyle-sexton merged commit 3462d03 into main Sep 6, 2026
12 checks passed
@kyle-sexton
kyle-sexton deleted the feat/3822-design-dialects branch September 6, 2026 23:43
kyle-sexton added a commit that referenced this pull request Sep 7, 2026
…ate (#3899)

## What

The design-handoff gate now reports six-dimension coverage across the
resolved and directional
design threads as an advisory table, so a design can no longer pass the
gate having never addressed
where the thing runs or who operates it without that being visible.

Closes #3817. Refs #3801.

## Behavior

After the verdict sentence, and on a FAIL after the routing sentence
too, the gate emits one table
with columns `Dimension | Covered by | Status` and one row per dimension
a design answers: what,
how, where, who, when, why.

- A row is covered when a thread whose status is RESOLVED or directional
records a decision about
  that dimension; the row names that thread and its status.
- A TAGGED-DEFERRED thread never covers a row.
- An uncovered row reads `none` in both remaining cells.
- `design-threads.md` carries no dimension field, so the reading rule
per dimension is stated as the
  example table's own second column.
- On a `design-resolution.md` early exit the table is read over that
file.
- The handoff summary gains an `Uncovered dimensions` bullet and the
resume prompt carries them, so
  `/planning:plan` can hold them as open questions.
- The table is never written to disk, never contributes to the pass/fail
determination, never
  blocks, and no flag makes it block.

No framework prose: the six words are introduced as "the six dimensions
a design answers" and
neither Zachman nor TOGAF is named, explained, or cited anywhere in the
diff.

## Files

- `plugins/planning/skills/design-handoff/SKILL.md`: new `## Coverage
report (advisory)` section
between "Binary gate" and "Handoff summary"; one new handoff-summary
bullet; one new gotcha; one
  new clause in the frontmatter `description`.
- `plugins/planning/skills/design-handoff/evals/evals.json`: cases 6, 7,
8
(`coverage-table-all-resolved`, `coverage-gaps-still-pass`,
`coverage-on-early-exit`); case 2
gains one expectation asserting the FAIL verdict and routing are
unchanged and precede any
  coverage table.
- Three new fixtures under `evals/fixtures/`, each referenced from its
case's `files[]`.
- `plugins/planning/README.md`: the `design-handoff` row mentions the
advisory table.
- `plugins/planning/CHANGELOG.md` `## [0.38.0]` `### Added`;
  `plugins/planning/.claude-plugin/plugin.json` version `0.38.0`.

`docs/SKILL-CHEAT-SHEET.md` is untouched: `metadata.summary` did not
change.

## Two deviations from the issue's fenced sanity block

Both are reported rather than worked around silently.

**1. Version is `0.38.0`, not the `0.37.0` the issue names.** PR #3879
merged
(`3462d03e5`) while this branch was in flight and took `0.37.0` for the
planning plugin on `main`.
`0.37.0` is therefore no longer available; `--check-bump` requires a
version strictly greater than
the base. `grep -q '^## \[0.37.0\]'` still passes, but on #3879's entry
rather than this one; the
entry this PR adds is `## [0.38.0]`, written above `## [0.37.0]` in
descending order.

**2. `! (git diff origin/main -- .../SKILL.md | grep -q '^-.*Use
when:')` cannot hold alongside the
description edit the issue also requires.** The frontmatter
`description` is one physical line, so
any edit to it emits a `-` line carrying the whole description, `Use
when:` included. The check was
run and reports the line-diff artifact.

The stated intent (no existing "Use when:" or "Skip when:" phrase is
dropped) was verified two ways
instead:

- The tail of the description from `Use when:` to end of line is
byte-identical to `origin/main`.
Both are 477 bytes and compare equal; the new clause was inserted before
`Use when:`.
- `scripts/check-changed-skills.sh origin/main` reports
  `INFO: all 5 base-ref trigger phrase(s) preserved`.

## Manual smoke: the FAIL sentence is byte-identical

`git diff origin/main -- plugins/planning/skills/design-handoff/SKILL.md
| grep -c '^-.*silent gap'`
returns `0`: the sentence "A thread that is unresolved AND untagged is a
silent gap" is untouched,
and so is the FAIL routing around it. The only `-` lines in the SKILL.md
diff are the description
line and the two lines the new bullet and resume-prompt sentence were
spliced into.

## Verification

| Check | Result |
| --- | --- |
| `! grep -qiE 'zachman\|togaf' .../SKILL.md` | PASS |
| `grep -qE '^\| *why *\|' .../SKILL.md` | PASS |
| `grep -q 'Dimension \| Covered by \| Status' .../SKILL.md` | PASS |
| `grep -q 'unresolved AND untagged is a silent gap' .../SKILL.md` |
PASS |
| `grep -c '"id":' .../evals/evals.json` | 8 |
| `bash scripts/check-changed-skills.sh origin/main` | `CHECK-SKILL
design-handoff: PASS, 0 errors, 0 warning(s)`; `SKILL.md 98/500 lines`;
`description 728/1536 chars` |
| `bash scripts/validate-plugins.sh` | `All plugin manifests and the
catalog validated.` |
| `bash scripts/check-skill-count-claims.sh --check` | `All 23
skill-count claim(s) match the tree (1 exempted).` |
| `bash scripts/check-orphaned-fixtures.sh --check` | `No orphaned eval
fixtures` |
| `bash scripts/check-changelog-parity.sh --check-bump origin/main` |
PASS |
| `bash scripts/check-changelog-parity.sh --check-preserved origin/main`
| `All 1 changed changelog(s) preserve every version heading` (86
compared) |
| `bash scripts/check-changelog-parity.sh --check-order` | `All 92
changelog(s) read newest-first with no duplicate versions.` |
| `bash scripts/check-purged-em-dashes.sh` | `94 declared paths, 126
files scanned, no em dashes.` |
| `bash scripts/check-stale-base-overlap.sh --check origin/main` | `HEAD
is up to date with origin/main` |
| `node scripts/validate-plugin-contracts.mjs` | `53 setup skills, 3
retirement manifests, 3347 plugin files checked` |
| `npx markdownlint-cli2` over the 6 changed markdown files | `0 issues`
|
| `check-jsonschema` over `evals.json` against
`plugins/skill-quality/reference/evals.schema.json` | `ok, validation
done` |

A fresh-context verifier subagent that did not write the change reviewed
the diff against the issue
body with the author's reasoning withheld, returning a per-criterion
verdict and a findings table.
It marked all eleven acceptance criteria MET with no CRITICAL and no
MAJOR finding, and raised two
MINOR ones. Both were confirmed against the files and fixed:

- The `design-threads-coverage-gaps.md` fixture's Thread 4 read
"Decision: keep the export in this
codebase", which a judge could fairly score as covering `where`, making
that case's `where` = `none`
expectation fragile. The decision line now reads "build the export
rather than adopting the
  reporting vendor's own", with the rationale reframed off placement.
- The coverage rule was keyed on thread status, but
`design-resolution.md` has no threads and no
statuses, leaving the early-exit path without a rule for filling the
cells. The skill now states
that rule explicitly: on that artifact a row is covered when the
artifact itself records a decision
about the dimension, `Covered by` names the recorded decision, and
`Status` reads `recorded`. Eval
  case 8 asserts the same.

## Out of scope, per the issue

Coverage is not blocking and no flag makes it blocking; no Zachman grid
ships as a skill; thread
resolution and tagging are unchanged and nothing is written into
`design-threads.md`; design-time
prompting for dimension coverage in `/planning:design` stays deferred.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_012jiwedVq2GxuzN7siXQbr4

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
kyle-sexton added a commit that referenced this pull request Sep 7, 2026
…R convention (#3898)

Closes #3818

Adds `/architecture:record-decision`, a thin skill that records one
architecture decision into whatever ADR convention the consuming
repository already has, plus presence-gated routes to it from three
planning skills. Four sequential phases, one commit each.

## Phase 1: skill and shared discovery ladder

- `plugins/architecture/skills/record-decision/SKILL.md`. Discovers the
ADR directory, numbering scheme and record shape in use, writes exactly
one record that follows them, and reports what it found before it
writes. Where nothing is declared and nothing exists, it names the rungs
it searched, offers two or three shapes, points at the upstream catalog
by URL, and writes nothing until the human chooses.
- `plugins/architecture/reference/adr-discovery.md`. The plugin's single
owner of the discovery ladder (declared, then existing directory, then
none) plus the numbering and shape inference rules.
- `improve/actions/deepening.md` drops its inline directory list for a
link to that reference, keeping the declared-location-first rule and the
closing sentence verbatim.

The upstream catalog
(`joelparkerhenderson/architecture-decision-record`) is **cited by URL
and never vendored**: it is CC BY-NC-SA 4.0, recorded in the skill as a
four-part verification record (claim, basis, as-of 2026-09-06, recheck
trigger). No catalog prose appears anywhere in this diff.

## Phase 2: evals and fixtures

Seven rich-form cases over three fixture trees (an existing convention
declared by a directory README, an inferred shape carrying a deliberate
duplicate `ADR-008`, and a tree with no convention). Coverage: trigger
and happy path, shape inference with a duplicate reported and not
renamed, offer-and-defer, the write that follows a human's choice, the
refusal to vendor catalog prose, the scope refusal for index and
supersession, and the admission test on a decision that does not earn a
record.

## Phase 3: planning routes

Each edit is presence-gated and keeps today's behaviour as the fallback:

- `interview/SKILL.md` line 155 bullet and the interview-outputs line;
new Composition row; eval cases 17 and 18 covering both branches.
- `design-handoff/SKILL.md` gains the "ADR candidates" bullet in the
handoff summary. The offer never blocks the handoff.
- `plan/context/close-out.md` step 2. The ADR admission test is
unchanged.

## Phase 4: surfaces and regen

architecture `0.8.0`, planning `0.38.1`, matching CHANGELOG entries,
`adr` and `decision-record` in keywords and marketplace tags (the two
lists match sorted), README sections, and regenerated `docs/CATALOG.md`
and `docs/SKILL-CHEAT-SHEET.md`.

## Overlap with other open PRs

Stated plainly, per the collision brief:

- `plugins/planning/skills/interview/SKILL.md` is also edited by
**#3882** (`feat/3821-ears-capture`). This PR touches only the two body
lines and the one Composition row the issue names.
- `plugins/planning/skills/design-handoff/SKILL.md` was also edited by
**#3899**, which has since merged; this branch rebased onto it cleanly
and its coverage-report section is untouched.
- `plugins/planning/.claude-plugin/plugin.json`, `CHANGELOG.md` and
`README.md` are also touched by **#3882**.
- `plugins/architecture/.claude-plugin/plugin.json`, `CHANGELOG.md` and
`improve/actions/deepening.md` are also touched by **#3896**
(`claude/3609-rendered-views-retrofit`, still open) and by **#3901**,
which merged as `0.7.0` while this branch was in flight. This branch
rebased onto #3901 and preserves its `map-landscape` and `setup`
entries, keywords and tags.

**Version note.** The issue specifies planning `0.36.5` to `0.36.6`.
Main moved twice under this branch while it was in flight: #3879 landed
`0.37.0` and #3899 landed `0.38.0`. This branch therefore takes
**`0.38.1`**, the next unused number above main, and preserves both
landed entries intact below it. Architecture likewise moved: #3901
landed `0.7.0` for its own new skill, so this branch takes **`0.8.0`**
(a minor bump, matching the convention that a new skill takes one) and
keeps #3901's entry, keywords and tags intact alongside its own.

## Manual check

Run against this repository, the skill's discovery reports `docs/adr/`,
`NNNN-kebab.md`, no README or template file, shape inferred from `0030`
(Status and Date list lines, then `## Context`, `## Decision`, `##
Consequences`), duplicates at `0018`, `0025` and `0028`, and proposes
`0031-<kebab>.md`. Run in an empty `git init` directory it finds no
convention on any rung and creates nothing. Both match the issue's
stated expectations.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_012jiwedVq2GxuzN7siXQbr4

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
kyle-sexton added a commit that referenced this pull request Sep 7, 2026
…alect resolves (#3926)

Closes #3924
Refs #3799, #3882

## Summary

`/planning:design` could not read the `diagram_dialect` convention keys,
because its own skill body told the running agent the resolver it needed
did not exist. `plugins/planning/skills/design/SKILL.md:222` said "the
planning plugin ships no bundled resolver", and `:224` said "**Until the
resolver is bundled, a configured dialect cannot be read at all.** ...
this plugin carries no copy of the shared resolver, so every run
resolves through step 6 and takes the default".

Both statements were false on `main`.
`plugins/planning/lib/resolve-convention-home.sh` is present and
executable, and the sibling skills in the same plugin name it:
`plugins/planning/skills/interview/SKILL.md:268-270` and
`plugins/planning/skills/prd/SKILL.md:296-298`.

The cause was ordering. #3879 landed the design skill at
2026-09-06T23:43:06Z; #3882 landed the resolver nine hours later and did
not sweep design back. The effect on `main` was that a consumer setting
`diagram_dialect.data` to `dbml` was silently served `mermaid`, and the
system-scope C4 container view was unreachable for every consumer, since
`diagram_dialect.system` could never resolve to a value.

Three surrounding documents carried reader claims that were also wrong
on `main`, all of the same shape: a value that reads as sourced but was
never checked against the code.

## Fix

Six files, no behavior outside the four documents named in the issue.

1. **`plugins/planning/skills/design/SKILL.md`.** The false clause at
`:222` and the whole "Until the resolver is bundled" paragraph at `:224`
are replaced with the resolver's real path and exit-code contract,
phrased as `interview/SKILL.md:268-270` and `prd/SKILL.md:296-298`
already phrase it, with only the degrade value adapted from `free-text`
to this skill's own defaults (`mermaid` for the data artifact, no C4
view for the system scope). The "tracked separately" pointer is dropped,
since it pointed at #3881, which closed as refuted. The untrusted-input
rule and the "restated here rather than cited because an installed
plugin never sees the publishing repository at runtime" rationale are
preserved. One punctuation change inside the preserved rule, disclosed
so a diff of that hunk is not a surprise: the break after "The
convention doc is untrusted input" is now a colon where it was an em
dash, so the rewritten line introduces no em dash into a repository mid
de-slop campaign. Every word of the rule is unchanged. No dialect branch
below the ladder moved.

2. **`docs/PLUGIN-PHILOSOPHY.md:669`.** The row named
`/work-items:decompose` and `/review:quality-gate` as readers. Neither
reads a key. The row now names only the three planning skills.

3. **`docs/conventions/authoring-formats/README.md`.** "no skill reads
either key on `main` today" is removed from both places it appeared. The
column heading "Declared consumer (not yet reading)" becomes "Reading
skill", and the rows now name `/planning:interview`, `/planning:prd` and
`/planning:design`. `/work-items:decompose` and `/review:quality-gate`
are dropped from the table and stated explicitly below it as consuming
the produced artifact without reading a key, so the document's own
closing rule ("A skill appears here once it actually reads the key")
stays true of the table. The `:167` contract, "each consuming slice adds
its own reading and updates its row in the same change", is honoured by
this change.

4. **`docs/conventions/config-cascade/README.md:303`.** "Conformance
becomes verifiable when the first resolver lands" and "**No skill on
`main` reads these keys yet**" are dropped, replaced with which skills
read which keys through which resolver.

5. **`plugins/planning/.claude-plugin/plugin.json`** bumped `0.39.0` to
`0.39.1`, with a matching new `## [0.39.1]` entry at the top of
**`plugins/planning/CHANGELOG.md`**.

No test digest needed refreshing:
`plugins/planning/tests/interview-defenses.test.sh` pins content over
`interview/SKILL.md` and `prd/SKILL.md`, and this change touches
neither. The one `grep -rn design plugins/planning/tests/` hit is the
word "design" inside an interview pin's prose, not a pin over the design
skill.

## Verification

Behavior was attempted, not read.

**Fixture run.** A fixture repository was built under the platform temp
directory (never inside the repo), carrying a convention-home pointer
line in `AGENTS.md` and a `docs/conventions/authoring-formats/README.md`
setting `diagram_dialect.data` to `dbml`.

```
$ bash plugins/planning/lib/resolve-convention-home.sh --root "$FX" --explain
root:      /tmp/ccp3924-fixture
AGENTS.md: one
CLAUDE.md: none
chosen:    AGENTS.md (one)
token:     docs/conventions
docs/conventions
EXIT=0
```

Reading the key through the resolved home returned the configured value,
not the default:

````
$ sed -n '/^```yaml/,/^```/p' "$FX/$(bash "$R" --root "$FX")/authoring-formats/README.md"
contract_version: 1.0.0
acceptance_criteria_format: ears
diagram_dialect:
  data: dbml
  system: likec4
````

**Exit-code contract, confirmed against the script rather than copied
from interview's wording.**

```
$ bash "$R" --root "$FX-nopointer"
no convention-home region in AGENTS.md or CLAUDE.md under /tmp/ccp3924-fixture-nopointer; ask the operator for the home
EXIT=1

$ bash "$R" --bogus
ERROR: unknown argument: --bogus
EXIT=2

$ bash "$R" --root "$FX-does-not-exist"
ERROR: --root is not a directory: /tmp/ccp3924-fixture-does-not-exist
EXIT=2

$ bash "$R" --root "$FX-badgrammar"      # two pointer lines in one region
FAIL: two pointer lines in one convention-home region (AGENTS.md); keep exactly one
EXIT=3
```

The script's own `--help` states the same contract: "Exit: 0 resolved
(home on stdout); 1 no pointer anywhere (ask); 2 usage; 3 FAIL". That is
what the new design text now documents.

**Every reader claim left standing, confirmed by `git grep` inside that
skill's own files.**

| Claim | Command | Result |
|---|---|---|
| `/planning:interview` reads `acceptance_criteria_format` | `git grep
-lE "acceptance_criteria_format\|resolve-convention-home" --
plugins/planning/skills/interview` | `SKILL.md`, `context/loop.md` |
| `/planning:prd` reads `acceptance_criteria_format` | `git grep -lE
"acceptance_criteria_format\|resolve-convention-home" --
plugins/planning/skills/prd` | `SKILL.md` |
| `/planning:design` reads `diagram_dialect` | `git grep -lE
"diagram_dialect" -- plugins/planning/skills/design` | `SKILL.md` |

**Every skill removed as a reader, confirmed at zero hits.**

| Claim | Command | Result |
|---|---|---|
| `/work-items:decompose` reads no key | `git grep -nE
"acceptance_criteria_format\|diagram_dialect\|resolve-convention-home"
-- plugins/work-items` | no output |
| `/review:quality-gate` reads no key | `git grep -nE
"acceptance_criteria_format\|diagram_dialect\|resolve-convention-home"
-- plugins/review` | no output |

Both skills also state it themselves:
`plugins/work-items/skills/decompose/context/container-lifecycle.md:46`
reads "no flag, no lever, no convention key", and
`plugins/review/skills/quality-gate/context/close-out.md:383` reads "no
flag, no lever, and no convention key is read here".

**Local gates.**

- `CHECK_SKILL_SKILLS_ROOT=plugins/planning/skills bash
plugins/skill-quality/scripts/check-skill.sh design` gives `PASS, 0
errors, 3 warning(s)`. All three warnings are pre-existing and
structural (line count over the 200 soft target, no Gotchas surface, a
numbered procedure at lines 156-162 with no completion-criteria signal);
none is introduced here.
- `bash scripts/check-purged-em-dashes.sh` gives `98 declared paths, 130
files scanned, no em dashes`.
- `bash scripts/check-changelog-parity.sh --check` passes.
- `npx markdownlint-cli2` over the five changed markdown files reports 0
issues.
- `git diff | grep -c $'\r'` is 0.

## Related

- Closes #3924.
- Refs #3799, the container whose close-out review graded acceptance
criterion 4 as FAILED and found this. The typing half of that criterion
shipped correctly in #3879; the dialect-selection half was unreachable.
#3799 stays open until this lands.
- Refs #3882, which landed
`plugins/planning/lib/resolve-convention-home.sh` nine hours after #3879
landed the design skill, without sweeping design back.
- #3881 was the prior tracking issue for this gap and closed as refuted,
which is why the "tracked separately" pointer is removed rather than
repointed.
- Out of scope on purpose: the two acceptance-criteria templates (the
generic `Criterion 1` and `agent-brief.md`'s `Specific, testable
criterion 1`) are a separate known follow-up and are untouched here.

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

planning/design: dialect-select and scope-label the existing per-scope artifacts

1 participant