.agents/validate.sh is the commit gate: full E2E suite, container security-header check, and repo-hygiene checks must all pass before a phase is committed. AGENTS.md now documents the audit-driven conventions (M-1 innerHTML/terminal input, M-2 simulated curl/wget, M-4 security-header snippet, L-2 server_tokens) and the test-locked featured-projects grid. LLM-Generated: true
4.9 KiB
4.9 KiB
AGENTS.md
Rules for any agent working in this repository.
Always
- Read
.agents/PLAN.mdfirst — project goals, architecture, and the LOCKED DECISIONS (Architectural Anchors) are binding. - Follow the phased protocol in
.agents/phases/:todo/NN_name/— pending phases (00_phase.mdoverview +NN_task.mdtask files; task sort order = execution order).complete/— finished phases (read-only history).- New work is captured as a phase directory via the
phase-authoringskill; code changes flow through thephased-executionskill (each task runs in a fresh subprocess behind the validation gate).
- Test before you ship:
./build.sh— rebuilddist/(tests run againstdist/, the deployed artifact — never testsrc/directly).npm test— the Playwright E2E suite (pinned@playwright/test1.63.0; do not bump without re-checking the cached browser revision)..agents/validate.sh— the pipeline gate: full E2E suite + the container security-header check + repo-hygiene checks; must exit 0 before a phase is committed.- For any
nginx.conf/nginx-security-headers.inc/ Dockerfile change:./scripts/check-headers.sh(added by Phase 03, run automatically by.agents/validate.shwhen a container runtime exists). It builds the real image, serves it on127.0.0.1:18099and must printHEADER CHECK PASSED; don't substitute a hand-rolledcurlfor it.
Never
- Modify
.agents/PLAN.mdexcept via an explicit user-approved change to the LOCKED DECISIONS (record the approval in the PLAN's review history). - Modify anything in
.agents/phases/complete/. - Edit files in
.agents/phases/todo/without asking the user first (phase rewrites are aphase-authoringaction). - Add runtime dependencies, CDNs, or a JS build toolchain (LOCKED: vanilla
HTML/CSS/JS, flat
src/*.js,build.shhashing). - Add real network I/O to the fake terminal (LOCKED: simulated output only — see Phase 02 and PLAN §2.5).
- Add
Strict-Transport-Securityinside the nginx container — TLS/HSTS are the Caddy edge's job (the container serves plain HTTP on 8080).
Conventions
- Static site: edits in
src/→./build.sh→dist/(hash-cached names). New root-level assets are picked up automatically bybuild.sh; nested directories are not (keep JS files flat insrc/). - Terminal input is untrusted: never render typed input or
commandHistorywithinnerHTML— route it throughupdateDisplay()/textContent(audit M-1, guarded by the markup-payload test intests/e2e/02-terminal.spec.js). The onlyinnerHTMLuses allowed insrc/terminal.jsare static prompt literals, theclear/prank element wipes, and the cannedneofetchoutput (thecmdText === 'neofetch'branch — every other command output goes throughtextContent). Interminal-vim.js/terminal-achievements.jsinnerHTMLis acceptable only with static markup orescapeHtml()-escaped text. - The fake terminal does zero network I/O:
curl/wgetrender canned output fromsimulatedCurlOutput()/simulatedWgetOutput()insrc/terminal-commands.js(pure string builders, no DOM, no network). Keep any browser-side fetch call out ofsrc/entirely (audit M-2, Phase 02). Guarded by the curl/wget regression test intests/e2e/02-terminal.spec.js, which records every request whose URL falls outsidebaseURLfromplaywright.config.jsand fails the suite if the list is not empty. - Security headers live in
nginx-security-headers.inc(the Dockerfile copies it to/etc/nginx/snippets/security-headers.inc) and everylocationinnginx.confincludes it. nginx does not mergeadd_headeracross configuration levels, so never rely on server-level inheritance and never add inline securityadd_headerlines tonginx.conf— put them in the snippet (audit M-4, Phase 03).server_tokens off;stays in theserverblock (audit L-2).scripts/check-headers.shguards this rule: drop oneincludefrom a location and the check fails for that path. - Featured-projects content is test-locked: the
#projectsgrid insrc/index.html(six cards in a fixed order — Brain of Reese first with its Gitea source link, ServWaf last with no link because it is closed source) is asserted by thefeatured projects show the six updated cards in ordertest intests/e2e/01-page.spec.js. Edit the cards insrc/index.htmland update that test in the same change (Phase 05). - Terminal modules:
terminal-commands.js(canned data),terminal-achievements.js,terminal-vim.js,terminal.js(core) — load order is fixed inindex.html(alldefer); keep dependencies pointing only at earlier files. - Commits: small, imperative subject; one logical change per commit.
dist/,node_modules/,test-results/,playwright-report/are build/test artifacts — never edit them by hand.