Codebase Structure

Analysis Date: 2026-05-05

Directory Layout

CrumbRobos_v0/
β”œβ”€β”€ schema/
β”‚   └── crumbframe.v1.json          # JSON Schema draft-07 β€” single source of truth for frame structure
β”œβ”€β”€ frames/
β”‚   └── whoop_1s_65mm.crumbframe.json   # First frame: 1S Whoop 65mm kids workshop build
β”œβ”€β”€ scripts/
β”‚   β”œβ”€β”€ doktor.sh                   # Agent check runner β€” validation entrypoint
β”‚   └── doktor.sh.OZMv0             # Archived/original version (not used)
β”œβ”€β”€ partners/
β”‚   └── partners.json               # Global partner registry (shops, tools, knowledge, community)
β”œβ”€β”€ web/
β”‚   β”œβ”€β”€ index.html                  # Web renderer entry point (ES Module loader)
β”‚   β”œβ”€β”€ style.css                   # Dark-theme CSS with connection-type color variables
β”‚   └── renderer/
β”‚       β”œβ”€β”€ exploded2d.js           # ES Module class: SVG component node renderer
β”‚       └── connections.js          # ES Module class: SVG bezier connection renderer
β”œβ”€β”€ .planning/
β”‚   └── codebase/                   # GSD codebase map documents (this directory)
β”œβ”€β”€ .github/
β”‚   └── CONTRIBUTING.md             # Contributor guide (German)
β”œβ”€β”€ .doktor_results.json            # Last agent check run output (auto-generated by doktor.sh)
β”œβ”€β”€ CLAUDE.md                       # Project context for Claude Code
└── README.md                       # Project overview (German + English links)

Directory Purposes

schema/:
- Purpose: JSON Schema definitions that enforce valid frame structure
- Contains: One file per schema version (crumbframe.v1.json)
- Key files: schema/crumbframe.v1.json β€” $id: "crumbframe.v1", draft-07, required by all frames via $schema field

frames/:
- Purpose: One .crumbframe.json file per drone build (the knowledge base)
- Contains: Complete drone descriptions with components, connections, agent checks, embedded partner refs
- Key files: frames/whoop_1s_65mm.crumbframe.json β€” reference implementation, 1S Whoop, kids workshop
- Naming convention: {class}_{voltage}_{size}.crumbframe.json (e.g., racing_4s_5inch.crumbframe.json)

scripts/:
- Purpose: Agent/automation tooling β€” run locally by contributors before commit
- Contains: Bash scripts only. No Python scripts (Python called inline via heredoc in doktor.sh)
- Key files: scripts/doktor.sh β€” the only active script; doktor.sh.OZMv0 is an archived predecessor

partners/:
- Purpose: Global partner list independent of any single frame
- Contains: partners.json β€” shops, tool sites, knowledge resources, open-source communities
- Note: Frames also embed a partners section for frame-specific partner refs. The global partners/partners.json is the master registry.

web/:
- Purpose: Browser-based interactive renderer for frame exploded diagrams
- Contains: HTML shell, CSS, ES Module JS classes
- Key files: web/index.html (entry), web/renderer/exploded2d.js (component nodes), web/renderer/connections.js (wire drawing)
- No build step β€” served directly as static files

.planning/codebase/:
- Purpose: GSD codebase map documents consumed by /gsd-plan-phase and /gsd-execute-phase
- Generated: Yes (by /gsd-map-codebase)
- Committed: Yes

.github/:
- Purpose: GitHub community files
- Contains: CONTRIBUTING.md (German, contributor workflow)

Key File Locations

Entry Points:
- scripts/doktor.sh: CLI validation entrypoint β€” bash scripts/doktor.sh frames/DATEI.crumbframe.json
- web/index.html: Web renderer entry β€” open in browser (requires local web server for fetch to work)

Schema / Validation:
- schema/crumbframe.v1.json: JSON Schema draft-07 β€” defines all valid fields and constraints

