Install Best-Practice Rules & Commands
Every MACSTACK project ships the same battle-tested .claude/rules/ set and core
commands (proven in a production orchestrator). Install them at scaffold time; adapt
wording to the project, never drop a rule silently.
Mandatory .claude/rules/
Create each file; content = a short version of the rule + the WHY:
safety.md — Never: commit secrets (.env, tokens, .mcp.json with values),
any in TypeScript, display names instead of resource IDs in MCP calls, deleting
production data without confirmation, hardcoded URLs/tokens. Always: validate at
boundaries, handle 401/404/429/500 on external calls, env vars for credentials,
created_at/updated_at on every table, batch endpoints for >10 records.
secrets-env-sync.md — Infisical = the source of truth; local .env* are
working copies; changed env → /secrets-push; before a deploy/push →
/env-audit; push is an upsert (never deletes); never commit .env* (see the
infisical-env skill).
commit-after-task.md — Conventional Commits (type(scope): summary), small
frequent commits after each finished unit of work; body explains WHAT/WHY;
committing ≠ pushing (pushing is a separate explicit action).
search-first.md — Part A: reuse before building (codebase → dependencies →
from scratch); Part B: 2+ failed attempts / unfamiliar API → search official docs
(Context7 → llms.txt → web), do not keep guessing.
external-api-docs.md — before writing code against a third-party SDK/API,
verify usage against official docs (an llms.txt map of the stack's services);
training data goes stale.
project-conventions.md — naming: TS PascalCase/camelCase/kebab files; DB
snake_case, FK {table}_id, booleans is_*/has_*, timestamps *_at; workflows
[Domain] - [Action] - [Trigger]; kebab API URLs; never cite file.ts:214 —
cite a symbol name or a test title, because line numbers rot the moment the
file above them grows and a pointer at a closing brace reads as authoritative.
No TODO / FIXME in code — forward-looking work goes to macstack/history/TASKS.md
(and to the team's tracker), where it has an id, an owner and a status. A TODO in
a source file is a task nobody can see, prioritise or close.
macstack-sync.md (specific to the standard) — macstack.json is a living
specification: any stack change (new software/workflow/entity/interface) is
accompanied by a macstack.json update + lint in the same commit; a spec change
means macstack.json and the affected documents under macstack/client/,
generated/ or history/ land in the same commit — the specification and its
documents are one definition of done.
A day of work ends with a work row in macstack/history/ledger.jsonl naming the task
ids it advanced and what did not go as planned. Git records what changed; the log
records why it went that way and what was tried first, which is the half nobody
can reconstruct later. Put the task id in the commit subject — (M11-T9) — and
the commit, the task and the log entry line up for free.
If the project deploys to a PaaS (dokploy/coolify) — also add deploy-verify.md
(a deploy is done only when the build is done + containers are healthy + logs are
clean + the domain returns 200).
Mandatory .claude/commands/
| Command |
What it does |
commit.md |
Conventional commit per the commit-after-task rule |
pr.md |
Create a PR (body: what/why, work-item link) |
secrets-sync.md, secrets-push.md, env-audit.md, setup-tokens.md |
from the infisical-env skill |
update-context.md |
update macstack.json + CLAUDE.md + .env.example after stack changes (the sync skill) |
macstack-lint.md |
validation, plus the dashboard — "where are we and what next" (the lint skill; status folded into it) |
CLAUDE.md wiring
Ensure CLAUDE.md: (1) has the "Stack Specification" section → macstack.json and
macstack/README.md, including its trigger table — the exact block is in
macstack-dev:setup; (2) lists the rules as MANDATORY, one line each; (3) stays
short (<100 lines) — details live in rules/skills/macstack.json, not in CLAUDE.md.
The trigger table is not optional and not decoration. Without it the block says only
"read this first", and an agent that reads the folder without ever being told when to
update it leaves it to go stale. A document that reads perfectly while describing
yesterday's system is worse than no document, because it is believed. Check for the
table, not just for the heading.
Rules for applying
- Idempotent: an existing rule file with local edits is never overwritten — show a
diff instead.
- Rules are project files (committed); the plugin only installs their initial
versions.
1---2name: best-practices3description: This skill should be used when the user asks to "install best practice rules", "set up project rules", "add project rules and commands", "set up project conventions", or scaffold-project reaches the rules step. Installs the proven MACSTACK rule set (.claude/rules) and core commands into a project.4---56# Install Best-Practice Rules & Commands78Every MACSTACK project ships the same battle-tested `.claude/rules/` set and core9commands (proven in a production orchestrator). Install them at scaffold time; adapt10wording to the project, never drop a rule silently.1112## Mandatory `.claude/rules/`1314Create each file; content = a short version of the rule + the WHY:15161. **`safety.md`** — Never: commit secrets (`.env`, tokens, `.mcp.json` with values),17 `any` in TypeScript, display names instead of resource IDs in MCP calls, deleting18 production data without confirmation, hardcoded URLs/tokens. Always: validate at19 boundaries, handle 401/404/429/500 on external calls, env vars for credentials,20 `created_at`/`updated_at` on every table, batch endpoints for >10 records.212. **`secrets-env-sync.md`** — Infisical = the source of truth; local `.env*` are22 working copies; changed env → `/secrets-push`; before a deploy/push →23 `/env-audit`; push is an upsert (never deletes); never commit `.env*` (see the24 `infisical-env` skill).253. **`commit-after-task.md`** — Conventional Commits (`type(scope): summary`), small26 frequent commits after each finished unit of work; body explains WHAT/WHY;27 committing ≠ pushing (pushing is a separate explicit action).284. **`search-first.md`** — Part A: reuse before building (codebase → dependencies →29 from scratch); Part B: 2+ failed attempts / unfamiliar API → search official docs30 (Context7 → llms.txt → web), do not keep guessing.315. **`external-api-docs.md`** — before writing code against a third-party SDK/API,32 verify usage against official docs (an llms.txt map of the stack's services);33 training data goes stale.346. **`project-conventions.md`** — naming: TS PascalCase/camelCase/kebab files; DB35 snake_case, FK `{table}_id`, booleans `is_*/has_*`, timestamps `*_at`; workflows36 `[Domain] - [Action] - [Trigger]`; kebab API URLs; never cite `file.ts:214` —37 cite a symbol name or a test title, because line numbers rot the moment the38 file above them grows and a pointer at a closing brace reads as authoritative.39 **No `TODO` / `FIXME` in code** — forward-looking work goes to `macstack/history/TASKS.md`40 (and to the team's tracker), where it has an id, an owner and a status. A TODO in41 a source file is a task nobody can see, prioritise or close.427. **`macstack-sync.md`** (specific to the standard) — macstack.json is a living43 specification: any stack change (new software/workflow/entity/interface) is44 accompanied by a macstack.json update + `lint` in the same commit; a spec change45 means `macstack.json` **and** the affected documents under `macstack/client/`,46 `generated/` or `history/` land in the same commit — the specification and its47 documents are one definition of done.48 **A day of work ends with a `work` row in `macstack/history/ledger.jsonl`** naming the task49 ids it advanced and what did not go as planned. Git records what changed; the log50 records why it went that way and what was tried first, which is the half nobody51 can reconstruct later. Put the task id in the commit subject — `(M11-T9)` — and52 the commit, the task and the log entry line up for free.5354If the project deploys to a PaaS (dokploy/coolify) — also add `deploy-verify.md`55(a deploy is done only when the build is done + containers are healthy + logs are56clean + the domain returns 200).5758## Mandatory `.claude/commands/`5960| Command | What it does |61|---|---|62| `commit.md` | Conventional commit per the commit-after-task rule |63| `pr.md` | Create a PR (body: what/why, work-item link) |64| `secrets-sync.md`, `secrets-push.md`, `env-audit.md`, `setup-tokens.md` | from the `infisical-env` skill |65| `update-context.md` | update macstack.json + CLAUDE.md + .env.example after stack changes (the `sync` skill) |66| `macstack-lint.md` | validation, plus the dashboard — "where are we and what next" (the `lint` skill; `status` folded into it) |6768## CLAUDE.md wiring6970Ensure CLAUDE.md: (1) has the "Stack Specification" section → macstack.json and71`macstack/README.md`, **including its trigger table** — the exact block is in72`macstack-dev:setup`; (2) lists the rules as MANDATORY, one line each; (3) stays73short (<100 lines) — details live in rules/skills/macstack.json, not in CLAUDE.md.7475The trigger table is not optional and not decoration. Without it the block says only76"read this first", and an agent that reads the folder without ever being told when to77update it leaves it to go stale. A document that reads perfectly while describing78yesterday's system is worse than no document, because it is believed. Check for the79table, not just for the heading.8081## Rules for applying8283- Idempotent: an existing rule file with local edits is never overwritten — show a84 diff instead.85- Rules are project files (committed); the plugin only installs their initial86 versions.