Skip to content

Claude Code SOTA conformance: hooks on the stdin contract, agents aligned, commands to skills, flavian plugin (#167) - #180

Merged
PAMulligan merged 8 commits into
mainfrom
feat/claude-code-conformance-167
Nov 2, 2026
Merged

PAMulligan merged 8 commits into
mainfrom
feat/claude-code-conformance-167

Conversation

@PAMulligan

@PAMulligan PAMulligan commented Nov 2, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Brings Flavian's Claude Code configuration to the current spec (Claude Code 2.1.316) the way Maecenas, Aurelius and RCVMD were, and packages the repo as the flavian plugin. Resolves #167.

Agents Skills Checker errors Warnings
Before (main) 53 12 139 56
After 53 16 0 6 (the SKILL.md files over 500 lines)

Design and plan: docs/plans/2026-11-02-claude-code-conformance-design.md, docs/plans/2026-11-02-claude-code-conformance.md. Record: docs/audits/2026-11-02-claude-code-sota-conformance.md.

What changed, by commit

  • Hooks on the stdin JSON contract. The six inline PostToolUse hooks read $TOOL_INPUT/$TOOL_OUTPUT and never fired; the three scripts/*-fse/validate-theme-location.sh copies read a CLAUDE_TOOL_INPUT variable that does not exist. Nine hooks now run on lib/hook-io.sh: the layout guard answers with a JSON deny and scopes itself to the Flavian layout (so the plugin's copy stays quiet in repos that track wp-content/), a new deploy-guard.sh asks before production deploys, rollbacks, remote writes and local data loss and denies them in subagents, pre-commit-token-guard.sh asks on hardcoded design values in committed theme files, plus size, quality-gate, coverage, dark-mode and mutation reminders and a SessionStart status block. hooks.json mirrors the registration for the plugin. .mcp.json starts Playwright with npx instead of cmd /c.
  • Agents. All 53 aligned by script: MultiEdit/Edits → Edit, Task → Agent, KillShell → TaskStop; TaskOutput, TodoWrite, AskUserQuestion dropped; MCP lists collapsed to mcp__<server>__*; valid colours; memory: project on eight agents; skills: preloads on sixteen; agent-scoped hooks through "$CLAUDE_PROJECT_DIR"; agent-expert and command-expert teach this repo's layout.
  • Commands → skills. scaffold-block moved; lint and test rewritten for this repo (the old copies described Python tooling); create-blog-article moved with a provenance note and disable-model-invocation; fse-pattern-first-architecture/skill.md renamed to SKILL.md (it only loaded on a case-insensitive file system). The figma pipeline tracks progress in .claude/pipeline/<theme>/state.json instead of TodoWrite and episodic-memory checkpoints.
  • Rules, plugin, workflow, evals. .claude/rules/ (WordPress standards out of CLAUDE.md, Claude Code conventions, scripts and hooks, pipeline artifacts); .claude-plugin/plugin.json (27 agents ship, 26 excluded with the reason: 13 clash with names the maecenas plugin ships, 13 have no WordPress job); .claude/workflows/fse-template-lanes.js (one lane per template, bounded fix loop); evals/ with one case per hard rule.
  • Checks in CI. scripts/claude-code-conformance.js + spec (re-verified against 2.1.316), scripts/check-doc-counts.sh, tests/claude-code/ on node:test, validate-configs.yml runs them; validate-agent-configs.sh now accepts the spec's values and runs on macOS bash 3.2.
  • Docs. CLAUDE.md 670 → 165 lines; PLUGINS-REFERENCE.md and SETUP-COMPLETE.md no longer describe six plugins that were never installed; counts 53/16 everywhere.

Decisions to confirm

  1. settings.json carries hooks only. The planned permissions.allow and ask rules were refused by the auto-mode classifier as self-modification when I tried to write them, which is the right call; the gates hold through the hooks. Add the rules yourself if you want fewer prompts (list in the audit record §5).
  2. The token guard asks rather than denies (inline SVG fills and deliberate exceptions exist in patterns); where a hook cannot prompt it denies.
  3. 26 agents stay out of the plugin through metadata.excludedAgents; nothing was deleted. Reversible by editing the manifest.
  4. model: opus + permissionMode: bypassPermissions on 28 agents were left as they were (out of scope; listed for review).
  5. flavian@pmds needs the marketplace entry in Maecenas: PMDevSolutions/Maecenas#77. Until it merges, nothing installs from here.

Test plan

  • node scripts/claude-code-conformance.js → 0 errors, 6 warnings
  • bash scripts/check-doc-counts.sh → 53 agents, 16 skills, in sync
  • node --test tests/claude-code/*.test.mjs → 88 pass (hooks 70, checker 12, doc counts 6)
  • tests/bats/bin/bats tests/validate-agent-configs.bats tests/figma-fse/validate-theme-location.bats tests/unit → 53 ok
  • ./scripts/validate-agent-configs-ci.sh → pass
  • claude plugin validate . → passed (advice only: no icon, CLAUDE.md at the plugin root)
  • claude plugin eval . --scaffold --allow-tools Write Edit Bash (costs model calls; not run)
  • First real Figma conversion with three or more templates exercises fse-template-lanes

🤖 Generated with Claude Code

PAMulligan and others added 8 commits November 2, 2026 13:37
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…guard

The six inline PostToolUse hooks in settings.json read $TOOL_INPUT and
$TOOL_OUTPUT, which are not part of the hook contract, so none of them
ever fired. Every hook now reads the event JSON on stdin through
lib/hook-io.sh, answers with JSON, and always exits 0:

- validate-theme-location.sh denies wp-content/ writes with a JSON
  permissionDecision and scopes itself to the Flavian layout, so the
  plugin's copy stays quiet in repos that track wp-content/themes/
- deploy-guard.sh (new) asks before production deploys, rollbacks,
  remote writes over ssh/scp/rsync/wp --ssh, and local data loss
  (docker volumes, wp db reset); denies them inside subagents;
  agent-no-deploy.sh is the frontmatter form for the deploy agents
- pre-commit-token-guard.sh asks on hardcoded values in the theme files
  a commit carries; bundle-size-guard.sh reminds above 5 MB / 10 MB
- post-bash-reminders.sh <case> replaces the quality-gate, coverage,
  dark-mode and mutation reminders, registered with if: filters
- session-context.sh adds a status block at SessionStart
- hooks.json mirrors settings.json for the plugin build
- the three scripts/*-fse/validate-theme-location.sh copies, which read
  a CLAUDE_TOOL_INPUT variable that never existed, now exec the project
  hook; their bats test moves to the stdin contract
- .mcp.json starts the Playwright MCP with npx instead of cmd /c

Tests: tests/claude-code/hooks.test.mjs (70) and the bats suite.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ne state in a file

Custom slash commands are skills now, so the four files in
.claude/commands/ move to .claude/skills/<name>/SKILL.md:

- scaffold-block: moved as is, with a name
- lint and test: rewritten for this repository (PHPCS, the security and
  performance scans, the conformance check, bats and node --test
  suites); the Python linters and runners the old copies described never
  applied here
- create-blog-article: moved with a provenance note and
  disable-model-invocation, because its paths do not exist in Flavian

fse-pattern-first-architecture/skill.md becomes SKILL.md, which Claude
Code looks for; the lowercase name only worked on a case-insensitive
file system.

The figma pipeline tracks progress in .claude/pipeline/<theme>/state.json
instead of TodoWrite (not offered on current models) and episodic-memory
checkpoints (a plugin that is not installed); the schema and the
resumption procedure live in the skill, and Step 2.4 can run through the
fse-template-lanes workflow. The hook-integration skill documents the
stdin JSON contract and the current hooks; the skills catalogue lists 16.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…bagent spec

Tool lists name only tools that exist: MultiEdit and Edits become Edit,
Task becomes Agent, KillShell becomes TaskStop; TaskOutput, BashOutput,
SlashCommand, TodoWrite and AskUserQuestion (never available in a
subagent) are dropped; explicit MCP tool lists collapse to
mcp__<server>__* patterns. Colors use the eight values Claude Code
accepts. Agent-scoped hooks reference their scripts through
"$CLAUDE_PROJECT_DIR" and lose the undocumented description field.

Eight agents whose knowledge compounds across conversions and audits get
memory: project; sixteen preload the skills that are their method;
deployment-agent and devops-automator carry the agent-no-deploy hook.
The converter and InDesign agents track progress in the pipeline state
file instead of TodoWrite and episodic memory, and agent-expert and
command-expert now teach this repository's layout and the current
conventions instead of the claude-code-templates tree.

Conformance check: 139 errors before, 0 after.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ow, evals

- .claude/rules/: path-scoped standards that load only when matching
  files are in play: the Claude Code conventions (verified against
  2.1.316), the WordPress standards that used to live in CLAUDE.md, the
  scripts-and-hooks conventions, and the pipeline artifacts
- .claude-plugin/plugin.json: the repo is the `flavian` plugin over its
  live .claude/ directories; 27 agents ship, 26 stay out through
  metadata.excludedAgents (13 names the maecenas plugin already ships,
  13 with no WordPress job); release-please keeps its version in step
  with package.json
- .claude/workflows/fse-template-lanes.js: one lane per FSE template
  (convert, validate, bounded fix loop) in priority groups, then the
  state file's templates section; Step 2.4 of the pipeline skills calls
  it by name
- evals/: one case per hard rule (root-level layout, tokens not
  literals, no production deploy) with scaffolds and mechanical graders

claude plugin validate . passes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…o CI

- scripts/claude-code-conformance.js and scripts/lib/claude-code-spec.json,
  copied from Maecenas; the spec is re-verified against Claude Code
  2.1.316 (docs and CHANGELOG 2.1.311 to 2.1.316: no changes to the
  enumerations the checker uses)
- scripts/check-doc-counts.sh: a standalone port that fails when an
  "N agents" / "N skills" claim in the live docs disagrees with disk;
  historical records and WordPress code are excluded
- scripts/validate-agent-configs.sh: accepts the spec's model aliases,
  permission modes and hook events, and runs on macOS bash 3.2 (the
  associative array needed bash 4)
- tests/claude-code/conformance.test.mjs and doc-counts.test.mjs on
  node:test; pnpm lint:claude, check:doc-counts, test:claude
- validate-configs.yml runs the bats suites, the validator, the
  conformance check, the doc counts and the node tests, and triggers on
  the files they read

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…th it

- docs/audits/2026-11-02-claude-code-sota-conformance.md: method, the
  before-and-after numbers (139 errors and 56 warnings to 0 and 6),
  the actions per area of issue #167, the decisions, what needs Paul
- CLAUDE.md rewritten as orientation (670 lines to 165): the layout rule,
  the rules that always hold, the scripts and commands, the Claude Code
  configuration (53 agents, 16 skills, 9 hooks, 4 rules, 1 workflow, the
  flavian plugin), the pipelines and the documentation map; the WordPress
  standards now load from .claude/rules/wordpress-standards.md
- .claude/PLUGINS-REFERENCE.md rewritten: no plugins are installed and
  none are needed; the flavian plugin and how to install it; the
  optional official plugins that fit WordPress work
- .claude/SETUP-COMPLETE.md reduced to a dated status
- README.md, CUSTOM-AGENTS-GUIDE.md, scripts/README.md and
  TROUBLESHOOTING.md: counts, the Agent tool, the hooks, the install line

check-doc-counts.sh: 53 agents, 16 skills, in sync.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The plugin.json extra-file entry is the only change; the earlier commit
had rewritten the whole file through a JSON serializer.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@PAMulligan
PAMulligan merged commit d222ca7 into main Nov 2, 2026
24 checks passed
@PAMulligan
PAMulligan deleted the feat/claude-code-conformance-167 branch November 2, 2026 23:31
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.

Claude Code SOTA conformance: Flavian (audit 2026-10-03)

1 participant