eos-insights
Periodic cross-corpus reflection on EmptyOS development — where the system is heading. Aggregates a 30-day (or custom) window of the ARTIFACT corpus — git log, devlogs and _next/ track briefs, the app
SKILL.md.agent-bus/skills/eos-insights/SKILL.md
GitHubEmptyOS Insights
A "knowledgeable engineering manager reading the whole project" report. Reflect on a window of EmptyOS development across every artifact source, surface the trends no single audit sees, and write a durable report — proposing, never auto-applying. This is the EmptyOS self-audit-loop (.claude/rules/self-audit-loops.md) turned into a periodic synthesis, and the system-side analogue of Claude Code's /insights.
When to use
- User says "eos insights", "what is the system becoming", "dev trends", "what have I been building", "system reflection", "where is EmptyOS drifting"
- Monthly / milestone step-back over EmptyOS development
Do NOT use this for:
- One dev session's housekeeping →
/eos-session-wrapup. - A point-in-time code-health scan →
/eos-architecture-review,/eos-bug-audit,/eos-kb-audit,/eos-simplify. - How you use Claude Code (conversation history, tool usage) → that's Claude Code's built-in
/insights, a different corpus. - Personal life →
/eos-life-insights.
The line: this skill is the aggregator the codebase was missing — it reads across sources and over time, and it reads the outputs of trace-miner / kb-gap-miner rather than re-mining.
Pre-flight
Mostly read-only static + git + scripts. A couple of enrichments hit the daemon — only then:
- Daemon up (optional, for
eos app listproxy / miner endpoints) —curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:9000/→200. If down, read manifests + script output directly; never restart the daemon (.claude/rules/daemon-handling.md). - SDK/script shell is safe —
scripts/check_dark_flags.py,scripts/kb_claim_audit.py,scripts/kb_link_audit.pyare pure file I/O (no kernel boot), safe to run while the daemon is up. - Vault root —
[notes] pathinemptyos.toml(read it from there; don't hardcode the path).
Vocabulary
- Window — default last 30 days from today; custom on request.
- Artifact corpus — git history + devlog notes + manifests + dark-flag state + miner output + KB. NOT the conversation history.
- Track — a work lane named in
{vault}/10_Projects/emptyos/log/_next/_index.md, each with a_next/<track>.mdon-deck brief, last-touched date. - Report path —
{vault}/30_Resources/EmptyOS/insights/outputs/YYYY-MM-DD-eos.md(today).outputs/⇒ AI-authored (.claude/rules/authorship-boundary.md); setauthor: aiexplicitly.
Process
Step 0 — Read the prior scorecard (the loop closes here)
Before gathering anything, read what the last run proposed:
python scripts/insights_ledger.py scorecard eos
A proposal recurring across reports without being acted on is a stronger signal than a fresh one. Carry still-relevant ones forward, note any you can see were acted on, drop the stale. This is what makes the skill a loop, not a one-shot. (no prior ledger …) on the first run is fine.
Step 1 — Deep-research loop (read, don't just count)
Apply the deep-research method (.claude/rules/deep-research.md) to the EmptyOS artifact corpus — the four passes below are that method's moves 2–5 (the v1 failure mode was tabulating without reading; statistics dressed as insight):
1a — First pass (breadth). The cheap inventory:
- git:
git log --since="30 days ago" --pretty=format:"%h %ad %s" --date=short;git log --since="30 days ago" --name-only --pretty=format: | sort | uniq -c | sort -rn | head -30(hot files); commit-type split; per-apps/<group>/emptyos//engines/churn. {vault}/10_Projects/emptyos/log/_next/_index.md(tracks + last-touched).apps/**/manifest.toml+plugins/*/manifest.tomlcrossed with git churn (dormant).python scripts/check_dark_flags.py(dark-flag inventory; STALE = dark >90d).docs/DEFERRED-WORK.md— the deferred-feature registry: eachdeferredrow's trigger +Addedage (the "is it ready to build/deploy yet?" recheck input).trace-minertop issues by score (data/apps/trace-miner/issues.json) — aggregate, do NOT re-mine.python scripts/kb_claim_audit.py+kb_link_audit.py(+ kb-gap-miner output).python scripts/check_gap_freshness.py+python scripts/insights_ledger.py scorecard gap— market gap-analysis registry coverage (stale/unanalyzed apps, gaps recurring unaddressed → surface as candidates for a/eos-app-gap-analysisrun or promotion).
1b — Gap pick. Name the 3-5 load-bearing or uncertain claims — the ones a decision hangs on ("is engineering-pilot actually stalled?", "is the boot-import failure real and current?", "are the dormant tracks dead or just parked?"). These, not the easy counts, are what to deepen.
1c — Deep-read (the part v1 skipped). For each gap claim, READ the primary sources — don't infer from counts:
- the actual body of ~5 relevant
{vault}/10_Projects/emptyos/log/YYYY-MM-DD.mdsession logs; - the top friction samples in
data/apps/trace-miner/issues.json+ the matching lines indata/daemon.err.log(confirm a friction is real-and-CURRENT, not a stale artifact); - the actual feature code / manifest behind the oldest dark-flags before calling one "ship" or "cut".
- for each
deferredrow indocs/DEFERRED-WORK.md, a cheap readiness check (judgment, not regex — triggers are prose): did a consumer/caller appear (grep), does the named engine/app now exist, did a blocking dependency land, or has it aged pastAddedwhile the need recurs in friction / KB-gap signals? Triangulate — every headline claim rests on ≥2 independent sources (a stall = quiet git churn AND a parked devlog note, not one alone).
1d — Adversarial pass (kill overconfidence). Before writing, try to refute each top finding ("the dormant track is dead, not parked — prove it isn't"; "the healthy feat:fix ratio hides revert churn — check"). Test each heuristic against 3 known-healthy cases (.claude/rules/audits.md). Drop or downgrade anything that doesn't survive; a claim you couldn't verify is graded inferred, never asserted as fact.
Step 2 — Synthesize the report
Forecast, don't just describe. Thoroughness = a quantitative spine + narrative, not prose alone (the Claude /insights standard).
Quantitative spine (required):
- A
## Statssection right after Headline — a 2-colMetric | Valuetable (commits, files changed, lines +/−, tests touched, net-new KB, dark-flags soaking/ON). The renderer turns it into the stat-tile row. - ≥3 chartable distributions — emit each as a 2-col
Label | Valuetable (the renderer auto-draws a bar chart): commit-type split (feat/fix/refactor…), per-area churn, dark-flag status, friction-kind. Slice the corpus several ways. - Copyable artifacts — for each rule/skill/KB proposal, put the exact paste-ready text in a fenced ``` block (the renderer adds a copy button).
Sections (markdown ## — keep these names so the renderer themes them right):
- Headline — one paragraph: "what the system is becoming" (becomes the hero box). Lead with the trajectory finding, not the biggest number.
- Trend (vs prior window) — this 30d vs the prior 30d (commits, dormant count, dark-flag backlog) and a read of the previous insights report's deltas (find it: prior
…-eos.mdin the outputs dir). Trend, not snapshot — this fixes the v1 "still photo" gap. - Build velocity per track — lanes that moved/quieted, last-touched dates. Include a
Label | Valuetable (e.g. area → touches) so the renderer draws a bar chart. - Trajectory vs goals — the strategic layer v1 skipped: does where effort actually went match stated priorities (engineering-pilot / monetization, energy×software, NIW — per the project/career memories)? Surface divergence (e.g. heavy self-tooling investment while a revenue-relevant track went dormant). Wheel-for-the-codebase: over-feeding occupational/intellectual self-improvement vs shipping/financial.
- Growing vs dormant — gaining vs losing attention; parked vs truly dead (decided by the 1c deep-read, not the count alone).
- Dark-flags never flipped on — built-but-unadopted, STALE called out, each a "ship it / cut it / still cooking?" prompt.
- Top friction signatures — ranked AFTER flooring noise (auth-probe etc.); code-bug vs external; each confirmed real-and-current from the 1c read.
- KB growth + gaps — net new, broken-link/claim count, top unanswered clusters.
- Deferred-feature readiness (proposals) — walk
docs/DEFERRED-WORK.md'sdeferredrows; for any whose trigger now shows signs of being met (per the 1c readiness check), surface a Candidate to promote:<feature>— trigger may be met because<signal>. PROPOSAL ONLY — never flip a row's Status or build/enable anything; the human edits the row (deferred → triggered). Omit the section if nothing looks ready. - Suggested next steps (proposals) — candidate CLAUDE.md rules / skills / KB lessons, each with a rationale. PROPOSALS ONLY.
Evidence grading — tag every non-trivial finding with how it was derived: [counted] (a tally), [read-verified] (confirmed against a primary source in 1c), [inferred] (a judgment that survived 1d but isn't directly evidenced). The grade is the honesty signal that separates this from v1's statistics-dressed-as-insight.
Step 3 — Write the report
Block-style YAML tags:
---
author: ai
tags:
- insights
lens: eos
period: 30d
as_of: YYYY-MM-DD
lifecycle: snapshot
---
Write to {vault}/30_Resources/EmptyOS/insights/outputs/YYYY-MM-DD-eos.md.
Section-heading discipline (the renderer themes cards by keyword in the ## title): a leading ## Headline section becomes the amber hero box; titles containing friction/error/bug → red, dark-flag/dormant/stale/backlog → amber, proposal/next step/suggested → blue, kb/velocity/growing/win/health → green, else neutral. Keep the section names in this skill (Headline, Build velocity per track, Growing vs dormant, Dark-flags…, Top friction…, KB growth…, Suggested next steps) so the themes land right.
Step 3b — Render the HTML view
python scripts/render_insights_html.py "{vault}/30_Resources/EmptyOS/insights/outputs/YYYY-MM-DD-eos.md"
This writes a styled …-eos.html sibling (the Claude-Code-/insights-style report: hero + TOC + stat tiles + themed cards + tables). The markdown stays the vault-native source of truth; the HTML is a generated view. scripts/render_insights_html.py is pure stdlib (no kernel boot) — safe to run anytime. Add --open to pop it in the browser. Give the user the file:///…/YYYY-MM-DD-eos.html URL.
Step 4 — Feedback-loop posture (load-bearing)
eos-insights surfaces rule/skill/KB proposals; it does NOT auto-write rules, skills, or KB notes. The human decides whether a later session acts on any of them (.claude/rules/proposed-action.md, .claude/rules/self-audit-loops.md, "with you, not for you"). This is the EmptyOS-correct version of the yahav10/claude-insights "insights → auto-generate skills/rules" loop — propose, don't auto-apply. If the user picks a proposal, that's a separate explicit action in a follow-up turn.
Record the proposals so the next run's Step-0 scorecard can grade them:
python scripts/insights_ledger.py record eos --from "{vault}/30_Resources/EmptyOS/insights/outputs/YYYY-MM-DD-eos.md"
This closes the loop. State lives under data/apps/insights/ (telemetry, gitignored), never the vault.
Step 5 — Report to chat
- Top 3-4 trends (a velocity line, the standout dormant area, the most painful friction signature).
- The report paths — both the
.mdand thefile:///…/YYYY-MM-DD-eos.htmlview. - Which 1-2 proposals look highest-leverage, and the one EmptyOS gap this run bumped into (e.g. no machine-readable "track last-touched", trace-miner output not queryable offline) — fed forward per the self-audit-loop.
Deep-research mode (comprehensive run)
For a thorough run — or when the user asks to "go deep" / "comprehensive" — execute the 1a–1d loop as a multi-agent Workflow instead of serially:
- Phase 1 parallel deep-readers (one each: git, devlog bodies, dark-flags+code, friction+
daemon.err.log, KB) → structured findings. - Phase 2 dedup by
sig_hash(emptyos/sdk/miner_state.py). - Phase 3 independent adversarial verifiers that try to refute each top finding (majority-refute → drop).
- Phase 4 synthesize + write report + ledger-record.
This is emptyos/sdk/deep_loop.py's gap→deepen→merge realized as fan-out. The Workflow tool needs explicit user opt-in (it spawns many agents) — don't launch it unprompted; the serial 1a–1d loop is the default.
Do NOT use the explore app for insights. It is web-only (ask_web over DuckDuckGo/arxiv/etc.) — the wrong corpus. Insights analyzes the codebase and vault; asking the web "why did velocity drop" hallucinates. The deep-research engine here is the multi-agent Workflow over internal sources, not explore.
Cross-references
.claude/skills/eos-life-insights/SKILL.md— the personal-vault sibling.scripts/insights_ledger.py— the prediction ledger (Step 0 scorecard + Step 4 record).emptyos/sdk/deep_loop.py/emptyos/sdk/miner_state.py— deepen pattern + dedup/score primitives..claude/skills/eos-session-wrapup/SKILL.md— single-session log; eos-insights aggregates over many..claude/rules/self-audit-loops.md— the umbrella pattern (turn EmptyOS's tools on EmptyOS); this is its periodic-synthesis instance..claude/rules/proposed-action.md— propose, don't auto-apply (the Step 4 rule).apps/extension/dev/trace-miner/+apps/extension/dev/kb-gap-miner/— friction + KB-gap outputs aggregated here.scripts/check_dark_flags.py,scripts/kb_claim_audit.py,scripts/kb_link_audit.py— pure inputs (safe to shell).docs/DEFERRED-WORK.md— the deferred-feature registry; the §9 readiness recheck reads it and proposes promotions (the periodic "has a trigger fired?" pass lives here).{vault}/10_Projects/emptyos/log/_next/_index.md— track index + last-touched.project_feature_pipeline_flag_default_dark(memory) — why a long-dark flag is a signal..claude/rules/authorship-boundary.md—author: ai+outputs/.
When NOT to use
- One session →
/eos-session-wrapup. - A focused code-quality pass → the one-off audit skills.
- The window has almost no commits/devlog (quiet period) → say so and skip; thin data makes a step-back report misleading (the
/insights"skews on intensive sessions / variable between runs" failure mode).