LocalIntelligence/
├── SKILL.md this file
├── Workflows/
│ ├── DailyBrief.md orchestrator — runs Refresh.ts and summarizes
│ ├── Construction.md
│ ├── Crime.md fetches city crime stats via the configured crime-data adapter
│ ├── Business.md
│ ├── Officials.md
│ ├── Legislation.md
│ ├── Elections.md
│ ├── Arrests.md
│ └── News.md
├── Tools/
│ ├── Hometown.ts parser + types — sole source of city info
│ ├── Refresh.ts orchestrator — calls 8 fetchers, writes latest.json; --fill adds AI gap-fill
│ ├── ClaudeFill.ts AI gap-filler — one web-research claude subprocess for empty sections
│ ├── UserSources.ts user-configured RSS/JSON sources from CUSTOMIZATIONS sources.json
│ ├── FetchConstruction.ts
│ ├── FetchBusiness.ts
│ ├── FetchOfficials.ts
│ ├── FetchLegislation.ts
│ ├── FetchElections.ts
│ ├── FetchArrests.ts
│ ├── FetchNews.ts
│ └── FetchCrime.ts shells to a dedicated crime-stats skill's workflow output
└── References/
└── DataSources.md catalog of universal civic sources keyed off {city,state}
Output: ~/.claude/LIFEOS/MEMORY/DATA/LocalIntelligence/<YYYY-MM-DD>_<city>_<state>_digest.json (dated history — the Week/Month/Year views aggregate these) plus latest.json written to BOTH LIFEOS/USER/CUSTOMIZATIONS/SKILLS/LocalIntelligence/ (the Pulse module's primary read path) and MEMORY/DATA/LocalIntelligence/ (legacy fallback).
--fill mode: bun run Tools/Refresh.ts --fill runs the fetchers, then ClaudeFill.ts researches any empty/unavailable sections via one web-enabled claude subprocess with deterministic output validation. The daily Pulse cron and the dashboard Refresh button both use --fill; a bare invocation stays purely deterministic.
Fetch order per refresh: built-in fetchers → UserSources.ts (deterministic, user-configured) → ClaudeFill.ts (only sections still empty). Deterministic data always wins over model research.