Shared Claude Code working agreement (style + VCS rules + slash commands) for Grey.ooo Symfony projects
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Matthew Baggett 2005d01bd1 Document Forgejo's per-job CI rerun button (#33)
## What

Documents a Forgejo capability found while chasing a red E2E job on
Someones.Computer#1126: every job in a run's sidebar carries its own
rerun icon (revealed on hover, just before its duration), separate
from the existing `Re-run all jobs` button. It re-runs only that job,
and lets whatever's downstream of it (e.g. `Ship` behind `E2E`)
re-evaluate once it finishes — no new commit, and no re-running work
that already passed.

## Why

VCS.md already covers watching CI (`tea pulls --fields ci`'s dropped
rows, the commit-statuses cross-check) but had nothing on re-running a
red job short of a new commit or the whole-run button. Neither the API
nor `tea` can trigger a re-run at all on this Forgejo, so the run page
is the only route — worth a session knowing both granularities exist.

## Verified

Pure docs change — `docs/Topics/VCS.md` only. Ran the platform repo's
own `bin/lint-markdown.sh` against this file as a sanity check: two
pre-existing findings elsewhere in the file (unrelated, untouched by
this diff), nothing near the new section.

Reviewed-on: #33
2026-08-25 19:53:06 +00:00
commands Scope /ci-local to the host's architecture and named jobs 2026-08-13 19:11:30 +02:00
docs/Topics Document Forgejo's per-job CI rerun button (#33) 2026-08-25 19:53:06 +00:00
frameworks/symfony Document that the Symfony Web Debug Toolbar breaks full-page screenshots 2026-08-11 22:19:34 +02:00
hooks Add a Stop hook that enforces the concise-recap answering style 2026-08-14 16:56:55 +02:00
languages/php Add seeing-changes-through habits, layered language/framework docs 2026-07-25 16:06:16 +02:00
skills Track time in a memory ledger and name the session in every claim (#28) 2026-08-18 10:45:11 +00:00
CLAUDE.md Add working agreement modes: ask-permission and PR mode 2026-08-21 20:01:26 +02:00
README.md Add a Stop hook that enforces the concise-recap answering style 2026-08-14 16:56:55 +02:00

Grey.ooo agent-standards

Shared Claude Code working agreement for Grey.ooo projects: answering style, git/VCS ground rules, and the slash commands that enforce them — plus optional, layered language- and framework-specific conventions. Extracted from someones.computer, Printshop, and Interchange so every repo stays coherent instead of drifting copy-by-copy.

Layering

Three layers, each independently importable — a project only pulls in what applies to it:

Layer Path Applies to
Universal CLAUDE.md, docs/Topics/*.md, commands/*.md, skills/*/SKILL.md Every project, any language
Language languages/<lang>/CLAUDE.md (+ topic docs) Every project in that language
Framework frameworks/<name>/CLAUDE.md (+ topic docs) Every project on that framework

Only languages/php/ and frameworks/symfony/ exist today, since that's what's been audited so far. Add a new layer the same way: a CLAUDE.md entry point, only facts confirmed across two or more repos (a single project's quirk belongs in that project's own docs/Topics/, not here — see Documentation-Conventions.md).

What's in here

Path Purpose
CLAUDE.md Portable "Answering style" / "Documentation style" sections, a Forgejo-not-GitHub callout, and the "seeing changes through" habits (watch CI to green, run the app). @-import into a project's root CLAUDE.md.
docs/Topics/VCS.md Full git/VCS working agreement (branching, commits, PRs, CI, WIP rules). @-import from a project's own docs/Topics/VCS.md reference, or point straight at this copy.
docs/Topics/Documentation-Conventions.md The docs/Topics/ + Errata.md + Plans/ + Issues/ documentation structure. Optional — only adopt if the project actually organises docs this way.
docs/Topics/Claude-in-CI.md Principles for running Claude headlessly and unattended inside a CI pipeline (kill switches, credential scoping, evidence verification, fail-closed trust gates, harness testing). Optional — only relevant if the project is building or running that kind of automation; interactive Claude Code use needs none of it.
commands/audit-docs.md /audit-docs — checks docs against the codebase for drift. Fully generic.
commands/vcs-check.md /vcs-check — checks branch naming, then runs whatever quality gate the consuming project's own CLAUDE.md documents. Generic by design — see Requirements on the consuming project.
commands/ci-local.md /ci-local — reproduces the project's CI/CD pipeline locally via act (Forgejo Actions semantics, not GitHub's). Generic by design, same requirement.
hooks/stop-recap.sh Stop hook — enforces the "Answering style" section by blocking the first attempt to end a turn with an instruction to give a clean, concise recap. Fully generic; needs only jq.
skills/*/SKILL.md Four Forgejo-tracker skills extracted from someones.computer — see Skills below for what each does and what it needs.
languages/php/CLAUDE.md PHP-specific gotchas — currently just the shared matthewbaggett/php* base image's prod-tuned opcache footgun, confirmed independently in all three source repos.
frameworks/symfony/CLAUDE.md Symfony/API Platform-specific gotchas — currently just the routes.yaml prefix vs. uriTemplate behaviour.

Skills

Unlike commands/, these are not all-or-nothing — each one assumes something about how a project runs beyond the universal git+Forgejo+tea baseline, and adopting one that doesn't fit just produces a skill that stalls or asks for things the project doesn't have. Check the "Needs" column before symlinking:

Skill Does Needs
resolve-pr-conflicts Sweeps open PRs for merge conflicts and stale-red CI against main, merges and pushes the fix back Nothing beyond the universal baseline, plus the project's own quality-gate command to prove a resolution (Phase 6 reads it from the same place /vcs-check does)
ask-me-questions Harvests open decisions from the tracker and code, puts them to the user as AskUserQuestion popups, writes the answers back Nothing beyond the universal baseline
issue-triage Verifies the whole tracker against the code, orders it into waves, groups related issues, unsticks conflicted PRs, starts the top group as a PR An actively-used Forgejo tracker (milestones, labels) worth verifying against — a project with a handful of untriaged issues gets less out of this than one running a real backlog. Runs resolve-pr-conflicts internally, so needs the same quality-gate hookup.
triage-loop Runs issue-triage's read/verify/order/group, then fans out across as many disjoint groups as the machine can carry, offering one work chip each Everything issue-triage needs, plus a workflow that can actually run several worktrees in parallel (a stack-per-worktree setup, or equivalent) — on a machine that can only carry one, this collapses to issue-triage with extra measurement overhead

Each skill states its own project-specific seams inline (frontmatter allowed-tools that need extending with the project's build/test commands, illustrative script and Makefile-target names to swap for whatever the project actually ships) rather than assuming a stack. Read the skill before symlinking it, not just this table.

Requirements on the consuming project

vcs-check and ci-local don't hardcode tool invocations — projects differ (host composer vs. docker compose exec <service> ...; PHPUnit-only vs. PHPUnit+PHPStan+php-cs-fixer). Instead they read the consuming project's own root CLAUDE.md for a "Quality gate" table (or equivalent — a link to docs/Topics/Testing.md/CI.md) that names the concrete checks and how to run them. Keep that table accurate locally; these commands are only as good as it is. resolve-pr-conflicts and issue-triage read the same table to prove a merge or a started group — one table, several consumers.

Consuming this in a project

Add as a submodule, conventionally at .claude/agent-standards:

git submodule add https://git.grey.ooo/Grey.ooo/agent-standards.git .claude/agent-standards

Root CLAUDE.md: replace the project's own "Answering style" / "Documentation style" prose with an import line, and keep project-specific tables (stack, paths, quality-gate commands) local:

@.claude/agent-standards/CLAUDE.md

VCS doc: point the project's VCS import straight at the shared copy instead of keeping a local docs/Topics/VCS.md:

@.claude/agent-standards/docs/Topics/VCS.md

Language/framework layers (optional): import only the ones that apply, alongside the universal CLAUDE.md import:

@.claude/agent-standards/languages/php/CLAUDE.md
@.claude/agent-standards/frameworks/symfony/CLAUDE.md

Slash commands: symlink each one into .claude/commands/ so Claude Code picks it up:

cd .claude/commands
ln -s ../agent-standards/commands/audit-docs.md audit-docs.md
ln -s ../agent-standards/commands/vcs-check.md vcs-check.md
ln -s ../agent-standards/commands/ci-local.md ci-local.md

Stop hook (optional): symlink the script into .claude/hooks/, then wire it up in .claude/settings.json (there's no auto-discovery for hooks the way there is for commands and skills):

mkdir -p .claude/hooks
cd .claude/hooks
ln -s ../agent-standards/hooks/stop-recap.sh stop-recap.sh
// .claude/settings.json
{
  "hooks": {
    "Stop": [
      { "hooks": [{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/stop-recap.sh" }] }
    ]
  }
}

Skills (optional, pick per project): symlink the directory, not just SKILL.md — Claude Code discovers a skill by its containing folder. Only symlink the ones whose "Needs" column (above) actually matches this project; symlinking one that doesn't fit costs nothing to try but won't do anything useful:

cd .claude/skills
ln -s ../agent-standards/skills/resolve-pr-conflicts resolve-pr-conflicts
ln -s ../agent-standards/skills/issue-triage issue-triage

Updating

Pull changes into a consuming project like any submodule bump:

git -C .claude/agent-standards pull origin main
git add .claude/agent-standards
git commit -m "Bump agent-standards"

Scope

The universal layer assumes only: git + Forgejo (git.grey.ooo, canonical) with tea, and act-reproducible CI defined under .github/workflows/. That's true for any Grey.ooo repo regardless of language. Anything more specific — Composer, php bin/console, PHPUnit/coverage gates, AssetMapper/Twig — belongs in the languages//frameworks/ layers above, imported only where it applies.