#!/usr/bin/env bash # ============================================================================= # lib/structure.sh # Single source of truth for the canonical genome directory layout, plus the # verify/sync helpers used by scripts/verify-genomes.sh. # # IMPORTANT: this is the ONE place the structure is defined. scaffold.sh sources # this file and builds new genomes from GENOME_DIRS, so scaffolding and the # structure check can never drift apart. # ============================================================================= # NOTE — Return-code smell # Several functions in this file (and in lint.sh) use the return code as a # numeric counter (e.g. return $missing). This is a known smell: exit codes # wrap at 256 and conflate "count of problems" with "exit status". At the # current scale (<10 problems per run) the wrap-around risk is zero, so we # accept it pragmatically. If counts ever grow, switch to stdout counters # or dedicated global variables. # Canonical directories every genome must have. # raw/* are input buckets (collaborator-writable); wiki/* is the agent-owned, # contract-bound layout the lint, the index sections and the ingest skill depend on. GENOME_DIRS=( "raw/articles" "raw/transcripts" "raw/code-packs" "raw/assets" "raw/private" "wiki/sources" "wiki/entities" "wiki/concepts" "wiki/queries" "wiki/private" ) # --------------------------------------------------------------------------- # structure_report # Reports drift of against GENOME_DIRS. # - missing canonical dir → counted as drift (returns non-zero) # - extra dir under raw/ or wiki/ → warning only (does not fail) # Returns the number of MISSING canonical directories. # --------------------------------------------------------------------------- structure_report() { local base="$1" local missing=0 for d in "${GENOME_DIRS[@]}"; do if [[ ! -d "${base}/${d}" ]]; then warn "missing: ${d}" missing=$((missing + 1)) fi done # Extra directories (drift the other way) — informational only. local canon=" ${GENOME_DIRS[*]} " while IFS= read -r d; do d="${d#"${base}/"}" [[ "$canon" == *" ${d} "* ]] && continue info "extra (not in canon): ${d}" done < <(find "${base}/raw" "${base}/wiki" -mindepth 1 -type d 2>/dev/null) # NOTE: return $missing is a smell — see header. Kept for compatibility. return $missing } # --------------------------------------------------------------------------- # structure_sync # Creates any MISSING canonical directories (idempotent). Never deletes — # retiring a bucket is a deliberate, contract-aware change to GENOME_DIRS + # the templates, not an automatic prune. # --------------------------------------------------------------------------- structure_sync() { local base="$1" local added=0 for d in "${GENOME_DIRS[@]}"; do if [[ ! -d "${base}/${d}" ]]; then mkdir -p "${base}/${d}" touch "${base}/${d}/.gitkeep" success "created: ${d}" added=$((added + 1)) fi done [[ $added -eq 0 ]] && info "already in sync: ${base}" return 0 }