Imported from CRELLIA-S-L/crawl-call (
AGENTS.md). Install upstream withnpx skills add CRELLIA-S-L/crawl-call. Copyright stays with the author.
Crawl Call: Chomp Company — agent guide
A summary for coding agents; the project follows the SRS-DD standard.
On any conflict, specs/README.md wins — it is the single normative document on the specification.
System behavior is described in specs/ as numbered requirements with links between them and references to code.
- Specification rules —
specs/README.md, by section;python3 tools/srs_view.py --vocabularyprints the words a block may use. - Engineering principles —
specs/constitution.md(ART-*); they apply to every task. - Markdown is not wrapped to a width — a line breaks where the meaning breaks, never inside a sentence; the renderer does the wrapping.
- Check —
python3 tools/srs_check.py. - Run the tests —
sh scripts/run-tests.sh <simulator-udid>: it boots the simulator, builds and runs as separate phases under a watchdog, and prints what each took.CRAWLCALL_TIMEOUTsets the watchdog. The reasoning, the phase times and why it is not one command are inspecs/50-verification.md. - Run a build on the phone —
CRAWLCALL_DEVICE=<device-udid> sh scripts/run-on-device.sh <app> [screenshot]: it installs, launches, waits, captures if asked, and closes the app again — on the way out as well as at the end, because a run is over when the app is terminated (specs/50-verification.md, FR-TOOL-180).CRAWLCALL_WATCHsets how long it is left running;CRAWLCALL_RECORD=<file>switches the frame record on, takes it off the phone and names the slowest frames (FR-TOOL-250). The device is given by the environment; no device identifier lives in the repository — the maintainer's standing rule, not a requirement. - Read —
python3 tools/srs_view.py <ID>for one requirement with its links resolved,--code <path>for the requirements describing a file (--statementsadds what each obliges),<ID> --wherefor the lines that carry it (--sourceprints them),--areasfor what the specification is divided into,--openfor a page a non-engineer can read;.claude/skills/srs-page/SKILL.mdis the procedure around it. - Check a finished change —
.claude/skills/srs-check/SKILL.mdreads theverificationmethod and thetestsfield of every requirement the change touched, and offers exactly those; it runs nothing unasked. - Skills — the procedures in
.claude/skills/*/SKILL.mdare plain markdown; an agent without a skill system reads them directly as workflow guides. - Freeze a baseline —
python3 tools/srs_baseline.py X.Y.Zwrites the row intospecs/92-baselines.md; the commit that carries it is the baseline, and.claude/skills/srs-baseline/SKILL.mdis the procedure. Nothing here commits or tags for you. - Upgrade the framework —
python3 tools/srs_upgrade.pyshows the version transition, the upgrade notes and the file list, then asks;.claude/skills/srs-upgrade/SKILL.mdis the procedure. No framework clone, no address to look up.
Two ways in
A question about how the system works starts with what this project wrote about itself — specs/00-glossary.md, specs/01-introduction.md, specs/02-overview.md: short, and in the project's own words, which a search over requirement text assumes you already know. Then --areas, then one area, then the requirement, then its code.
A change to behavior starts at the loop below.
The loop
- Before changing behavior, find the requirements that describe it:
python3 tools/srs_view.py --code <path/to/file>, or the tables inspecs/90-traceability.md. None exist — create one first, with the initial status per the Lifecycle section ofspecs/README.md. - Plans reference requirement IDs, not prose.
- Implement.
- Record what you chose: each way the change met a requirement that could have been met another way is a decision — Workflow in
specs/README.mdsays what counts — and goes intospecs/adr/; when there was none, the report says so. - Close the loop: status,
code,tests— in the same set of edits as the code. - Run the checker.
The rules most easily broken
- Changing behavior — first find or create the requirement, then write the code.
specs/90-traceability.mdis generated by a script; never edit it by hand.- Builds, tests, and every other action that ART-030 of the constitution reserves run only with the user's explicit confirmation.
A run on a device is closed when it is over — the app terminated, not left in the background — including a run that failed or was interrupted; the reason is the next measurement's cold start (
specs/50-verification.md). - Naming a record to a person — a requirement, a decision, and where the project keeps the layers an element or a grounds record: at its first mention in what the person reads as a whole (a message, a plan, a report), give its title, the file it is written in and its status, pasted from the tool, never typed:
python3 tools/srs_view.py --cite <ID>…printsFR-<AREA>-<NNN> — <its own title> (specs/<file>.md, <status>)and cites a decision by itsADR-NNNN;python3 tools/srs_arch.py --citeandpython3 tools/srs_grounds.py --citeprint the same form for an element and a register record. Afterwards the number alone is enough; insidespecs/,arch/andgrounds/the identifier is the name. A line a checker printed is run through--citebefore it is relayed. The rule holds in a table, a list, the steps of a plan and the report of any procedure — a template with no place for the citation is one you add it to. It is checked at sending: what was pasted is what the tool printed — no bold around it, no backticks around the file, nothing added inside the brackets. A mention in passing is a mention. A span named as a set —FR-<AREA>-010throughFR-<AREA>-090, a whole area — is one name, not a mention of each member. A commit message and the changelog are the exception and name identifiers bare, in a trailing parenthesis. A number the specification does not carry yet is a proposal, and is marked as one. - Reading the code behind a change — take the files from the
codeandtestsfields of the requirements the change belongs to (--code <path>answers from the other end), not from a search over the repository. Go wider where you must, and say where you went. - Reporting to a person — write in sentences that follow one another, and keep a list or a table for what the reader has to count or compare. A label with a fragment after it is a note to yourself.
- Saying what the project's files say — read the source in the same message and match the sentence to it before sending, not to what you remember. A count is derived over the current files, a claim that something is nowhere written names what was searched, and a paraphrase is checked against the passage it paraphrases.
- Putting something to a person for a decision — a sentence for a document, a requirement's text, a step of a plan: the message that asks carries the text as it would be written, quoted in a block where it is long; "as shown above" is a key handed over instead of the thing, the same failure as a bare identifier.
- A rule the conversation settles — where something agreed will bind the work after this task is over and no requirement says it, offer to author the requirement, naming what it would oblige and the area it belongs to. Offered, never written: the maintainer decides whether it is written at all.
- A commit that alters behavior names the requirement identifiers it implements, bare, in a trailing parenthesis — ART-060 asks the commit or the pull request for them, and the identifiers are the ones the change was planned from.
