agentleFS
adyusufadyusuf/claude-code-standards/CLAUDE.md

claude-code-standards

CLAUDE.md1 starsChanged 13 days agoMITView on GitHub

This file enters context in every project, every session and every agent turn — it is the most expensive instruction file there is. Only the rule itself goes here; rationale, history and measurements move to docs/decision-log.md (standards/00 §6a). Size gate: scripts/md-budget.tsv. Detailed standards live in standards/ (paths are relative to the plugin root) — index: standards/README.md or the software-standards skill. Project-specific rules live in the project's own CLAUDE.md and override the rules here — with one exception, #29. - English…

  • Reads credentials
  • Deletes or force-pushes
  • Commits and pushes

The file

Show its rules and text

We split this CLAUDE.md into the rules it gives an agent

13 rules. About 0 are common, 8 are distinctive, and 5 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈8

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Small step first: Before a large refactor, propose a small patch and wait for approval.

    line 26
  2. Very specific:

    One API — web and mobile consume the same contract: No platform-specific endpoints.

    line 30
  3. Distinctive:

    Authorization is fail-closed: Default is DENIED. Never build semantics where "I forgot to configure it" means "open to everyone".

    line 31
  4. Distinctive:

    Tests get updated: If a file that has tests was touched, its tests are updated.

    line 33
  5. Distinctive:

    Ask before adding a dependency: Write down why it is needed, what the alternative is, and its maintenance cost, then wait for approval.

    line 35
  6. Distinctive:

    Report the truth: If tests are red, say so with the output.

    line 40
  7. Very specific:

    If the task spans multiple files or layers (API + client, migration + code, i18n tr+en), did all of them change?

    line 52
  8. Distinctive:

    If something is knowingly deferred, list it explicitly in the final report — never skip it silently.

    line 53
  9. Very specific:

    First git fetch and update dev: Do not branch from a stale base.

    line 61
  10. Very specific:

    Create a new branch (or worktree) off dev and work there: Never commit directly on dev.

    line 62
  11. Distinctive:

    Scope: EVERY test address the system might send a message to — e2e (web and mobile), seed/e2e accounts in the test environment, data …

    line 87
  12. Distinctive:

    When the code is done, unit tests are written (#8), then the tests run once.

    line 100
  13. Very specific:

    Every promotion to test and to prod WARNS "e2e was NOT run" and carries on, never read as a pass.

    line 104

≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
CLAUDE.md

Global Working Rules

This file enters context in every project, every session and every agent turn — it is the most expensive instruction file there is. Only the rule itself goes here; rationale, history and measurements move to docs/decision-log.md (standards/00 §6a). Size gate: scripts/md-budget.tsv. Detailed standards live in standards/ (paths are relative to the plugin root) — index: standards/README.md or the software-standards skill. Project-specific rules live in the project's own CLAUDE.md and override the rules here — with one exception, #29.

Language

  • English throughout — prose, headings, file and folder names, identifiers, commit messages and comments. There is no second language in this rule set.
  • User-facing text is never a raw string → an i18n key (the primary locale is mandatory, the secondary one ships as a placeholder).

Default stack

.NET (Web API) + PostgreSQL/SQLite · React + Vite + TypeScript · React Native/Expo · Playwright (web e2e) · Maestro (mobile e2e) · GitHub Actions.

Invariant rules (apply to every project)

  1. Small step first. Before a large refactor, propose a small patch and wait for approval. No unrequested "while I was in there" improvements.
  2. Single source of truth. Hard-coded URL / IP / port / host / API key is forbidden. Each tier has exactly one config module; other files never read process.env / import.meta.env / IConfiguration directly, they take a named import from that module. Fallbacks exist for DEV only and are defined in one place.
  3. Secrets never enter the repository. Passwords, tokens, connection strings, certificates → env / secret store. The repo holds only .env.example. If a secret leaks: rotate first, clean up second.
  4. Backward compatibility is mandatory. APIs and databases evolve additively only. Fields and endpoints are never deleted, renamed or retyped; they are marked obsolete and keep returning real values. → standards/08-backward-compatibility.md
  5. One API — web and mobile consume the same contract. No platform-specific endpoints; differences are resolved in the UI layer. Business logic never lives on the client. → standards/07-api-design.md
  6. Authorization is fail-closed. Default is DENIED. Never build semantics where "I forgot to configure it" means "open to everyone". Every endpoint checks authorization in the backend; the check in the UI is UX only.
  7. Validation in two places. On the client for UX, in the API for security. Client-side validation is never sufficient on its own.
  8. Tests get updated. If a file that has tests was touched, its tests are updated. If there are no tests, say so explicitly. A behaviour change is never merged untested.
  9. Never leave a 300+ line file. Split it at its natural boundaries (modal, list renderer, form, sub-service). Splitting must not change behaviour; the main file stays an orchestrator.
  10. Ask before adding a dependency. Write down why it is needed, what the alternative is, and its maintenance cost, then wait for approval.
  11. No magic strings. Constants become enums/consts. Enum switches always carry a default branch (forward compatibility).
  12. Date format dd/mm/yyyy. Locale-aware toLocaleDateString/Intl and dot-separated formats are forbidden. Transport and storage are always UTC ISO-8601.
  13. Search is always case- and accent-insensitive. "sisman" ↔ "Şişman", "istanbul" ↔ "İstanbul" must match. Raw .Contains / .ToLower().Contains() / LIKE is forbidden; a central normalizer is used.
  14. A new rule is never left verbal. Once a permanent decision is made, write it in the same turn to the relevant CLAUDE.md (project) or to the rule set's standards/ (global). Do not finish the task while skipping this step.
  15. Report the truth. If tests are red, say so with the output; name any step that was skipped. Never report completion on the basis of "it probably works".
  16. Setup is documented. Every project carries SETUP.md + .env.example + a secret/token inventory (what it is, where to get it, where it is stored, who owns it, rotation). Any change that adds a tool, env var or secret updates these in the same PR. A clean machine must be set up by following the document, without guesswork.
  17. A single origin is preferred. The API is served under the UI's domain (app.example.com/api/*); a separate api. subdomain is the exception and requires an ADR. The SPA fallback must not cover /api/*.
  18. A backup is only a backup if it has been tested. 3-2-1 rule (one copy off-server), encrypted, one restore drill per month, and a record of the drill. A failed backup and a backup that never ran are alarmed separately. Not just the database: user files, configuration, certificates and secrets are all in scope. Take a manual backup before any DROP or bulk update.
  19. Security scanning is automatic. Secret scan + dependency CVE on every push; SAST on pull requests; OWASP ZAP baseline after the test deploy. Before a release, the OWASP Top 10 mapping table is reviewed (standards/15-security.md §12). Critical/high findings block the merge. SAST and SECRET SCANNING are steps in every project and also run locally (scripts/codeql-scan.sh, gitleaks detect); CI calls the same script with the same thresholds — never two different rules in two places. A script that runs every gate in the pipeline locally must exist (scripts/merge-gate.sh → gate-core.sh) so verification does not stop when CI is down. A gate that did not run did not pass — it is reported as "skipped" and the result is not green. False positives are suppressed only through justified triage; the rule itself is never switched off. → standards/15-security.md §13a-13c
  20. An autonomous background agent is never started without asking. Nothing that keeps running turn after turn without user intervention — /loop autonomous mode, a self-retriggering ScheduleWakeup loop, a cron/schedule-based agent — is set up without explicit prior approval. If such a job is already running, report it proactively: what it is doing, what it is waiting for, what it is consuming, how to stop it. Never leave it running silently.
  • ⚠️ APPROVED, but CONDITIONALLY. The conditions and stop rules are in modes/autonomous-run.md — task list, definition of done, stall brake, STOP on any irreversible action; no money stop. If any condition is absent the run does not start and this rule applies in full again. 21-23. [Delegated to #27 / removed] The numbers are preserved so references do not break; the original text and rationale are in docs/decision-log.md §21-23.
  1. A self-administered completeness check is mandatory before saying "done". Immediately before reporting a task as "done / finished / complete", in the same turn and without being asked, I apply this checklist to myself:
  • Re-read the user's original request (do not rely on a summarised memory of it) and verify item by item that every point in it is satisfied.
  • Were edge cases and error paths considered? (empty list, null, unauthorized access, concurrency, backward compatibility.)
  • Were tests (#8), build/lint/format, and where relevant the SETUP.md/.env.example/secret inventory updates (#16) actually run?
  • If the task spans multiple files or layers (API + client, migration + code, i18n tr+en), did all of them change?
  • If something is knowingly deferred, list it explicitly in the final report — never skip it silently.
  • Say "done" only after passing the check. → the request list, evidence and forbidden patterns: standards/00-working-method.md §4a; rationale and application notes: docs/decision-log.md §24
  1. The gate is SHARED and runs at every promotion; running e2e is OPTIONAL (#33). Two layers: scripts/gate-core.sh <dev|test|prod> is the SHARED STEP SET (canonical copy in the configuration repository, a committed copy in every project); the project's scripts/merge-gate.sh is the orchestrator and CALLS it. A gate cannot depend on a path outside the repository (CI runners lack the configuration). gate-core.sh <target> --list prints what would run.
  • feature/* → dev and dev → test: EVERYTHING EXCEPT RUNNING E2E (the step list is in standards/13-pr-and-review.md §4), with coverage as #29 says; a missing e2e spec is a warning, never blocking (#33).
  • A step that did not run did not pass. A missing tool is reported as SKIPPED and the result is INCOMPLETE, never green; the exit code is the gate.
  • A project may ADD steps to the shared gate; it may never remove one. → the step list: standards/13-pr-and-review.md §4; rationale: docs/decision-log.md §25
  1. Once the work is planned: pull dev → branch/worktree off dev → work there → one commit per task, merged to dev through a gate. The order is binding:
  2. First git fetch and update dev. Do not branch from a stale base.
  3. Create a new branch (or worktree) off dev and work there. Never commit directly on dev.
  4. Each task is committed on its own (its own commit(s), the task named in the message) — never mixed into another task's commit. Ready branches reach dev/test as ONE batch: one review, one test run, one gate on the merged result — a producer (agent, background task) finishes its code and tests (at most a narrow run of its own piece), hands off, and is never reviewed or gated alone; the auditor also judges the test and gate results and sends findings back; fixes go on their own branch; dev never implies test; never squashed. → standards/13-pr-and-review.md §8
  5. Claude performs the dev/test/prod merges and pushes as the configuration says (#34) — never --force, not over a red gate (#25, #33).
  6. The formatter/linter runs once at the END of the task list, not on every merge (#25).
  • ⚠️ The configuration repository's own layout: branches dev / test / prod. The live config is the installed adyusuf plugin, copied from prod by /plugin update; work happens in a separate dev worktree and reaches the live config only by promotion, which Claude performs (standards/00-working-method.md §7a). → rationale: docs/decision-log.md §26
  1. The operating mode (A/B/C/D/E) is selectable per project; the selection IS the approval. The mode determines agent usage, review and approval policy together. Single source: modes/README.md; the selection lives in the project's .claude/mode file. To change it: /adyusuf:working-mode <letter>.
  • A Skill (no agents) · B Selective (analyst/test-writer/doc-writer) · C Full team (9 roles) — DEFAULT (the configuration's mode) · D Wide team (14 roles) · E Fan-out (Workflow). The Agent Teams modes (X/Y/Z) are archived and not offered — modes/archive/.
  • ⚠️ No agents in A; in B/C/D/E choosing the mode is the approval — no separate question before a call, and the agent count plus estimated cost are reported at the end of the turn. Automatic delegation counts as a call too. In C/D/E review is two-layered: the qa agent performs the first pass and I verify the critical findings.
  • ⚠️ The mode never loosens any of these: approval on irreversible work (deploy, DROP, force push, sending anything to the outside world), a red-gate promotion (#26), the completeness check before "done" (#24), secrets staying out of the repo (#3).
  • <letter> <model> (e.g. C sonnet) runs only the Opus agents on <model>; the letter alone = every agent on its defined model → modes/README.md › Model override.
  • How to apply: never ask the mode at session start. Order: a session choice → the project's .claude/mode → the configuration's mode (default C, Opus agents on sonnet). Change it with /adyusuf:working-mode (session, project) or /adyusuf:config (the defaults). The agents of the mode and their models can be adjusted per role (/adyusuf:config, agents.*). → modes/README.md › Session start; docs/decision-log.md §27
  1. On every pass the auditor CHECKS for gaps and errors, SENDS WORK BACK, and GETS IT FIXED; cost is reported at every handoff. On every turn that uses agents:
  • The completeness-check block is mandatory. Every role whose output someone else will rely on (every role except the four the orchestrator audits instead) closes its report with an evidence block: Verification (command run / range read) · Item mapping (each requested item → file:line) · Not covered → Result: serious gap NO | YES. The block is written even when the pass is clean. The orchestrator writes one line per handoff (evidenced ✅ clean + cost) and the full block at the end of the turn and on every "YES"; it never swallows the role's own block. ⚠️ This is a check, not a question: the auditor does not ask "is anything missing?" — not the user, not the producing role. What cannot be verified does not count as fine.
  • If something is missing it is SENT BACK, not escalated to the user. The work returns to its producer (qa → developer/me → qa again); the hand-back carries what is missing · with what evidence · what to do. It reaches the user only for the stop reasons in §5 and at the ceiling — and even then as a status report, not a question.
  • One clean pass is enough. A single "no serious gap" is sufficient for a handoff. The Verification line must carry the command that was run or the range that was read. On "YES" the work goes back; when the fix arrives, the same verification that surfaced the finding is re-run. Ceiling: the same work is sent back at most twice (3 passes); if it is still not resolved the chain stops and the user is informed, with unclosed findings listed individually as open findings. A "serious gap" is anything that affects behaviour, security, backward compatibility or data, or that leaves a requested item unmet.
  • No handoff while a finding is open — the auditor gets it fixed. A hand-back is not a note, it is an order. A finding closes only by (a) being fixed and evidenced, (b) the user explicitly saying "don't", or (c) being reported as an open finding with an out-of-scope justification — no finding is ever dropped silently. The end-of-turn report shows closed vs. still open.
  • Three audit gaps are closed: analyst also returns the command that produced its finding · devops output goes through qa · product-manager output goes to user approval. → detail modes/role-selection.md §2a, §3, §5-§8; rationale docs/decision-log.md §28
  1. Line coverage of AT LEAST 80% in every codebase — one written exception.
  • The measure: line coverage, every codebase SEPARATELY — backend · web · mobile Android · mobile iOS. Never averaged. An unmeasured codebase does not count as passing; it is reported as "not measured" and still blocks the push.
  • The denominator must be honest: only generated code is excluded (EF migrations + ModelSnapshot, obj/, *.g.cs, *.Designer.cs, .d.ts, the tests, e2e/config). The exclusion list lives in one place, with a reason per entry. Removing hand-written product code from the list is loosening the threshold → forbidden. Sole exception: mod glue, standards/10-test-strategy.md §7.2a.
  • The gate: the coverage step is in the shared gate (#25) and runs before a push where coverage_before_push.<t> is yes (#34); below the threshold → exit code ≠ 0. CI calls the same core with the same threshold.
  • No loosening: the threshold is not lowered and the exception above is the only one. A project's CLAUDE.md CANNOT override this rule.
  • Fake coverage is forbidden: e2e does not count towards this figure. Writing assertion-free tests is the same as loosening the threshold — an added test must catch a fault under mutation (standards/10-test-strategy.md §7).
  • Adoption: the first session opened in a project measures coverage, installs the gate if there is none, and reports the gap along with a plan to close it. No measured push passes until the gap is closed. → rationale: docs/decision-log.md §29
  1. Email in test data goes to a REAL mailbox: <account>+<variable>@gmail.com.
  • Scope: EVERY test address the system might send a message to — e2e (web and mobile), seed/e2e accounts in the test environment, data entered by hand in the integration environment, invitation/link recipients.
  • Forbidden: fake domains — .test, .local, example.com, sample.*.
  • Single source: the address is produced by one helper in the tests (the base is overridable via env, e.g. E2E_EMAIL_BASE); addresses are never written by hand into a spec or seed (#2).
  • Out of scope: tests whose sender is faked. → detail standards/11-playwright.md §4; rationale docs/decision-log.md §30
  1. The run cycle (e2e AND every test/gate run → standards/00 §11; parallelism/reuse → §12): full run → identify failures → fix → run only what was fixed → I decide on a full re-run.
  • The WHOLE suite runs first, without stopping at the first failure. Failures are classified: product bug · stale spec · data/fixture · environment.
  • Failures are fixed — each fix in its own commit; fixes may share one gate and one merge (#26). Raising retries or loosening assertions does not count as a fix.
  • Then ONLY the fixed tests (and those they could affect) run.
  • ⚠️ E2E is optional (#33): if run, only against code on test; verification on dev is unit tests + tsc/lint (#25).
  • I decide whether to repeat the full suite and report the reasoning: repeat it if the fix touched something shared · if the promotion record requires a full run · if some failures were environmental; if the fix is limited to a single spec, a targeted run is enough.
  • A run that hit an environment limit is invalid; it is not read as a product failure — parallelism is lowered and the run repeated. → detail standards/11-playwright.md §9a; rationale docs/decision-log.md §31
  1. Order: ALL the code first → then unit tests are written → then unit tests run; e2e is optional (#33).
  • The planned work's code is written in full; tests are not run after every small change.
  • When the code is done, unit tests are written (#8), then the tests run once; anything red is fixed and only the relevant tests re-run.
  • E2E is optional and never run by a gate (#33).
  • #26 still holds: each task gets its own commit and reaches dev through a gate — alone or in a batch — once its unit run is green. → rationale: docs/decision-log.md §32
  1. E2E is OPTIONAL — no gate runs it and it never blocks a promotion (user decision 03/10/2026: not enough resources to run it).
  • Every promotion to test and to prod WARNS "e2e was NOT run" and carries on, never read as a pass. Run it by hand or with GATE_RUN_E2E=1 (a red result then blocks like any step).
  • test → prod checks neither the test branch nor the test environment (04/10/2026, general rule): it WARNS; GATE_CHECK_TEST_DEPLOY=1 verifies the deployed SHA and a mismatch then blocks. The missing-spec check stays a warning. → docs/decision-log.md §33
  1. Merges, pushes and the gates before them follow the configuration (/adyusuf:config), not questions. When the code is done: merge where merge.<t> is yes, run the gates where gates_before_push.<t> is yes, push where push.<t> is yes, then wait for green CI where ci_after_push.<t> is yes; before deploying test/prod, run e2e on dev/test where e2e_before_deploy.<t> is yes. A red gate, CI run or e2e blocks every later target. A gate set to no is NOT run and the merge commit carries Gate-Waived: <gates> (neden: configuration); before a prod merge list those lines in the report. Never ask what a setting answers. A gate that did not run did not pass; coverage follows coverage_before_push.<t> (#29). → standards/13-pr-and-review.md §8a; docs/decision-log.md §34

Never-do list

The full list, including the items tied to numbered rules: docs/decision-log.md § Never-do list.

  • ❌ Business logic / validation / authorization decided on the client alone
  • ❌ Connecting to the database directly from a client
  • ❌ Committing dead code that has been commented out
  • ❌ Opening a PR without running the formatter (dotnet format, Prettier/ESLint)
  • ❌ Deleting or renaming a field/endpoint (= delete + add)
  • ❌ SELECT *, N+1 queries, a list endpoint without pagination
  • ❌ A swallowed exception (catch {}), an error with no log
  • ❌ Writing PII / tokens / passwords to the log
  • ❌ Loosening tests "so they pass", papering over a flaky test with retry
  • ❌ Pushing to main, or to prod outside a promotion
  • ❌ Without user approval: production deploy, DB DROP, git push --force, deleting data, sending a message or publishing to an external service
  • ❌ An untested backup ("we have backups" is not enough — a restore drill is performed)
  • ❌ Invoking any agent outside the active mode's role set — including migration-reviewer and other plugins' agents that shadow these role names (ours are adyusuf:<role>). ⚠️ test-writer is not banned: it is one of B's three roles. The protection is the role set, never a name list → #27, #28

Working method (for Claude)

The full protocol is in standards/00-working-method.md (plan → approval → execute, verification, context discipline, parallel sessions, work that requires approval). In short: read a file before editing it · for work touching multiple files, present a short plan first · never say "it works" without running build + the relevant tests + lint/format, and if you did not run them say "I did not run them" · when uncertain, finish the independent work first, then ask one clear question · commit only your own diff and never use --force · get approval for irreversible work (deploy, DROP, sending anything outward, deleting files).

STATUS REPORTING during a long gate/run (PERMANENT, all projects)

Report progress as a short markdown table in the reply. No Artifact dashboard, no published board; the session's plan file (standards/22) is an extra record only.

The table carries: the item · its state · the measured figure, with the signal it was read from · what it is waiting on. Keep it to the rows that matter; a blocked row states the reason, not a percentage.

⚠️ Every figure is MEASURED, never invented — if it cannot be measured, the row says "cannot be measured". A long run's output is never piped into something that buffers (tail/head): write it to a log file and read the table from that. A step that did not run is reported as "did not run", never as passing.

⚠️ Name background tasks by cost: FREE - <name> if no model runs, else the model name (Sonnet 5.5 - <name>) — and a non-FREE task names its model wherever it is reported.

→ Detailed rules: standards/00-working-method.md §10, §10c.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.