Data:
- frames/whoop_1s_65mm.crumbframe.json: Only current frame β€” reference for all new frames
- partners/partners.json: Master partner registry

Web Renderer:
- web/renderer/exploded2d.js: Exploded2D class β€” SVG init, $ref resolution, component drawing, inspector panel
- web/renderer/connections.js: Connections class β€” typed bezier connection drawing
- web/style.css: CSS variables for connection types (--conn-power, --conn-signal, --conn-mechanical, --conn-video)

Generated / Transient:
- .doktor_results.json: Written by doktor.sh after each run β€” not hand-edited

Naming Conventions

Frame files:
- Pattern: {class}_{voltage}_{size}.crumbframe.json
- Examples: whoop_1s_65mm.crumbframe.json, racing_4s_5inch.crumbframe.json
- All lowercase, underscores, no spaces

Component keys (within components object):
- Pattern: descriptive snake_case with positional suffix for multi-instance parts
- Examples: fc_esc, motor_fl, motor_fr, motor_rl, motor_rr, prop_fl, battery, vtx, camera, rx
- Position suffixes: fl (front-left), fr (front-right), rl (rear-left), rr (rear-right)

Agent check keys (within agent_checks object):
- Pattern: descriptive snake_case of what is checked
- Examples: betaflight_release, elrs_release, product_availability, partner_price_update, schema_validate

Partner keys (within partners object):
- Pattern: snake_case short identifier
- Examples: rc_hangar15, ecalc, fpv_beginner, betaflight, expresslrs

JavaScript:
- ES Module classes: PascalCase (Exploded2D, Connections)
- Methods: camelCase (initSVG, drawComponents, showDetails)
- Variables: camelCase (frameData, fromComp, gConnections)

Where to Add New Code

New frame (drone build):
- Create: frames/{class}_{voltage}_{size}.crumbframe.json
- Template from: frames/whoop_1s_65mm.crumbframe.json
- Required fields per schema: meta, frame, power_system, use_context, passkante, components, connections, agent_checks, partners
- Validate: bash scripts/doktor.sh frames/NEWFILE.crumbframe.json

New component type (new type enum value):
- Edit: schema/crumbframe.v1.json β€” add to components.additionalProperties.properties.type.enum array
- Update: CLAUDE.md β€” add to "Komponenten-Typen" table
- Update: web/renderer/exploded2d.js β€” add shape logic in drawComponents() if visual distinction needed

New connection type:
- Edit: schema/crumbframe.v1.json β€” add to connections.items.properties.type.enum
- Edit: web/style.css β€” add .connection-{type} CSS rule with color variable
- Update: CLAUDE.md β€” add to "Verbindungs-Typen" table

New agent check type:
- Edit: schema/crumbframe.v1.json β€” add to agent_checks.additionalProperties.properties.type.enum
- Edit: scripts/doktor.sh β€” add handling branch for the new type in the agent check loop (currently loop executes bash field generically, but type-specific logic can be added before the eval)
- Update: CLAUDE.md β€” add to "Agent-Check-Typen" table

New partner:
- Edit: partners/partners.json β€” add new partner entry with name, url, type, donation_eligible
- Valid type values: shop | tool | knowledge | community

New renderer feature:
- Component visual logic: web/renderer/exploded2d.js in drawComponents() or showDetails()
- Connection visual logic: web/renderer/connections.js in draw()
- Styles: web/style.css

New doktor check (validation step):
- Edit: scripts/doktor.sh β€” add new numbered section [N] following the existing pattern (echo section header, run jq query, call ok/fail/warn helpers, increment ERRORS or WARNINGS)

Special Directories

.planning/:
- Purpose: GSD planning and codebase map documents
- Generated: Partially (codebase maps auto-generated, phase plans AI-generated but committed)
- Committed: Yes

.git/:
- Purpose: Git history
- Generated: Yes
- Committed: No (standard git)


Structure analysis: 2026-05-05