The system in AI-SDLC-frappe/ is built around one reference app on one course bench: spice_lite in sample-app/, bench /home/user/frappe-bench, site test.localhost, Frappe v15 on PostgreSQL 16, and an invented Kenya deployment in the incident pack. Most of it does not depend on that: the roster, the handoff format, the orchestrator and its gates, the Claude Code hooks, tool-guard.mjs, the eval harness and verify-system.mjs carry over unchanged. What changes is what the agents know (paths, DocTypes, apps, sites) and which bench commands they may run.
Worked target below: a spice_next_core-style bench. Replace the example values with yours:
| Course value | Example target value (replace with yours) |
|---|---|
app spice_lite in sample-app/spice_lite/ |
core app spice_next_core in apps/spice_next_core/ of your repo |
bench /home/user/frappe-bench, user frappe |
bench /opt/spice/frappe-bench, user frappe |
site test.localhost |
a disposable dev site dev.spice.localhost with allow_tests set, on PostgreSQL 16, never a copy of a country site |
| no other apps | country apps (for example spice_ke) and integration apps (for example spice_telephony with required_apps = ["spice_next_core"]) |
Order matters: each step’s check can only pass once the steps before it are done. Evaluation comes last, because golden tasks written before the context pack and agents are updated would measure the old system.
cd AI-SDLC-frappe
node scripts/capstone/stack-inventory.mjs --files > /tmp/inventory-before.md # 242 files at the time of writing
node scripts/capstone/verify-system.mjs --bench /opt/spice/frappe-bench --site dev.spice.localhost \
--app-dir apps/spice_next_core # expect FAIL rows: that is the to-do list
scripts/capstone/terms.mybench.json with the course terms that must disappear (for example {"course": ["\\bspice_lite\\b", "test\\.localhost", "/home/user/frappe-bench", "\\bSL (Patient|Encounter|Observation)\\b"]}) and rerun the inventory with --terms after every step. You are done when only the files you chose to keep (course docs, the old example runs) still match.sample-app/spice_lite/ with your core app path, and list every app on the bench with one line each: core, country apps, integration apps and their required_apps.Default bench: /opt/spice/frappe-bench, site dev.spice.localhost (PostgreSQL 16). verify-system --bench warns when CLAUDE.md names a different bench than the one you check.CLAUDE.local.md (git-ignored), not into the shared file: your own bench path, your own dev site.bench --site dev.spice.localhost run-tests --app spice_next_core, one module, CI=1 when the exit code matters, and how to run pure-Python unit tests without a site if you have them.site_config.json, “Frappe hook” vs “Claude Code hook”, humans migrate and merge)..claude/rules/doctype-json.md paths: apps/spice_next_core/spice_next_core/**/doctype/**/*.json, apps/*/*/patches.txt, apps/*/*/hooks.py, and the country apps’ apps/spice_*/spice_*/fixtures/*.json (Custom Field and Property Setter fixtures are schema changes too)..claude/rules/spice-lite-python.md becomes spice-next-core-python.md with paths: apps/**/*.py; keep only rules a reviewer can check against your code.ls apps/spice_next_core/spice_next_core/*/doctype/*/*.json | wc -l.python3 .claude/skills/explain-endpoint/scripts/doctype_summary.py apps/spice_next_core/spice_next_core > /tmp/doctypes.txt prints one line per DocType with naming, search_index, unique and required fields, Links and DocPerm rows. Run it for each country app too.context/domain/spice-lite-glossary.md as your glossary from that output: your patient, encounter and observation DocTypes, their field names, and the business rules your controllers enforce.autoname in the summary.context/architecture/overview.md: the app graph (core, each country app with what it customises, each integration app with its required_apps), the process model per country deployment (gunicorn workers, RQ queues and timeouts, scheduler), and ERPNext as an external integration if you have it.context/security/phi-and-secrets-policy.md: same structure; name your integration users and where their keys live.required_apps in its hooks.py names the core app. verify-system --app-dir apps/spice_telephony --bench ... checks that the site lists every app in required_apps.verify-system --app-dir once per app you want agents to change: the app-layout, hooks-py, modules, patches and doctypes rows must be PASS for each.architecture-review/frappe-options.md: keep the core vs country app vs integration app decision table; replace the examples with one decision your team really made.psql --version; agents never read site_config.json).("is", "set") Datetime filter (D-2), search_index indexes that are never created (D-6, the pg_indexes query in .claude/skills/performance-review/checklist.md), and assertQueryCount raising TypeError (D-10). Record the result in your known-issues list; the performance and test-strategy skills depend on it.FRAPPE_SRC=/opt/spice/frappe-bench/apps/frappe node evaluations/harness/run-evals.mjs --verify-traps (also run by verify-system --bench).check-handoff.mjs, check-agents.mjs, check-roster-flat.mjs and verify-system.mjs all hard-code the roster.bash-allow entry that names test.localhost names your dev site; {bench} follows SPICE_BENCH_DIR, so set that in your shell or in CLAUDE.local.md instructions rather than editing the guard.apps/spice_next_core/spice_next_core/), protected folders for already-applied patches; tester write scope: test files only..claude/hooks/guard-bench.mjs reads its no-prompt test site from SPICE_TEST_SITE (default test.localhost): export it in the shell that starts claude, or set "env": {"SPICE_TEST_SITE": "dev.spice.localhost"} in .claude/settings.json (applies once the folder is trusted), instead of editing the hook, then node .claude/hooks/guard-bench.test.mjs..claude/settings.json: Bash(bench --site dev.spice.localhost run-tests *) replaces the test.localhost allow rules; keep every ask and deny rule, including Read(**/site_config.json) and Read(**/common_site_config.json).agents/<name>/CONTRACT.md lists exactly the tools its agent file lists: node agents/check-agents.mjs.workflows/composition/security-scope.mjs rule 2 fires on changed @frappe.whitelist or allow_guest lines and on any file under an api/ folder. If your whitelisted modules are files such as clinical/api.py, add that pattern, then node workflows/composition/composition.test.mjs.workflows/incident-response.md triage table: your real queues, timeouts and log locations per country deployment..mcp.json spice-site: point SPICE_SITE_URL and SPICE_SITE_HOST at your dev site with a read-only API user (mcp/spice-site-server/scripts/provision_api_user.py), never at a country site; node scripts/automation/check-mcp-config.mjs.workflows/examples/ as a format example or replace it with one run of your own; verify-system validates every example folder.get_all in a request path, a schema change without a patch, an f-string SQL), with synthetic data only.sre suite from your own incidents: build each evidence pack like .claude/skills/production-rca/examples/INC-2026-0922-lastn/ (redacted exports, time zones stated in the brief), run build-timeline.mjs on it (exit 0 means no PHI), and write the golden RCA a human signed off."_synthetic": true); they measure nothing in your system. Record one live run per suite and replay that in CI.docs/governance/CODEOWNERS.example to .github/CODEOWNERS with your paths: **/doctype/**, **/patches.txt, **/patches/**, **/hooks.py, **/fixtures/**, **/modules.txt to your schema owners; each country app folder to its country team; .claude/, CLAUDE.md, .mcp.json, agents/, skills/, workflows/, evaluations/ to your AI governance group.docs/governance/ai-change-gate.yml.example; set AI_GOVERNANCE_APPROVERS and SCHEMA_APPROVERS.node scripts/capstone/verify-system.mjs and CI=1 bench --site dev.spice.localhost run-tests --app spice_next_core as required checks.node scripts/capstone/verify-system.mjs --app-dir apps/spice_next_core \
--bench /opt/spice/frappe-bench --site dev.spice.localhost --with-tests # -> WIRED, exit 0
node scripts/capstone/stack-inventory.mjs --terms scripts/capstone/terms.mybench.json --max 10
/feature run and one /incident run (on an evidence pack from a past incident) on your bench, with every handoff passing node .claude/hooks/check-handoff.mjs .ai-sdlc/runs/<run-id>..claude/**, CLAUDE.md and skills/**, so the AI-config category of the gate requires an AI-governance approval.