Resumen (ES)
Hoy (2026-05-28) en dojo-os aterrizamos PR #2381 con un patrón de 4 curas de defensa-en-profundidad contra una deriva real: agentes (y humanos) clasifican Edge Functions por la dependencia externa que tocan (Stripe → ¿Launchpad?) en vez de por su propósito (per-Path SKU → Pathways). El caso fundador fue stripe-create-path-checkout-session: una EF de Pathways (origen DOJ-4002) que un agente etiquetó como "Launchpad/Stripe EF" porque vio Stripe en el código.
Las 4 curas en dojo-os:
- Cura 1 — Ownership explícito:
docs/repo-health/edge-function-classification.md lista cada EF con su pillar canónico y ticket de origen.
- Cura 2 — Clasificación activa:
.claude/scripts/classify-ef-pillar.sh clasifica por header ((DOJ-NNNN)), no por dependencia.
- Cura 3 — Regla de agente: sección "Pillar Classification" en
CLAUDE.md + memoria por-sesión feedback_pillar_by_purpose_not_dependency.md.
- Cura 4a — Hook a nivel repo:
.claude/hooks/pre-write-ef-pillar-header.sh (PreToolUse) bloquea EFs nuevas sin (DOJ-NNNN) en las primeras líneas.
Lo que falta — Cura 4b: defensa cross-repo. Otros repos que ya alojan o eventualmente alojarán Edge Functions o código atribuido por pillar (dojo-academy, internal-team-trainings, civic-tech, etc.) no tienen el guardrail. Si cualquier repo futuro crea código pillar-attributed sin la convención, la misma deriva recurre.
English summary
The drift: classify-by-dependency vs classify-by-purpose. dojo-os PR #2381 (today) shipped Cures 1–4a as a repo-local defense. Cure 4b lifts the hook into make-no-mistakes-toolkit so any repo using the toolkit can opt in via config, generalizing the rule beyond DojoCodingLabs (org-agnostic ticket-prefix knob).
Agent Layer
Scope
Add a toolkit-level PreToolUse hook (natural home: hooks/atomic/, parallel to the existing pre-atomic.sh / post-atomic-drift.sh pattern from the DOJ-4064 atomic-drift-thesis work).
Detection
- Trigger:
Write tool calls to a path matching the configured EF folder pattern (default: supabase/functions/*/index.ts).
- Rule: first 25 lines of the file content must contain a Linear ticket reference matching the configured prefix regex (default:
[A-Z]{2,4}-[0-9]+).
- Generalization: do not hardcode
DOJ-. The toolkit is org-agnostic; encode the prefix as a config knob so other Linear workspaces (and other ticket systems with similar shapes) can adopt.
Enforcement output
- Exit 1 with structured stderr guidance:
- Why this matters (drift thesis link)
- How to fix (add
(TICKET-NNNN) to the EF header, pointing to the origin ticket — not the dependency)
- Pointer to the repo's local
edge-function-classification.md (if present)
- The hook MUST be a no-op when the rule is disabled in config (default: disabled to avoid breaking existing toolkit consumers).
Configurability
Per-repo opt-in via a new config file hooks/atomic/edge-function-pillar-rules.json (shape parallel to the existing .atomic-design-rules.json consumed by atomic-design-toolkit):
{
"enabled": false,
"edge_function_paths": ["supabase/functions/*/index.ts"],
"ticket_prefix_regex": "[A-Z]{2,4}-[0-9]+",
"header_scan_lines": 25,
"classification_doc_path": "docs/repo-health/edge-function-classification.md"
}
Repos adopt by:
- Copying the config file into their repo root (or
.claude/).
- Setting
enabled: true.
- Tuning
edge_function_paths (some repos use AWS Lambda / Cloudflare Workers layouts).
- Tuning
ticket_prefix_regex for their workspace.
Optional companion: bootstrap slash command
/make-no-mistakes:ef-pillar-init — parallel to the existing v1.14 atomic-rules-init pattern. Scaffolds:
hooks/atomic/edge-function-pillar-rules.json
- A starter
docs/repo-health/edge-function-classification.md template
- Settings entry to register the hook
Acceptance Criteria
Tradeoffs (honest)
- Cost: ~150–250 LOC hook + config + docs, plus ~50–80 LOC tests.
- Benefit: prevents dependency-vs-purpose drift across all repos using the toolkit. Same defense, one source of truth.
- Risk — generalization: Edge Function is not a universal concept. AWS Lambda layouts, Cloudflare Workers, Vercel functions, etc. differ. Mitigation: the
edge_function_paths config knob lets each repo declare its own EF layout. The rule's essence (a ticket-of-origin in the header of pillar-attributed code) is layout-agnostic.
- Risk — false positives: a legitimate refactor that moves code between EFs without changing ownership might be blocked. Mitigation: the rule only fires on
Write to NEW files (existing files are not re-scanned). Edits to pre-existing EFs without ticket headers are out of scope (handled by a separate audit, not this hook).
- Maintenance: regex pattern + ticket-prefix knob need clear docs. The reference doc must explain how to configure for non-DojoCodingLabs adopters.
Context Files
Created by Claude Code on behalf of @lapc506
Resumen (ES)
Hoy (2026-05-28) en
dojo-osaterrizamos PR #2381 con un patrón de 4 curas de defensa-en-profundidad contra una deriva real: agentes (y humanos) clasifican Edge Functions por la dependencia externa que tocan (Stripe → ¿Launchpad?) en vez de por su propósito (per-Path SKU → Pathways). El caso fundador fuestripe-create-path-checkout-session: una EF de Pathways (origenDOJ-4002) que un agente etiquetó como "Launchpad/Stripe EF" porque vio Stripe en el código.Las 4 curas en
dojo-os:docs/repo-health/edge-function-classification.mdlista cada EF con su pillar canónico y ticket de origen..claude/scripts/classify-ef-pillar.shclasifica por header ((DOJ-NNNN)), no por dependencia.CLAUDE.md+ memoria por-sesiónfeedback_pillar_by_purpose_not_dependency.md..claude/hooks/pre-write-ef-pillar-header.sh(PreToolUse) bloquea EFs nuevas sin(DOJ-NNNN)en las primeras líneas.Lo que falta — Cura 4b: defensa cross-repo. Otros repos que ya alojan o eventualmente alojarán Edge Functions o código atribuido por pillar (dojo-academy, internal-team-trainings, civic-tech, etc.) no tienen el guardrail. Si cualquier repo futuro crea código pillar-attributed sin la convención, la misma deriva recurre.
English summary
The drift: classify-by-dependency vs classify-by-purpose. dojo-os PR #2381 (today) shipped Cures 1–4a as a repo-local defense. Cure 4b lifts the hook into
make-no-mistakes-toolkitso any repo using the toolkit can opt in via config, generalizing the rule beyond DojoCodingLabs (org-agnostic ticket-prefix knob).Agent Layer
Scope
Add a toolkit-level PreToolUse hook (natural home:
hooks/atomic/, parallel to the existingpre-atomic.sh/post-atomic-drift.shpattern from the DOJ-4064 atomic-drift-thesis work).Detection
Writetool calls to a path matching the configured EF folder pattern (default:supabase/functions/*/index.ts).[A-Z]{2,4}-[0-9]+).DOJ-. The toolkit is org-agnostic; encode the prefix as a config knob so other Linear workspaces (and other ticket systems with similar shapes) can adopt.Enforcement output
(TICKET-NNNN)to the EF header, pointing to the origin ticket — not the dependency)edge-function-classification.md(if present)Configurability
Per-repo opt-in via a new config file
hooks/atomic/edge-function-pillar-rules.json(shape parallel to the existing.atomic-design-rules.jsonconsumed byatomic-design-toolkit):{ "enabled": false, "edge_function_paths": ["supabase/functions/*/index.ts"], "ticket_prefix_regex": "[A-Z]{2,4}-[0-9]+", "header_scan_lines": 25, "classification_doc_path": "docs/repo-health/edge-function-classification.md" }Repos adopt by:
.claude/).enabled: true.edge_function_paths(some repos use AWS Lambda / Cloudflare Workers layouts).ticket_prefix_regexfor their workspace.Optional companion: bootstrap slash command
/make-no-mistakes:ef-pillar-init— parallel to the existing v1.14 atomic-rules-init pattern. Scaffolds:hooks/atomic/edge-function-pillar-rules.jsondocs/repo-health/edge-function-classification.mdtemplateAcceptance Criteria
hooks/atomic/pre-write-ef-pillar-header.sh(matches dojo-os semantics + adds ticket-prefix config knob)hooks/atomic/edge-function-pillar-rules.json(shape parallel to.atomic-design-rules.json)/make-no-mistakes:ef-pillar-initto bootstrap adoption in a new reporeferences/edge-function-pillar-classification.md(parallel toreferences/atomic-design-hooks-setup.mdfrom the v1.2.0 atomic-design-toolkit precedent)hooks/atomic/__tests__/covering: (a) EF with valid ticket header → pass, (b) EF missing ticket → block + exit 1, (c) non-EF path → no-op, (d) rule disabled in config → no-openabled: false. Existing toolkit consumers (dojo-os, atomic-design-toolkit, etc.) opt in explicitly. No silent breakage.Tradeoffs (honest)
edge_function_pathsconfig knob lets each repo declare its own EF layout. The rule's essence (a ticket-of-origin in the header of pillar-attributed code) is layout-agnostic.Writeto NEW files (existing files are not re-scanned). Edits to pre-existing EFs without ticket headers are out of scope (handled by a separate audit, not this hook).Context Files
.claude/hooks/pre-write-ef-pillar-header.sh.claude/scripts/classify-ef-pillar.shdocs/repo-health/edge-function-classification.mdC0AS5K6U70E, threadp1778746023651289Created by Claude Code on behalf of @lapc506