Imported from AaravChadha/acstack (
AGENTS.md). Install upstream withnpx skills add AaravChadha/acstack. Copyright stays with the author.
Agent rules — acstack repo
This repo IS the acstack skill pack, so it eats its own cooking: the conduct
block below binds every session here, the roadmap lives in PLAN.md, and the
build history lives in JOURNAL.md. Read those two before changing anything.
Binding rules for this repo:
-
Run
scripts/check.shbefore every commit. A failing guard blocks the commit — fix the drift, don't skip the check. -
Never hand-edit a count marker — run
scripts/recount.sh. It re-derives every marked count and rewrites the ones that drifted, holding no derivation of its own (it usescount-check.shas the oracle, so the two cannot disagree). Hand-editing is what makes two concurrent task closures collide: both sessions write the same new value, git auto-merges the identical edit without conflict, and the count sits one too high — demonstrated on a scratch clone 2026-09-14, where the file carrying the marker did not even appear in the merge diff. Run it after every merge too, which is rule 7's re-derivation made mechanical. It cannot repair non-derivable accumulators or unmarked prose, and says so. -
The
acstack:principlesblock is edited ONLY in README.md (canonical), then propagated verbatim to everyskills/*/SKILL.md. -
No client, company, or collaborator names anywhere in pack content. The guard reads its list from untracked
.acstack-banned(see.acstack-banned.example) and sweepsscripts/andsetuptoo — the list was hardcoded inside check.sh until 2026-07-29, in a repo destined to go public, and the sweep excluded its own directory so it could never catch itself. When in doubt, genericize. -
Skills stay under 500 lines and plain markdown — no bash preambles until the wave-4 runtime lands, and none beyond its documented budget after.
-
Commit style: three shapes, chosen by what the commit does. Derived from the log on 2026-08-14 (last 40 subjects: 21 / 7 / 12), not asserted:
- closing a numbered PLAN task —
task <number>: <description>, andtask <a> + <b>: <description>when one commit closes two; - a journal entry —
Journal <date>: <summary>, orJournal <date> (2nd): <summary>for a second entry the same day; - anything else — shakedown runs, fixes, corrections, records —
lowercase
<verb> <object> (<detail>).
All three take a brief what-and-why body and no attribution trailers.
This is a deliberate exception to CONDUCT rule 10's work-item-referenced subject, not a derivation from it — the pack itself has no ticket or task ID per commit.Verdict (2026-08-14): that was false, and had been since PLAN task IDs existed — a task ID is a work-item reference, so task-closing commits follow rule 10 rather than excepting themselves from it. The exception survives only for the third shape, where there genuinely is no work item. Found by a live/healthas an observation outside its ten checks, having outlived every audit before it (4.79); guarded by check.sh §34. Rule 10's no-attribution half binds throughout. - closing a numbered PLAN task —
Verification rules (added 2026-07-29, extended 2026-08-03 — each from a defect this repo shipped):
-
Verify the consumed form, not the authored form. The file you wrote is not evidence; the thing that reads it is. Check the parsed frontmatter, the rendered markdown, the command's actual output — not your own text.
/shipshipped for a whole wave with a YAML-truncated description, losing its entire trigger sentence, because it was re-read instead of parsed. A dry run is not the consumed form either:/whyshipped and answered nobody because./setup --dry-runprinted "21 would be linked" and that was accepted as proof — the form that registers a skill is the symlink in~/.claude/skills, and nothing had created it. Output describing an action is not evidence the action happened. -
Prove a new check fails before trusting that it passes. Seed the defect the check exists to catch and watch it fire. A green check with no demonstrated failure mode is decoration. This repo has produced three: the
sk-[A-Za-z0-9]{20,}secret regex that reported clean on a planted key, the description guard whose first positive control passed misleadingly because the text it tested had already been fixed, and /design-audit's palette check, whose\bmatched nothing at all becausegit grep -Eis POSIX ERE (now guarded by check.sh section 3b). -
Anything named as needed work gets a carrier task in the same edit. Recording it is not scheduling it. This covers cross-cutting rules, proposed skills, deferred fixes — anything a future reader would expect to happen. Three rules (multi-product detection, positive controls, the commit-subject format) were binding with nobody owning the work until an audit found them orphaned; then two proposed skills (refactor safety, dependency upgrade) were named in analysis and never scheduled, slipping past the first version of this rule because it said "cross-cutting rule" and they were skills. If you write that something is needed, either open the task or write down that it was deliberately declined.
-
A claim about a set enumerates the set. "The six read-only skills" was written without opening six files, and
/retro— which appends to JOURNAL.md and commits — was in the list. Count it, list it, or don't claim it. This applies to your own earlier statements too: in a long session, re-read before restating, or you will contradict yourself in writing. -
Evidence you wrote about your own work is not evidence until something independent tries to break it. Frame the reviewer to disprove — "treat every row as a claim, not a fact; the author wants this falsified" — and hand it the requirement text separately so it checks the claim against the bar rather than against itself. Rounds framed as audits agreed; rounds framed as falsification found real defects, every time. A pass told to disprove the 4.7 launch ledger returned 2 rows false and 4 overstated, every error in the author's favour, after three prior audit-framed rounds had missed all six. It found a README section claiming "captured, not written by hand" whose commands could not execute as printed, and an evidence column that read "this table" for a requirement to paste command output. Verify the reviewer's findings at
file:linetoo — in the same session one agent claim did not survive checking. -
A fix for a behaviourally-found defect is unverified until a live run re-tests it. Mechanical green is not proof: check.sh, controls and the matrix verify the authored fix, never that a model now behaves differently. Six shakedowns each found defects, every fix was verified mechanically and shipped, and none was re-tested — then the first round that looked backwards instead of at new ground found three more defects inside those fixes: a clustering bar that contradicted its own fixture, a skill that contradicted its own report shape, and an emoji denylist that reported clean on this pack's own before-page. A new-ground round cannot catch these, because a fix becomes old ground the moment it is committed. Re-test in the venue that found the defect, and keep the outstanding list where it cannot be forgotten. Cost, stated: this makes every behavioural fix owe a live round. That is affordable here; if it stops being affordable, narrow the rule to security- and correctness-relevant fixes rather than quietly stop obeying it.
-
A clean merge is not evidence. Two branches that each tick a box, file a task, or move the same count marker make identical edits; git auto-merges them with no conflict, and the marker sits one too high or a task number is allocated twice — measured on a scratch clone 2026-09-11, before parallel sessions had been run for real. So: squash by default — it is the only method that guarantees every commit on
mainis a complete change, sogit bisectcannot land on a broken intermediate and a revert is one SHA. Rebase only on a testable exception: every commit on the branch passesscripts/check.shon its own and its body carries reasoning worth keeping inmain. Never a merge commit (git's defaultMerge branch 'x'subject fails §34). Note which text §34 then guards: under rebase it is every original subject, already checked at commit time; under squash it is the PR title, which no guard sees before the merge — so a squash PR's title must itself satisfy the three shapes, or the guard degrades from prevention to detection onmain. Re-derive every count marker after every merge; and runscripts/check.shon the merged tree before pushing it, because count-check otherwise catches the drift only afterwards, onmain. The same shapebites one layer down: a skill edited in aVerdict (2026-09-14): that was asserted from the symlinks alone and is false — measured by crossover, a worktree session is served the worktree's own skill, because the trackedgit worktreeis not the skill that runs, since./setuplinks~/.claude/skills/<name>at the main checkout, so a live run from a worktree exercises the old file and passes for the wrong reason (5.15)..claude-plugin/plugin.jsonregisters./skillsrelative to whichever checkout holds it. The links half is true (all 25 resolve to the main checkout); the conclusion drawn from it was not. What survives is the verification point, not the hazard: two registrations of every skill coexist and which one a live run served is a fact to establish, never to infer fromreadlink— 5.15 for the measurement, 5.22 for whether precedence is even deterministic.
These 7 are repo-binding, not part of the shipped conduct block. Promote
one into CONDUCT.md only if it proves out across projects — the same bar
/learn uses for promoting a lesson into known-bug-classes.
Typed-only skills
These skills carry disable-model-invocation: true, which keeps them out
of the model's skill listing — so an agent will not reach for one on its
own, and the roster below exists because otherwise nobody would find them.
That is a discoverability control, not an enforcement boundary. A model
handed the name explicitly can still run it: a session told "type /plan
seed" invoked it end to end (observed 2026-08-04). The same honest scope as
allowed-tools — the flag governs what the model is offered, not what it
is prevented from doing. Treat these as user-initiated by convention, not
by mechanism.
Suggest one when its column-three condition is true, per conduct rule 9: name it once, never repeat it, and treat silence or a pivot as a no.
| Skill | What it does | Suggest when |
|---|---|---|
/plan |
Frozen BRIEF → written architecture pushback → living PLAN.md with runnable exit criteria | The repo has no PLAN.md (or legacy equivalent) and the user is starting something new — or a build request lands in such a repo and the work is not a bounded single-file change (new files, new surface, or multi-file). Never for a one-line fix. Do the work first; make the offer with the end-of-increment status statement, naming concrete options and a recommendation ("spec first in docs/ / a short design sketch / keep building as-is — I'd suggest X because Y"), with one clause of reason: simple-looking work is where unexamined assumptions cost most. Once per session per repo; nothing is recorded, so a later session may ask once more. |
/eval-spec |
The eval is the spec: golden set with category minimums, refusal cases, pinned grader — written before the system exists | An LLM-shaped feature is heading into build and no eval/ exists |
Agent conduct
These rules bind every session in this repo. Full text: CONDUCT.md in the acstack pack.
- The word is the mode. "Explain" = complete explanation, then stop — no menus, no actions, no scaffolding in the same turn. "Plan" = design docs only. Build only on an explicit go.
- The user sets the pace. An approved plan authorizes the what, not the when. End each increment with a status statement; do not roll into the next increment uninvited.
- Answer what was asked before anything else. The answer is the deliverable; don't bury it.
- Be direct. Push back in writing when the user is wrong. No sycophancy.
- Don't ask permission for what was requested; don't do what wasn't. Before an act that cannot be undone, name it and confirm — even when it was requested.
- Don't relitigate decided things. New evidence gets one plain sentence, then the user rules.
- Surface conflicts between instructions, conventions, or config — never silently pick a side.
- When unsure, ask before starting. Ambiguity is a reason to stop, not to guess-and-build.
- Closing offer-questions are allowed but expectation-free: they often go
unanswered; silence or a pivot is not consent; offered work waits for
explicit uptake; never repeat the question. Referrals to typed-only
skills (the
acstack-referralsroster) are offers under this rule: name one once, never repeat it, and do the requested work first. - Commits: short subject starting with the work-item reference
(
ticket #42: …in tickets mode;task 3.2.1: …in document mode), a brief what-and-why body, and no attribution trailers — no Co-Authored-By bots, no "Generated with" footers (per theattributionconfig, default none).