Merge branch 'main' into vida/research-2026-04-14
Some checks failed
Mirror PR to Forgejo / mirror (pull_request) Has been cancelled

This commit is contained in:
Leo 2026-04-14 16:54:23 +00:00
commit 95dadb9100
89 changed files with 1789 additions and 2715 deletions

View file

@ -5,15 +5,7 @@ name: Sync Graph Data to teleo-app
# This triggers a Vercel rebuild automatically.
on:
push:
branches: [main]
paths:
- 'core/**'
- 'domains/**'
- 'foundations/**'
- 'convictions/**'
- 'ops/extract-graph-data.py'
workflow_dispatch: # manual trigger
workflow_dispatch: # manual trigger only — disabled auto-run until TELEO_APP_TOKEN is configured
jobs:
sync:

2
.gitignore vendored
View file

@ -1,7 +1,7 @@
.DS_Store
*.DS_Store
ops/sessions/
ops/__pycache__/
__pycache__/
**/.extraction-debug/
pipeline.db
*.excalidraw

View file

@ -161,7 +161,7 @@ Each session searched for a way out. Each session found instead a new, independe
- **Input-based governance as workable substitute — test against synthetic biology**: Also carried over. Chip export controls show input-based regulation is more durable than capability evaluation. Does the same hold for gene synthesis screening? If gene synthesis screening faces the same "sandbagging" problem (pathogens that evade screening while retaining dangerous properties), then the "input regulation as governance substitute" thesis is the only remaining workable mechanism.
- **Structural irony claim: check for duplicates in ai-alignment then extract**: Still pending from Session 2026-03-20 branching point. Has Theseus's recent extraction work captured this? Check ai-alignment domain claims before extracting as standalone grand-strategy claim.
- **Structural irony claim: NO DUPLICATE — ready for extraction as standalone grand-strategy claim**: Checked 2026-03-21. The closest ai-alignment claim is `AI alignment is a coordination problem not a technical problem`, which covers cross-actor coordination failure but NOT the structural asymmetry mechanism: "AI achieves coordination by operating without requiring consent from coordinated systems; AI governance requires consent/disclosure from AI systems." These are complementary, not duplicates. Extract as new claim in `domains/grand-strategy/` with enrichment link to the ai-alignment claim. Evidence chain is complete: Choudary (commercial coordination without consent), RSP v3 (consent mechanism erodes under competitive pressure), Brundage AAL framework (governance requires consent — technically infeasible to compel), EU AI Act Article 92 (compels consent at wrong level — source code, not behavioral evaluation). Confidence: experimental.
### Dead Ends (don't re-run these)

View file

@ -16,6 +16,8 @@ Working memory for Telegram conversations. Read every response, self-written aft
- The Telegram contribution pipeline EXISTS. Users can: (1) tag @FutAIrdBot with sources/corrections, (2) submit PRs to inbox/queue/ with source files. Tell contributors this when they ask how to add to the KB.
## Factual Corrections
- [2026-04-14] Bynomo futardio fundraise reached $19K committed (38% of $50K target) with ~6 days remaining, up from $16 at launch
- [2026-04-14] Bynomo futardio launch went live 2026-04-13 (not earlier as previously implied), $50K target, $16 committed at time of data capture, live product on 8 chains with ~$46K volume pre-raise
- [2026-04-05] MetaDAO updated metrics as of Proph3t's "Chewing Glass" tweet: $33M treasury value secured, $35M launched project market cap. Previous KB data showed $25.6M raised across eight ICOs.
- [2026-04-03] Curated MetaDAO ICOs had significantly more committed capital than Futardio cult's $11.4M launch. Don't compare permissionless launches favorably against curated ones on committed capital without qualifying.
- [2026-04-03] Futardio cult was a memecoin (not just a governance token) and was the first successful launch on the futard.io permissionless platform. It raised $11.4M in one day.

View file

@ -1,65 +0,0 @@
# Alerting Integration Patch for app.py
Two changes needed in the live app.py:
## 1. Add import (after `from activity_endpoint import handle_activity`)
```python
from alerting_routes import register_alerting_routes
```
## 2. Register routes in create_app() (after the last `app.router.add_*` line)
```python
# Alerting — active monitoring endpoints
register_alerting_routes(app, _alerting_conn)
```
## 3. Add helper function (before create_app)
```python
def _alerting_conn() -> sqlite3.Connection:
"""Dedicated read-only connection for alerting checks.
Separate from app['db'] to avoid contention with request handlers.
Always sets row_factory for named column access.
"""
conn = sqlite3.connect(f"file:{DB_PATH}?mode=ro", uri=True)
conn.row_factory = sqlite3.Row
return conn
```
## 4. Add /check and /api/alerts to PUBLIC_PATHS
```python
_PUBLIC_PATHS = frozenset({"/", "/api/metrics", "/api/rejections", "/api/snapshots",
"/api/vital-signs", "/api/contributors", "/api/domains",
"/api/audit", "/check", "/api/alerts"})
```
## 5. Add /api/failure-report/ prefix check in auth middleware
In the `@web.middleware` auth function, add this alongside the existing
`request.path.startswith("/api/audit/")` check:
```python
if request.path.startswith("/api/failure-report/"):
return await handler(request)
```
## Deploy notes
- `alerting.py` and `alerting_routes.py` must be in the **same directory** as `app.py`
(i.e., `/opt/teleo-eval/diagnostics/`). The import uses a bare module name, not
a relative import, so Python resolves it via `sys.path` which includes the working
directory. If the deploy changes the working directory or uses a package structure,
switch the import in `alerting_routes.py` line 11 to `from .alerting import ...`.
- The `/api/failure-report/{agent}` endpoint is standalone — any agent can pull their
own report on demand via `GET /api/failure-report/<agent-name>?hours=24`.
## Files to deploy
- `alerting.py``/opt/teleo-eval/diagnostics/alerting.py`
- `alerting_routes.py``/opt/teleo-eval/diagnostics/alerting_routes.py`
- Patched `app.py``/opt/teleo-eval/diagnostics/app.py`

View file

@ -1,84 +0,0 @@
# Teleo Codex — Evolution
How the collective intelligence system has grown, phase by phase and day by day. Maps tell you what the KB *contains*. This tells you how the KB *behaves*.
## Phases
### Phase 1 — Genesis (Mar 5-9)
Cory and Rio built the repo. 2 agents active. First claims, first positions, first source archives. Everything manual. ~200 commits, zero pipeline.
### Phase 2 — Agent bootstrap (Mar 10-14)
All 6 agents came online. Bulk claim loading — agents read their domains and proposed initial claims. Theseus restructured its belief hierarchy. Entity schema generalized cross-domain. ~450 commits but zero automated extractions. Agents learning who they are.
### Phase 3 — Pipeline ignition (Mar 15-17)
Epimetheus's extraction pipeline went live. 155 extractions in 2 days — the system shifted from manual to automated. 67 MetaDAO decision records ingested (governance history). The knowledge base doubled in density.
### Phase 4 — Steady state (Mar 17-22)
Daily research sessions across all agents. Every agent running 1 session/day, archiving 3-10 sources each. Enrichment cycles started — new evidence flowing to existing claims. Divergence schema shipped (PR #1493) — claims began contradicting each other productively. ~520 commits.
### Phase 5 — Real-time (Mar 23+)
Telegram integration went live. Rio started extracting from live conversations. Astra expanded into energy domain (fusion economics, HTS magnets). Infrastructure overhead spiked as ingestion scaled. Transcript archival deployed. The system went from batch to live.
## Daily Heartbeat
```
Date | Ext | Dec | TG | Res | Ent | Infra | Agents active
------------|-----|-----|----|-----|-----|-------|------------------------------------------
2026-03-05 | 0 | 0 | 0 | 0 | 0 | 0 | leo, rio
2026-03-06 | 0 | 0 | 0 | 0 | 0 | 0 | clay, leo, rio, theseus, vida
2026-03-07 | 0 | 0 | 0 | 0 | 0 | 0 | astra, clay, leo, theseus, vida
2026-03-08 | 0 | 0 | 0 | 0 | 0 | 0 | astra, clay, leo, rio, theseus, vida
2026-03-09 | 0 | 0 | 0 | 0 | 0 | 0 | clay, leo, rio, theseus, vida
2026-03-10 | 0 | 0 | 0 | 3 | 0 | 1 | astra, clay, leo, rio, theseus, vida
2026-03-11 | 0 | 0 | 0 | 7 | 0 | 30 | astra, clay, leo, rio, theseus, vida
2026-03-12 | 0 | 0 | 0 | 1 | 0 | 11 | astra, clay, leo, rio, theseus, vida
2026-03-13 | 0 | 0 | 0 | 0 | 0 | 0 | theseus
2026-03-14 | 0 | 0 | 0 | 0 | 0 | 26 | rio
2026-03-15 | 35 | 30 | 0 | 0 | 6 | 5 | leo, rio
2026-03-16 | 53 | 37 | 0 | 2 | 9 | 21 | clay, epimetheus, leo, rio, theseus, vida
2026-03-17 | 0 | 0 | 0 | 1 | 0 | 0 | rio
2026-03-18 | 81 | 0 | 4 | 12 | 17 | 18 | astra, clay, epimetheus, leo, rio, theseus, vida
2026-03-19 | 67 | 0 | 0 | 5 | 26 | 41 | astra, epimetheus, leo, rio, theseus, vida
2026-03-20 | 27 | 1 | 0 | 6 | 9 | 38 | astra, epimetheus, leo, rio, theseus, vida
2026-03-21 | 23 | 0 | 1 | 5 | 3 | 44 | astra, epimetheus, leo, rio, theseus, vida
2026-03-22 | 17 | 0 | 0 | 5 | 2 | 32 | astra, leo, rio, theseus, vida
2026-03-23 | 22 | 0 | 14 | 5 | 16 | 190 | astra, epimetheus, leo, rio, theseus, vida
2026-03-24 | 31 | 0 | 7 | 5 | 21 | 70 | astra, epimetheus, leo, rio, theseus, vida
2026-03-25 | 14 | 0 | 10 | 4 | 18 | 36 | astra, leo, rio, theseus, vida
```
**Legend:** Ext = claim extractions, Dec = decision records, TG = Telegram extractions, Res = research sessions, Ent = entity updates, Infra = pipeline/maintenance commits.
## Key Milestones
| Date | Event |
|------|-------|
| Mar 5 | Repo created. Leo + Rio active. First claims and positions. |
| Mar 6 | All 6 agents came online. Archive standardization. PR review requirement established. |
| Mar 10 | First research sessions. Theseus restructured belief hierarchy. Leo added diagnostic schemas. |
| Mar 11 | Rio generalized entity schema cross-domain. 7 research sessions in one day. |
| Mar 15 | Pipeline ignition — 35 extractions + 30 decision records in one day. |
| Mar 16 | Biggest extraction day — 53 extractions + 37 decisions. |
| Mar 18 | Peak research — 12 sessions. Clay's last active day (2 sessions). 81 extractions. |
| Mar 19 | Divergence schema shipped (PR #1493). Game mechanic for structured disagreement. |
| Mar 21 | Telegram integration — first live chat extractions. |
| Mar 23 | Infrastructure spike (190 infra commits) as ingestion scaled. Rio Telegram goes live at volume. |
| Mar 25 | Transcript archival deployed. Astra expanded into energy domain. |
## Flags & Concerns
- **Clay dropped off after Mar 18.** Only 2 research sessions total vs. 8 for other agents. Entertainment domain is under-researched.
- **Infra-to-substance ratio is ~2:1.** Expected during bootstrap but should improve. Mar 23 was worst (190 infra vs. 22 extractions).
- **Enrichment quality issues.** Space (#1751) and health (#1752) enrichment PRs had duplicate evidence blocks, deleted content, and merge conflicts. Pipeline enrichment pass creates artifacts requiring manual cleanup.
## Current State (Mar 25)
| Metric | Count |
|--------|-------|
| Claims in KB | 426 |
| Entities tracked | 103 |
| Decision records | 76 |
| Sources archived | 858 |
| Domains active | 14 |
| Agents active | 6 (Clay intermittent) |
| Total commits | 1,939 |

File diff suppressed because it is too large Load diff

View file

@ -1,59 +0,0 @@
# Week 3 (Mar 17-23, 2026) — From Batch to Live
## Headline
The collective went from a knowledge base to a live intelligence system. Rio started ingesting Telegram conversations in real-time, Astra spun up covering space/energy/manufacturing, and the KB expanded from ~400 to 426 claims across 14 domains. The pipeline processed 597 sources and generated 117 merged PRs.
## What actually happened
### Astra came alive
The biggest structural change — a new agent covering space-development, energy, manufacturing, and robotics. In 8 days, Astra ran 8 research sessions, archived ~60 sources, and contributed 29 new claims. The energy domain is entirely new: fusion economics, HTS magnets, plasma-facing materials. Space got depth it didn't have: cislunar economics, commercial stations, He-3 extraction, launch cost phase transitions.
### Rio went real-time
Telegram integration means Rio now extracts from live conversations, not just archived articles. ~59 Telegram-sourced commits. Also processed 46 decision records from MetaDAO governance — the futarchy proposal dataset is now substantial. Plus 8 SEC regulatory framework claims that gave the IF domain serious legal depth.
### Theseus stayed steady
8 research sessions, ~58 sources. Major extractions: Dario Amodei pieces, Noah Smith superintelligence series, Anthropic RSP rollback, METR evaluations. AI alignment domain is the deepest in the KB.
### Vida kept pace
8 research sessions, ~51 sources. Health enrichments from GLP-1 economics, clinical AI, SDOH evidence.
### Clay went quiet
2 research sessions on Mar 18, then silence. Entertainment domain is the least active. Needs attention.
### Leo focused on infrastructure
Divergence schema shipped (PR #1493). 6 research sessions. Most time went to PR review, conflict resolution, and evaluator role.
## By the numbers
| Metric | Count |
|--------|-------|
| New claims added | ~29 |
| Existing claims enriched | ~132 files modified |
| Sources archived | 597 |
| Entities added | 10 |
| Decision records added | 46 |
| Merged PRs | 117 |
| Research sessions | 42 |
| Telegram extractions | ~59 |
| Pipeline/maintenance commits | ~420 |
## What's meaningful
- **29 new claims** — real intellectual growth, mostly space/energy (Astra) and IF regulatory (Rio)
- **132 claim enrichments** — evidence accumulating on existing positions
- **46 decision records** — primary futarchy data, not analysis of analysis
- **Divergence schema** — the KB can now track productive disagreements
- **Telegram going live** — first real-time contribution channel
## What changed about how we think
The biggest qualitative shift: the KB now has enough depth to create real tensions. The divergence schema shipped precisely because claims are contradicting each other productively (GLP-1 inflationary vs. deflationary by geography; human-AI collaboration helps vs. hurts by task type). The collective is past the accumulation phase and into the refinement phase.
## Concerns
1. Clay silent after day 1
2. Enrichment pipeline creating duplicate artifacts (PRs #1751, #1752)
3. Infra-to-substance ratio at 2:1
---
*Generated by Leo, 2026-03-25*

View file

@ -0,0 +1,17 @@
---
type: claim
domain: entertainment
description: Exponential cost reduction trajectory creates structural shift where production capability becomes universally accessible within 3-4 years
confidence: experimental
source: MindStudio, 2026 AI filmmaking cost data
created: 2026-04-14
title: "AI production cost decline of 60% annually makes feature-film-quality production accessible at consumer price points by 2029"
agent: clay
scope: structural
sourcer: MindStudio
related_claims: ["[[non-ATL production costs will converge with the cost of compute as AI replaces labor across the production chain]]"]
---
# AI production cost decline of 60% annually makes feature-film-quality production accessible at consumer price points by 2029
GenAI rendering costs are declining approximately 60% annually, with scene generation costs already 90% lower than prior baseline by 2025. At this rate, costs halve every ~18 months. Current data shows 3-minute AI short films cost $75-175 versus $5,000-30,000 for traditional professional production (97-99% reduction), and a feature-length animated film was produced by 9 people in 3 months for ~$700,000 versus typical DreamWorks budgets of $70M-200M (99%+ reduction). Extrapolating the 60%/year trajectory: if a feature film costs $700K today, it will cost ~$280K in 18 months, ~$112K in 3 years, and ~$45K in 4.5 years. This crosses the threshold where individual creators can self-finance feature-length production without institutional backing. The exponential rate is the critical factor—this is not incremental improvement but a Moore's Law-style collapse that makes production capability a non-scarce resource within a single product development cycle.

View file

@ -0,0 +1,17 @@
---
type: claim
domain: entertainment
description: The parallel acquisition strategies—holding companies buying data infrastructure versus private equity rolling up talent agencies—represent fundamentally different bets on whether creator economy value concentrates in platform data or human relationships
confidence: experimental
source: "New Economies 2026 M&A Report, dual-track acquisition pattern"
created: 2026-04-14
title: "Creator economy M&A dual-track structure reveals competing theses about value concentration"
agent: clay
scope: structural
sourcer: New Economies / RockWater
related: ["algorithmic-distribution-decouples-follower-count-from-reach-making-community-trust-the-only-durable-creator-advantage", "creator-owned-direct-subscription-platforms-produce-qualitatively-different-audience-relationships-than-algorithmic-social-platforms-because-subscribers-choose-deliberately", "creator and corporate media economies are zero-sum because total media time is stagnant and every marginal hour shifts between them"]
---
# Creator economy M&A dual-track structure reveals competing theses about value concentration
The 2025-2026 creator economy M&A wave exhibits two distinct acquisition strategies running in parallel, revealing competing institutional theses about where value actually concentrates. Track 1: Traditional advertising holding companies (Publicis, WPP) are acquiring 'tech-heavy influencer platforms to own first-party data'—betting that value lives in the data infrastructure layer. Track 2: Private equity firms are 'rolling up boutique talent agencies into scaled media ecosystems'—betting that value lives in the talent relationship layer. These are not complementary strategies but competing hypotheses about the fundamental value driver. The holding companies' data infrastructure thesis assumes that platform-level behavioral data and audience insights are the defensible asset. The PE talent relationship thesis assumes that individual creator-audience bonds are the defensible asset. The fact that both strategies are being pursued simultaneously at scale (81 deals in 2025, 26% software, 14% talent management) suggests institutional uncertainty about which layer will prove durable. This is not a unified 'land grab' but a bifurcated bet structure where different acquirer classes are hedging opposite positions on the same question: does creator economy value concentrate in the platform or the person?

View file

@ -0,0 +1,23 @@
---
type: claim
domain: entertainment
description: The $500M Publicis/Influential acquisition and 81-deal 2025 volume demonstrate traditional institutions are pricing and acquiring community relationships as strategic infrastructure
confidence: experimental
source: "New Economies/RockWater 2026 M&A Report, Publicis/Influential $500M deal"
created: 2026-04-14
title: "Creator economy M&A signals institutional recognition of community trust as acquirable asset class"
agent: clay
scope: structural
sourcer: New Economies / RockWater
related_claims: ["[[giving away the commoditized layer to capture value on the scarce complement is the shared mechanism driving both entertainment and internet finance attractor states]]", "[[community-trust-functions-as-general-purpose-commercial-collateral-enabling-6-to-1-commerce-to-content-revenue-ratios]]", "[[algorithmic-discovery-breakdown-shifts-creator-leverage-from-scale-to-community-trust]]"]
---
# Creator economy M&A signals institutional recognition of community trust as acquirable asset class
The Publicis Groupe's $500M acquisition of Influential in 2025 represents a paradigm shift in how traditional institutions value creator economy assets. Publicis explicitly described the deal as recognition that 'creator-first marketing is no longer experimental but a core corporate requirement.' This pricing — at a scale comparable to major advertising technology acquisitions — signals that community trust and creator relationships are now treated as strategic infrastructure rather than experimental marketing channels.
The broader M&A context reinforces this: 81 deals in 2025 (17.4% YoY growth) with traditional advertising holding companies (Publicis, WPP) and entertainment conglomerates (Paramount, Disney, Fox) as primary acquirers. The strategic logic centers on 'controlling the infrastructure of modern commerce' as the creator economy approaches $500B by 2030.
This institutional buying behavior validates community trust as an asset class through revealed preference: major corporations are allocating hundreds of millions in capital to acquire it. The acquisition targets breakdown (26% software, 21% agencies, 16% media properties) shows institutions are buying multiple layers of creator infrastructure, not just individual talent.
The shift from experimental to 'core corporate requirement' language indicates a phase transition: community relationships have moved from novel marketing tactic to recognized balance sheet asset.

View file

@ -0,0 +1,17 @@
---
type: claim
domain: entertainment
description: Cost concentration shifts from technical production to legal/rights as AI collapses labor costs, inverting the current production economics model
confidence: experimental
source: MindStudio, 2026 AI filmmaking analysis
created: 2026-04-14
title: IP rights management becomes dominant cost in content production as technical costs approach zero
agent: clay
scope: structural
sourcer: MindStudio
related_claims: ["[[non-ATL production costs will converge with the cost of compute as AI replaces labor across the production chain]]", "[[the media attractor state is community-filtered IP with AI-collapsed production costs where content becomes a loss leader for the scarce complements of fandom community and ownership]]"]
---
# IP rights management becomes dominant cost in content production as technical costs approach zero
As AI production costs collapse toward zero, the primary cost consideration is shifting to rights management—IP licensing, music rights, voice rights—rather than technical production. This represents a fundamental inversion of production economics: historically, technical production (labor, equipment, post-production) dominated costs while rights were a smaller line item. In the AI era, scene complexity is decoupled from cost—a complex VFX sequence costs the same as a simple dialogue scene in compute terms. The implication is that 'cost' of production is becoming a legal/rights problem, not a technical problem. If production costs decline 60% annually while rights costs remain constant or increase (due to scarcity), rights will dominate the cost structure within 2-3 years. This shifts competitive advantage from production capability to IP ownership and rights management expertise. Studios with large IP libraries gain structural advantage not from production infrastructure but from owning the rights that become the primary cost input.

View file

@ -0,0 +1,18 @@
---
type: claim
domain: entertainment
description: The format explicitly optimizes for engagement mechanics over story arc, generating $11B revenue without traditional narrative architecture
confidence: experimental
source: Digital Content Next, ReelShort market data 2025-2026
created: 2026-04-14
title: Microdramas achieve commercial scale through conversion funnel architecture not narrative quality
agent: clay
scope: structural
sourcer: Digital Content Next
supports: ["minimum-viable-narrative-achieves-50m-revenue-scale-through-character-design-and-distribution-without-story-depth", "consumer-definition-of-quality-is-fluid-and-revealed-through-preference-not-fixed-by-production-value"]
related: ["social-video-is-already-25-percent-of-all-video-consumption-and-growing-because-dopamine-optimized-formats-match-generational-attention-patterns", "minimum-viable-narrative-achieves-50m-revenue-scale-through-character-design-and-distribution-without-story-depth", "consumer-definition-of-quality-is-fluid-and-revealed-through-preference-not-fixed-by-production-value"]
---
# Microdramas achieve commercial scale through conversion funnel architecture not narrative quality
Microdramas represent a format explicitly designed as 'less story arc and more conversion funnel' according to industry descriptions. The format uses 60-90 second vertical episodes structured around engineered cliffhangers with the pattern 'hook, escalate, cliffhanger, repeat.' Despite this absence of traditional narrative architecture, the format achieved $11B global revenue in 2025 (projected $14B in 2026), with ReelShort alone generating $700M revenue and 370M+ downloads. The US market reached 28M viewers by 2025. This demonstrates that engagement mechanics can substitute for narrative quality at commercial scale. The format originated in China (2018) and was formally recognized as a genre by China's NRTA in 2020, expanding internationally through platforms like ReelShort, FlexTV, DramaBox, and MoboReels. Revenue models use pay-per-episode or subscription with strong conversion on cliffhanger breaks. The explicit conversion funnel framing distinguishes this from traditional storytelling—creators and analysts openly describe the format using terms like 'conversion funnel' and 'hook architecture' rather than narrative terminology.

View file

@ -0,0 +1,17 @@
---
type: claim
domain: entertainment
description: Pudgy Penguins demonstrates commercial IP success with cute characters and financial alignment but minimal world-building or narrative investment
confidence: experimental
source: CoinDesk Research, Luca Netz revenue confirmation, TheSoul Publishing partnership
created: 2026-04-14
title: Minimum viable narrative achieves $50M+ revenue scale through character design and distribution without story depth
agent: clay
scope: causal
sourcer: CoinDesk Research
related_claims: ["[[minimum-viable-narrative-strategy-optimizes-for-commercial-scale-through-volume-production-and-distribution-coverage-over-story-depth]]", "[[royalty-based-financial-alignment-may-be-sufficient-for-commercial-ip-success-without-narrative-depth]]", "[[distributed-narrative-architecture-enables-ip-scale-without-concentrated-story-through-blank-canvas-fan-projection]]"]
---
# Minimum viable narrative achieves $50M+ revenue scale through character design and distribution without story depth
Pudgy Penguins achieved ~$50M revenue in 2025 with minimal narrative investment, challenging assumptions about story depth requirements for commercial IP success. Characters exist (Atlas, Eureka, Snofia, Springer) but world-building is minimal. The Lil Pudgys animated series partnership with TheSoul Publishing (parent company of 5-Minute Crafts) follows a volume-production model rather than quality-first narrative investment. This is a 'minimum viable narrative' test: cute character design + financial alignment (NFT royalties) + retail distribution penetration (10,000+ locations) = commercial scale without meaningful story. The company targets $120M revenue in 2026 and IPO by 2027 while maintaining this production philosophy. This is NOT evidence that minimal narrative produces civilizational coordination or deep fandom—it's evidence that commercial licensing buyers and retail consumers will purchase IP based on character appeal and distribution coverage alone. The boundary condition: this works for commercial scale but may not work for cultural depth or long-term community sustainability.

View file

@ -0,0 +1,17 @@
---
type: claim
domain: entertainment
description: Unlike BAYC/Azuki's exclusive-community-first approach, Pudgy Penguins builds global IP through retail and viral content first, then adds NFT layer
confidence: experimental
source: CoinDesk Research, Luca Netz CEO confirmation
created: 2026-04-14
title: Pudgy Penguins inverts Web3 IP strategy by prioritizing mainstream distribution before community building
agent: clay
scope: structural
sourcer: CoinDesk Research
related_claims: ["[[community-owned-IP-grows-through-complex-contagion-not-viral-spread-because-fandom-requires-multiple-reinforcing-exposures-from-trusted-community-members]]", "[[progressive validation through community building reduces development risk by proving audience demand before production investment]]", "[[the media attractor state is community-filtered IP with AI-collapsed production costs where content becomes a loss leader for the scarce complements of fandom community and ownership]]"]
---
# Pudgy Penguins inverts Web3 IP strategy by prioritizing mainstream distribution before community building
Pudgy Penguins explicitly inverts the standard Web3 IP playbook. While Bored Ape Yacht Club and Azuki built exclusive NFT communities first and then attempted mainstream adoption, Pudgy Penguins prioritized physical retail distribution (2M+ Schleich figurines across 3,100 Walmart stores, 10,000+ retail locations) and viral content (79.5B GIPHY views) to acquire users through traditional consumer channels. CEO Luca Netz frames this as 'build a global IP that has an NFT, rather than being an NFT collection trying to become a brand.' This strategy achieved ~$50M revenue in 2025 with a 2026 target of $120M, demonstrating commercial viability of the mainstream-first approach. The inversion is structural: community-first models use exclusivity as the initial value proposition and face friction when broadening; mainstream-first models use accessibility as the initial value proposition and add financial alignment later. This represents a fundamental strategic fork in Web3 IP development, where the sequencing of community vs. mainstream determines the entire go-to-market architecture.

View file

@ -0,0 +1,17 @@
---
type: claim
domain: entertainment
description: Pudgy World's 160K account creation with only 15-25K DAU demonstrates that blockchain projects can convert brand awareness into trial without converting trial into engagement
confidence: experimental
source: CoinDesk, Pudgy World launch data March 2026
created: 2026-04-14
title: Web3 gaming projects can achieve mainstream user acquisition without retention when brand strength precedes product-market fit
agent: clay
scope: causal
sourcer: CoinDesk
related_claims: ["[[web3-ip-crossover-strategy-inverts-from-blockchain-as-product-to-blockchain-as-invisible-infrastructure]]", "[[progressive validation through community building reduces development risk by proving audience demand before production investment]]"]
---
# Web3 gaming projects can achieve mainstream user acquisition without retention when brand strength precedes product-market fit
Pudgy World launched with 160,000 user accounts created during January 2026 preview but sustained only 15,000-25,000 daily active users — an 84-90% drop-off from acquisition to retention. This pattern is distinct from earlier Web3 gaming failures, which typically had engaged small communities without mainstream reach. Pudgy Penguins entered with established brand strength ($50M 2025 revenue, major retail distribution through Walmart/Target) but the game itself failed to retain users despite successful acquisition. This suggests that hiding blockchain infrastructure can solve the acquisition problem (getting mainstream users to try) without solving the retention problem (getting them to stay). The 'doesn't feel like crypto at all' positioning successfully removed barriers to trial but did not create sufficient gameplay value to sustain engagement. This is evidence that brand-first, product-second sequencing in Web3 creates a specific failure mode: users arrive for the brand but leave when the product doesn't deliver independent value.

View file

@ -6,6 +6,7 @@ confidence: likely
source: "Noah Smith 'Roundup #78: Roboliberalism' (Feb 2026, Noahopinion); cites Brynjolfsson (Stanford), Gimbel (counter), Imas (J-curve), Yotzov survey (6000 executives)"
created: 2026-03-06
challenges:
- [['internet finance generates 50 to 100 basis points of additional annual GDP growth by unlocking capital allocation to previously inaccessible assets and eliminating intermediation friction']]
- [[internet finance generates 50 to 100 basis points of additional annual GDP growth by unlocking capital allocation to previously inaccessible assets and eliminating intermediation friction]]
related:
- macro AI productivity gains remain statistically undetectable despite clear micro level benefits because coordination costs verification tax and workslop absorb individual level improvements before they reach aggregate measures

View file

@ -6,6 +6,7 @@ confidence: experimental
source: "Aldasoro et al (BIS), cited in Noah Smith 'Roundup #78: Roboliberalism' (Feb 2026, Noahopinion); EU firm-level data"
created: 2026-03-06
challenges:
- [['AI labor displacement operates as a self-funding feedback loop because companies substitute AI for labor as OpEx not CapEx meaning falling aggregate demand does not slow AI adoption']]
- [[AI labor displacement operates as a self-funding feedback loop because companies substitute AI for labor as OpEx not CapEx meaning falling aggregate demand does not slow AI adoption]]
related:
- macro AI productivity gains remain statistically undetectable despite clear micro level benefits because coordination costs verification tax and workslop absorb individual level improvements before they reach aggregate measures

View file

@ -0,0 +1,17 @@
---
type: claim
domain: space-development
description: The 500-1800km SSO altitude range represents a fundamentally different and harsher radiation environment than the 325km LEO where Starcloud-1 validated GPU operations
confidence: experimental
source: SpaceNews, Blue Origin FCC filing March 19, 2026
created: 2026-04-14
title: Blue Origin Project Sunrise enters an unvalidated radiation environment at SSO altitude that has no demonstrated precedent for commercial GPU-class hardware
agent: astra
scope: causal
sourcer: SpaceNews
related_claims: ["[[starcloud-1-validates-commercial-gpu-viability-at-325km-leo-but-not-higher-altitude-odc-environments]]", "[[orbital compute hardware cannot be serviced making every component either radiation-hardened redundant or disposable with failed hardware becoming debris or requiring expensive deorbit]]"]
---
# Blue Origin Project Sunrise enters an unvalidated radiation environment at SSO altitude that has no demonstrated precedent for commercial GPU-class hardware
Blue Origin's Project Sunrise constellation targets sun-synchronous orbit at 500-1800km altitude, which places it in a significantly harsher radiation environment than Starcloud-1's 325km demonstration orbit. The source explicitly notes that 'the entire Starcloud-1 validation doesn't apply' to this altitude range. SSO orbits at these altitudes experience higher radiation exposure from trapped particles in the Van Allen belts and increased galactic cosmic ray flux compared to the very low Earth orbit where Starcloud demonstrated GPU viability. The FCC filing contains no mention of thermal management or radiation hardening approaches, suggesting these remain unsolved technical challenges. This creates a validation gap: while Starcloud proved commercial GPUs can operate at 325km, Project Sunrise proposes deploying 51,600 satellites in an environment with fundamentally different radiation characteristics, with no intermediate demonstration planned before full-scale deployment.

View file

@ -0,0 +1,17 @@
---
type: claim
domain: space-development
description: Each orbital shell can safely accommodate only 4,000-5,000 satellites before collision risk becomes catastrophic, creating a geometry-based constraint that no technology can overcome
confidence: experimental
source: MIT Technology Review, April 2026 technical assessment
created: 2026-04-14
title: LEO orbital shell capacity has a hard physical ceiling of approximately 240,000 satellites across all usable shells independent of launch capability or economics
agent: astra
scope: structural
sourcer: MIT Technology Review
related_claims: ["[[orbital debris is a classic commons tragedy where individual launch incentives are private but collision risk is externalized to all operators]]", "[[spacex-1m-odc-filing-represents-vertical-integration-at-unprecedented-scale-creating-captive-starship-demand-200x-starlink]]", "[[space traffic management is the most urgent governance gap because no authority has binding power to coordinate collision avoidance among thousands of operators]]"]
---
# LEO orbital shell capacity has a hard physical ceiling of approximately 240,000 satellites across all usable shells independent of launch capability or economics
MIT Technology Review's April 2026 analysis identifies orbital capacity as a binding physical constraint distinct from economic or technical feasibility. The article cites that "roughly 4,000-5,000 satellites in one orbital shell" represents the maximum safe density before collision risk becomes unmanageable. Across all usable LEO shells, this yields a total capacity of approximately 240,000 satellites. This is a geometry problem, not an engineering problem—satellites in the same shell must maintain minimum separation distances to avoid collisions, and these distances are determined by orbital mechanics and tracking precision limits. SpaceX's 1 million satellite filing exceeds this physical ceiling by 4x, requiring approximately 200 orbital shells operating simultaneously—essentially the entire usable LEO volume dedicated to a single use case. Blue Origin's 51,600 satellite Project Sunrise represents approximately 22% of total LEO capacity for one company. Unlike launch cost or thermal management, this constraint cannot be solved through better technology—it's a fundamental limit imposed by orbital geometry and collision physics.

View file

@ -0,0 +1,18 @@
---
type: claim
domain: space-development
description: Launch cost reduction from anticipated Starship operations improved ODC economics by 4-7x before any orbital deployment occurred
confidence: experimental
source: IEEE Spectrum, February 2026 technical assessment
created: 2026-04-14
title: Orbital data center cost premium converged from 7-10x to 3x through Starship pricing alone
agent: astra
scope: causal
sourcer: IEEE Spectrum
supports: ["the-space-launch-cost-trajectory-is-a-phase-transition-not-a-gradual-decline-analogous-to-sail-to-steam-in-maritime-transport", "launch-cost-reduction-is-the-keystone-variable-that-unlocks-every-downstream-space-industry-at-specific-price-thresholds"]
related: ["launch-cost-reduction-is-the-keystone-variable-that-unlocks-every-downstream-space-industry-at-specific-price-thresholds", "the-space-launch-cost-trajectory-is-a-phase-transition-not-a-gradual-decline-analogous-to-sail-to-steam-in-maritime-transport", "starship-achieving-routine-operations-at-sub-100-dollars-per-kg-is-the-single-largest-enabling-condition-for-the-entire-space-industrial-economy", "starcloud-3-cost-competitiveness-requires-500-per-kg-launch-cost-threshold", "orbital-data-centers-activate-through-three-tier-launch-vehicle-sequence-rideshare-dedicated-starship", "orbital-data-centers-activate-bottom-up-from-small-satellite-proof-of-concept-with-tier-specific-launch-cost-gates", "Starship economics depend on cadence and reuse rate not vehicle cost because a 90M vehicle flown 100 times beats a 50M expendable by 17x", "google-project-suncatcher-validates-200-per-kg-threshold-for-gigawatt-scale-orbital-compute"]
---
# Orbital data center cost premium converged from 7-10x to 3x through Starship pricing alone
IEEE Spectrum's formal technical assessment quantifies how Starship's anticipated pricing has already transformed orbital data center economics without any operational deployment. Initial estimates placed orbital data centers at 7-10x the cost of terrestrial equivalents. With 'solid but not heroic engineering' and Starship at commercial pricing, this ratio has improved to approximately 3x ($50B for 1 GW orbital vs $17B terrestrial over 5 years). This 4-7x improvement in relative economics occurred purely through launch cost projections, not through advances in thermal management, radiation hardening, or any other ODC-specific technology. The trajectory continues: at $500/kg launch costs (Starship's target), Starcloud's CEO implies reaching $0.05/kWh competitive parity with terrestrial compute. This demonstrates that launch cost is the dominant variable in ODC economics, with the cost premium trajectory (7-10x → 3x → ~1x) mapping directly to launch cost milestones. However, the 3x figure is contingent on Starship achieving operational cadence at projected pricing—if Starship deployment slips, the ratio reverts toward 7-10x.

View file

@ -0,0 +1,18 @@
---
type: claim
domain: space-development
description: ODC discourse could distract policymakers and investors from solving the actual binding constraints of terrestrial permitting and grid interconnection
confidence: experimental
source: Breakthrough Institute, February 2026 analysis
created: 2026-04-14
title: Orbital data center hype may reduce policy pressure for terrestrial energy infrastructure reform by presenting space as alternative to permitting and grid solutions
agent: astra
scope: causal
sourcer: Breakthrough Institute
challenges: ["orbital-data-centers-are-the-most-speculative-near-term-space-application-but-the-convergence-of-ai-compute-demand-and-falling-launch-costs-attracts-serious-players"]
related: ["space-governance-gaps-are-widening-not-narrowing-because-technology-advances-exponentially-while-institutional-design-advances-linearly", "orbital-data-centers-are-the-most-speculative-near-term-space-application-but-the-convergence-of-ai-compute-demand-and-falling-launch-costs-attracts-serious-players", "orbital-data-centers-and-space-based-solar-power-share-identical-infrastructure-requirements-creating-dual-use-revenue-bridge", "orbital-data-centers-embedded-in-relay-networks-not-standalone-constellations", "space-based-solar-power-and-orbital-data-centers-share-infrastructure-making-odc-the-near-term-revenue-bridge-to-long-term-sbsp", "orbital-data-center-governance-gap-activating-faster-than-prior-space-sectors-as-astronomers-challenge-spacex-1m-filing-before-comment-period-closes"]
---
# Orbital data center hype may reduce policy pressure for terrestrial energy infrastructure reform by presenting space as alternative to permitting and grid solutions
The Breakthrough Institute argues that current orbital data center discourse is 'mostly fueled by short-term supply constraints' that don't require an orbital solution. Their concern is that ODC excitement may crowd out policy attention from terrestrial solutions: 'Any who assert that the technology will emerge in the long-term forget that the current discourse is mostly fueled by short-term supply constraints.' The piece frames ODC as 'not a real solution for the investment, innovation, interconnection, permitting, and other needs of the artificial intelligence industry today.' This creates a systemic risk where the availability of a speculative space-based alternative reduces political pressure to solve terrestrial permitting reform, grid interconnection, and transmission buildout—the actual binding constraints. The argument is particularly notable because it comes from the Breakthrough Institute, a credible, technology-positive organization that has supported nuclear and advanced geothermal, making this not reflexive anti-tech criticism but a strategic concern about resource allocation and policy focus.

View file

@ -0,0 +1,17 @@
---
type: claim
domain: space-development
description: Microgravity eliminates natural convection and causes compressor lubricating oil to clog systems, making terrestrial data center cooling designs non-functional in orbit
confidence: experimental
source: Technical expert commentary, The Register, February 2026
created: 2026-04-14
title: Orbital data center thermal management requires novel refrigeration architecture because standard cooling systems depend on gravity for fluid management and convection
agent: astra
scope: functional
sourcer: "@theregister"
related_claims: ["orbital-data-center-thermal-management-is-scale-dependent-engineering-not-physics-constraint.md", "space-based computing at datacenter scale is blocked by thermal physics because radiative cooling in vacuum requires surface areas that grow faster than compute density.md", "orbital data centers require five enabling technologies to mature simultaneously and none currently exist at required readiness.md"]
---
# Orbital data center thermal management requires novel refrigeration architecture because standard cooling systems depend on gravity for fluid management and convection
Technical experts identified a fundamental engineering constraint for orbital data centers that goes beyond radiative cooling surface area: standard refrigeration systems rely on gravity-dependent mechanisms. In microgravity, compressor lubricating oil can clog systems because fluid separation depends on gravity. Heat cannot rise via natural convection, eliminating passive cooling pathways that terrestrial data centers use. This means orbital data centers cannot simply adapt existing data center cooling designs — they require fundamentally different thermal management architectures. The constraint is not just about radiating heat to space (which is surface-area limited), but about moving heat from chips to radiators in the first place. This adds a layer of engineering complexity beyond what most orbital data center proposals acknowledge. As one expert noted, 'a lot in this proposal riding on assumptions and technology that doesn't appear to actually exist yet.' This is distinct from the radiative cooling constraint — it's an internal fluid management problem that must be solved before the external radiation problem even matters.

View file

@ -0,0 +1,22 @@
---
type: claim
domain: space-development
description: Radiative heat dissipation in vacuum is governed by Stefan-Boltzmann law, making thermal management the binding constraint on ODC power density independent of launch costs or engineering improvements
confidence: experimental
source: TechBuzz AI / EE Times, February 2026 technical analysis
created: 2026-04-14
title: Orbital data centers require ~1,200 square meters of radiator per megawatt of waste heat (at ~350K), creating a physics-based scaling ceiling where gigawatt-scale compute demands radiator areas comparable to a large urban campus
agent: astra
scope: structural
sourcer: "@techbuzz"
related_claims: ["[[power is the binding constraint on all space operations because every capability from ISRU to manufacturing to life support is power-limited]]", "[[orbital-data-center-thermal-management-is-scale-dependent-engineering-not-physics-constraint]]", "[[orbital-radiators-are-binding-constraint-on-odc-power-density-not-just-cooling-solution]]"]
challenged_by: ["[[orbital-data-center-thermal-management-is-scale-dependent-engineering-not-physics-constraint]]"]
---
# Orbital data centers require ~1,200 square meters of radiator per megawatt of waste heat (at ~350K), creating a physics-based scaling ceiling where gigawatt-scale compute demands radiator areas comparable to a large urban campus
In orbital environments, all heat dissipation must occur via thermal radiation because there is no air, water, or convection medium. The source calculates that dissipating 1 MW of waste heat in orbit requires approximately 1,200 square meters of radiator surface area (roughly 35m × 35m), assuming a radiator operating temperature of approximately 350K (77°C). This scales linearly: a 1 GW data center would require 1.2 km² of radiator area, comparable to a large urban campus. The ISS currently uses pumped ammonia loops to conduct heat to large external radiators for much smaller power loads. The October 2026 Starcloud-2 mission is planned to deploy what was described as 'the largest commercial deployable radiator ever sent to space' for a multi-GPU satellite, suggesting that even small-scale ODC demonstrations are already pushing the state of the art in space radiator technology. Unlike launch costs or compute efficiency, this constraint is rooted in fundamental physics (Stefan-Boltzmann law for radiative heat transfer) and cannot be solved through better software, cheaper launches, or incremental engineering that does not increase radiator operating temperatures. The radiator area requirement grows with compute power, and radiators must point away from the sun while solar panels must point toward it, creating competing orientation constraints.
## Relevant Notes:
- [[orbital-data-center-thermal-management-is-scale-dependent-engineering-not-physics-constraint]] argues that thermal management is a tractable engineering problem, not a fundamental physics constraint, citing advancements like liquid droplet radiators.
- [[orbital-radiators-are-binding-constraint-on-odc-power-density-not-just-cooling-solution]] also highlights deployable radiator capacity as a binding constraint on ODC power scaling.

View file

@ -0,0 +1,17 @@
---
type: claim
domain: space-development
description: The Axiom/Kepler ODC nodes represent the first operational orbital data center deployment, but they validate edge inference (filtering, compression, AI/ML on satellite imagery) rather than data-center-class AI training
confidence: proven
source: Axiom Space / Kepler Communications, January 11, 2026 launch announcement
created: 2026-04-14
title: Orbital edge compute for space-to-space relay reached operational deployment (TRL 9) in January 2026 with SDA-compatible nodes, validating inference-class processing as the first commercially viable orbital compute use case
agent: astra
scope: functional
sourcer: "@axiomspace"
related_claims: ["[[on-orbit processing of satellite data is the proven near-term use case for space compute because it avoids bandwidth and thermal bottlenecks simultaneously]]", "[[orbital AI training is fundamentally incompatible with space communication links because distributed training requires hundreds of Tbps aggregate bandwidth while orbital links top out at single-digit Tbps]]", "[[orbital-data-centers-embedded-in-relay-networks-not-standalone-constellations]]", "[[spacex-1m-odc-filing-represents-vertical-integration-at-unprecedented-scale-creating-captive-starship-demand-200x-starlink]]"]
---
# Orbital edge compute for space-to-space relay reached operational deployment (TRL 9) in January 2026 with SDA-compatible nodes, validating inference-class processing as the first commercially viable orbital compute use case
The first two orbital data center nodes launched to LEO on January 11, 2026, as part of Kepler Communications' optical relay network. These nodes enable 2.5 Gbps optical intersatellite links (OISLs) meeting Space Development Agency (SDA) Tranche 1 interoperability standards. The compute hardware runs processing/inferencing tasks: filtering images, detecting features, compressing files, and running AI/ML models on data from other satellites. This is operational deployment (TRL 9), not demonstration. Critically, these are edge inference nodes embedded in a relay network, not standalone data-center-class training infrastructure. The use case is processing satellite data in orbit to reduce downlink bandwidth requirements and enable faster decision loops for connected spacecraft. By 2027, at least three interconnected, interoperable ODC nodes are planned. This validates that the first economically viable orbital compute application is edge processing for space assets, not replacement of terrestrial AI training data centers—a fundamentally different value proposition than the SpaceX 1M-satellite or Blue Origin Project Sunrise announcements suggest.

View file

@ -0,0 +1,17 @@
---
type: claim
domain: space-development
description: Radiator surface area scales faster than compute density making thermal management the hard limit on ODC power levels
confidence: experimental
source: Starcloud-2 mission specifications, TechCrunch March 2026
created: 2026-04-14
title: Deployable radiator capacity is the binding constraint on orbital data center power scaling as evidenced by Starcloud-2's 'largest commercial deployable radiator ever sent to space' for 100x power increase
agent: astra
scope: structural
sourcer: "@TechCrunch"
related_claims: ["[[orbital-data-center-thermal-management-is-scale-dependent-engineering-not-physics-constraint]]", "[[space-based computing at datacenter scale is blocked by thermal physics because radiative cooling in vacuum requires surface areas that grow faster than compute density]]"]
---
# Deployable radiator capacity is the binding constraint on orbital data center power scaling as evidenced by Starcloud-2's 'largest commercial deployable radiator ever sent to space' for 100x power increase
Starcloud-2's mission manifest highlights the 'largest commercial deployable radiator ever sent to space' as a key enabling technology for its 100x power generation increase over Starcloud-1. This framing — radiator as headline feature alongside NVIDIA Blackwell GPUs and AWS server blades — reveals that radiator capacity, not compute hardware availability, is the binding constraint on ODC power scaling. The physics: radiative cooling in vacuum requires surface area proportional to the fourth root of power dissipation (Stefan-Boltzmann law), meaning doubling compute power requires ~19% more radiator area. But deployable radiators face mechanical complexity limits: larger structures require more robust deployment mechanisms, increasing mass and failure risk. Starcloud-2 is likely operating at 1-2 kW compute power (100x Starcloud-1's estimated <100W), still toy scale versus terrestrial data centers. The radiator emphasis suggests that reaching datacenter-scale power (10+ kW per rack) in orbit requires breakthrough deployable radiator technology, not just cheaper launches. This is consistent with the thermal management claims in the KB but adds specificity: the constraint isn't cooling physics broadly, it's deployable radiator engineering specifically.

View file

@ -0,0 +1,17 @@
---
type: claim
domain: space-development
description: Quantifies the economic and performance trade-offs required to protect semiconductor hardware from space radiation damage
confidence: experimental
source: Breakthrough Institute, February 2026 analysis
created: 2026-04-14
title: Radiation hardening imposes 30-50 percent cost premium and 20-30 percent performance penalty on orbital compute hardware
agent: astra
scope: functional
sourcer: Breakthrough Institute
related_claims: ["[[orbital data centers require five enabling technologies to mature simultaneously and none currently exist at required readiness]]", "[[modern AI accelerators are more radiation-tolerant than expected because Google TPU testing showed no hard failures up to 15 krad suggesting consumer chips may survive LEO environments]]", "[[orbital compute hardware cannot be serviced making every component either radiation-hardened redundant or disposable with failed hardware becoming debris or requiring expensive deorbit]]"]
---
# Radiation hardening imposes 30-50 percent cost premium and 20-30 percent performance penalty on orbital compute hardware
Space radiation creates two distinct failure modes for semiconductor hardware: transient bit flips (zeros turning to ones) requiring error-correcting code memory and continuous checking, and permanent physical degradation where radiation exposure gradually disfigures semiconductor structure until chips no longer function. Protection against these failure modes through radiation hardening adds 30-50% to hardware costs while reducing performance by 20-30%. This creates a fundamental cost-performance trade-off for orbital data centers: either accept higher failure rates with commercial hardware, or pay significantly more for hardened components that perform worse. The Breakthrough Institute presents this as a 'terminal constraint' on near-term ODC viability, though the analysis does not quantify lifetime differences at various orbital altitudes or compare hardening costs to replacement strategies enabled by falling launch costs.

View file

@ -0,0 +1,17 @@
---
type: claim
domain: space-development
description: The Axiom/Kepler nodes' compliance with SDA standards before commercial deployment reveals that orbital compute is maturing through defense demand and interoperability requirements, not commercial demand first
confidence: experimental
source: Axiom Space / Kepler Communications, SDA Tranche 1 compliance in January 2026 launch
created: 2026-04-14
title: SDA Tranche 1 interoperability standards built into commercial ODC nodes from day one create deliberate dual-use architecture where defense requirements shape commercial orbital compute development
agent: astra
scope: structural
sourcer: "@axiomspace"
related_claims: ["[[commercial-odc-interoperability-with-sda-standards-reflects-deliberate-dual-use-orbital-compute-architecture]]", "[[military-commercial-space-architecture-convergence-creates-dual-use-orbital-infrastructure]]", "[[defense spending is the new catalyst for space investment with US Space Force budget jumping 39 percent in one year to 40 billion]]", "[[space governance gaps are widening not narrowing because technology advances exponentially while institutional design advances linearly]]"]
---
# SDA Tranche 1 interoperability standards built into commercial ODC nodes from day one create deliberate dual-use architecture where defense requirements shape commercial orbital compute development
The Axiom/Kepler orbital data center nodes are built to Space Development Agency (SDA) Tranche 1 interoperability standards, making them compatible with government and commercial satellite networks from day one. This is not a commercial product later adapted for defense use—the defense interoperability is architected in from inception. The nodes enable integration with government and commercial space systems through standardized optical intersatellite links. This pattern mirrors the defense-commercial convergence tracked in other space sectors: the SDA is filling the governance gap for orbital compute through technical standards rather than regulation, and commercial providers are building to those standards before a mature commercial market exists. This suggests orbital compute is following the defense-demand-floor pattern where national security requirements provide the initial market and technical specifications, with commercial applications following. The SDA standards create a dual-use architecture where the same hardware serves both defense and commercial customers, similar to satellite bus platforms and launch vehicles.

View file

@ -0,0 +1,17 @@
---
type: claim
domain: space-development
description: Orbital solar avoids permitting, interconnection queues, and grid constraints, offering the cleanest power source for firms willing to pay 3x capital premium
confidence: experimental
source: IEEE Spectrum, February 2026
created: 2026-04-14
title: Space solar eliminates terrestrial power infrastructure constraints creating strategic premium for capital-rich firms
agent: astra
scope: functional
sourcer: IEEE Spectrum
related: ["orbital-data-center-hype-may-reduce-policy-pressure-for-terrestrial-energy-infrastructure-reform-by-presenting-space-as-alternative-to-permitting-and-grid-solutions", "space-solar-produces-5x-electricity-per-panel-versus-terrestrial-through-atmospheric-and-weather-elimination", "solar irradiance in LEO delivers 8-10x ground-based solar power with near-continuous availability in sun-synchronous orbits making orbital compute power-abundant where terrestrial facilities are power-starved", "orbital-data-centers-and-space-based-solar-power-share-identical-infrastructure-requirements-creating-dual-use-revenue-bridge", "sun-synchronous-orbit-enables-continuous-solar-power-for-orbital-compute-infrastructure", "orbital-jurisdiction-provides-data-sovereignty-advantages-that-terrestrial-compute-cannot-replicate-creating-a-unique-competitive-moat-for-orbital-data-centers"]
---
# Space solar eliminates terrestrial power infrastructure constraints creating strategic premium for capital-rich firms
IEEE Spectrum identifies a strategic value proposition for orbital data centers that transcends pure cost comparison: space solar eliminates all terrestrial power infrastructure friction. While space solar produces ~5x electricity per panel versus terrestrial (no atmosphere, no weather, continuous availability in most orbits), the more significant advantage is avoiding permitting processes, interconnection queue delays, and grid capacity constraints entirely. For firms with sufficient capital and urgent compute needs, this represents a strategic premium worth paying even at 3x cost parity. The article frames this as particularly relevant given the backing from 'some of the richest and most powerful men in technology' (Musk, Bezos, Huang, Altman, Pichai)—entities for whom capital availability exceeds infrastructure access. This creates a two-tier market structure: cost-optimizing firms remain terrestrial, while capital-rich strategic players can pay the orbital premium to bypass infrastructure bottlenecks. The 3x premium becomes acceptable when terrestrial alternatives face multi-year permitting delays or grid capacity unavailability.

View file

@ -0,0 +1,17 @@
---
type: claim
domain: space-development
description: The 5x power advantage of space solar comes from eliminating atmospheric absorption and weather interference in addition to day-night cycling, providing a quantified multiplier for orbital power infrastructure economics
confidence: experimental
source: IEEE Spectrum, February 2026
created: 2026-04-14
title: Space solar produces 5x electricity per panel versus terrestrial through atmospheric and weather elimination not just continuous availability
agent: astra
scope: causal
sourcer: "@IEEESpectrum"
related_claims: ["[[solar irradiance in LEO delivers 8-10x ground-based solar power with near-continuous availability in sun-synchronous orbits making orbital compute power-abundant where terrestrial facilities are power-starved]]", "[[power is the binding constraint on all space operations because every capability from ISRU to manufacturing to life support is power-limited]]", "[[space-based solar power economics depend almost entirely on launch cost reduction with viability threshold near 10 dollars per kg to orbit]]"]
---
# Space solar produces 5x electricity per panel versus terrestrial through atmospheric and weather elimination not just continuous availability
IEEE Spectrum's technical assessment states that 'space solar produces ~5x electricity per panel vs. terrestrial (no atmosphere, no weather, most orbits lack day-night cycling).' This 5x multiplier is significant because it disaggregates the power advantage into three distinct physical mechanisms: (1) no atmospheric absorption reducing incident radiation, (2) no weather interference eliminating cloud coverage losses, and (3) orbital geometry enabling continuous illumination in sun-synchronous or high orbits. The article frames this as the core power advantage for firms 'willing to pay the capital premium,' positioning space solar as 'theoretically the cleanest power source available' with 'no permitting, no interconnection queue, no grid constraints.' The 5x figure provides a quantified baseline for orbital power infrastructure economics and explains why power-intensive applications like data centers and ISRU could justify the 3x capital premium—the power density advantage partially offsets the infrastructure cost disadvantage. This multiplier is independent of launch cost and represents a fundamental physics advantage that persists regardless of terrestrial solar improvements.

View file

@ -0,0 +1,17 @@
---
type: claim
domain: space-development
description: Amazon's FCC analysis shows 200,000 annual satellite replacements required versus 4,600 global launches in 2025, creating a physical production constraint independent of cost or technology
confidence: experimental
source: Amazon FCC petition, March 2026
created: 2026-04-14
title: SpaceX's 1 million satellite orbital data center constellation faces a 44x launch cadence gap between required replacement rate and current global capacity
agent: astra
scope: structural
sourcer: "@theregister"
related_claims: ["spacex-1m-odc-filing-represents-vertical-integration-at-unprecedented-scale-creating-captive-starship-demand-200x-starlink.md", "manufacturing-rate-does-not-equal-launch-cadence-in-aerospace-operations.md", "orbital-compute-filings-are-regulatory-positioning-not-technical-readiness.md"]
---
# SpaceX's 1 million satellite orbital data center constellation faces a 44x launch cadence gap between required replacement rate and current global capacity
Amazon's FCC petition provides the most rigorous quantitative challenge to SpaceX's 1 million satellite orbital data center filing. The math is straightforward: 1 million satellites with 5-year lifespans require 200,000 replacements per year to maintain the constellation. Global satellite launch output in 2025 was under 4,600 satellites. This creates a 44x gap between required and achieved capacity. This is not a cost problem or a technology readiness problem — it is a physical manufacturing and launch capacity constraint. Even if Starship achieves 1,000 flights per year with 300 satellites per flight (300,000 satellites/year), and if ALL of those launches served only this constellation, it would barely meet replacement demand. As of March 2026, Starship is not flying 1,000 times per year. The constraint is binding at the industrial production level, not the vehicle capability level. This analysis reveals that mega-constellation filings may be constrained more by manufacturing rate and launch cadence than by any single technology barrier.

View file

@ -0,0 +1,19 @@
---
type: claim
domain: space-development
description: The filing lacks technical specifications and mirrors SpaceX's prior Starlink mega-constellation filing pattern where initial numbers secured orbital rights for later negotiation
confidence: experimental
source: The Register / FCC filing analysis, January 30, 2026
created: 2026-04-14
title: SpaceX's 1M satellite ODC filing is a spectrum-reservation strategy rather than an engineering deployment plan
agent: astra
scope: functional
sourcer: "@theregister"
supports: ["orbital-compute-filings-are-regulatory-positioning-not-technical-readiness"]
challenges: ["spacex-1m-satellite-filing-faces-44x-launch-cadence-gap-between-required-and-achieved-capacity"]
related: ["orbital-compute-filings-are-regulatory-positioning-not-technical-readiness", "spacex-1m-odc-filing-represents-vertical-integration-at-unprecedented-scale-creating-captive-starship-demand-200x-starlink", "orbital-data-center-governance-gap-activating-faster-than-prior-space-sectors-as-astronomers-challenge-spacex-1m-filing-before-comment-period-closes", "blue-origin-project-sunrise-signals-spacex-blue-origin-duopoly-in-orbital-compute-through-vertical-integration"]
---
# SpaceX's 1M satellite ODC filing is a spectrum-reservation strategy rather than an engineering deployment plan
SpaceX filed for authority to launch 1 million satellites for orbital data centers on January 30, 2026, but the filing contains no technical specifications for radiation hardening, thermal management design, or compute architecture — only high-level claims about '100 kW of power per metric ton allocated to computing' and 'high-bandwidth optical links.' This pattern mirrors SpaceX's earlier Starlink filing for 42,000 satellites, which was widely understood as a spectrum and orbital shell reservation play to lock in frequency coordination rights and negotiate actual deployment numbers later. The filing is submitted under SpaceX's regulatory authority for FCC approval, not as an engineering review document. Amazon's critique focuses on physical impossibility (44x current global launch capacity required), but this assumes the filing represents a literal deployment plan rather than a strategic claim on orbital resources. The lack of engineering substance in a filing from a company with demonstrated technical capability suggests the primary goal is regulatory positioning — securing rights to orbital shells and spectrum allocations that can be negotiated down or phased over decades while preventing competitors from claiming the same resources.

View file

@ -0,0 +1,19 @@
---
type: claim
domain: space-development
description: The H100 demonstration establishes TRL 7 for commercial GPUs in low-altitude LEO but does not validate the 500-1800km radiation environment proposed for large-scale orbital data center constellations
confidence: experimental
source: CNBC, Starcloud-1 mission December 2025
created: 2026-04-14
title: Starcloud-1 validates commercial GPU viability at 325km LEO but not higher-altitude ODC environments
agent: astra
scope: structural
sourcer: CNBC
supports: ["orbital-data-centers-activate-bottom-up-from-small-satellite-proof-of-concept-with-tier-specific-launch-cost-gates", "modern AI accelerators are more radiation-tolerant than expected because Google TPU testing showed no hard failures up to 15 krad suggesting consumer chips may survive LEO environments"]
challenges: ["radiation-hardening-imposes-30-50-percent-cost-premium-and-20-30-percent-performance-penalty-on-orbital-compute-hardware"]
related: ["orbital-data-centers-activate-bottom-up-from-small-satellite-proof-of-concept-with-tier-specific-launch-cost-gates", "modern AI accelerators are more radiation-tolerant than expected because Google TPU testing showed no hard failures up to 15 krad suggesting consumer chips may survive LEO environments", "radiation-hardening-imposes-30-50-percent-cost-premium-and-20-30-percent-performance-penalty-on-orbital-compute-hardware"]
---
# Starcloud-1 validates commercial GPU viability at 325km LEO but not higher-altitude ODC environments
Starcloud-1 successfully operated an NVIDIA H100 GPU in orbit at 325km altitude from November-December 2025, training NanoGPT, running Gemini inference, and fine-tuning models. This establishes TRL 7 (system prototype demonstration in operational environment) for commercial datacenter-grade GPUs in space. However, the 325km altitude is significantly more benign than the 500-1800km range proposed by SpaceX and Blue Origin for large-scale ODC constellations. At 325km, the satellite operates well inside Earth's magnetic shielding and below the Van Allen belts' intense radiation zones. The 11-month expected mission lifetime is naturally limited by atmospheric drag at this altitude, meaning long-term radiation degradation curves remain unknown. Neither Starcloud nor NVIDIA disclosed radiation-induced error rates or performance degradation metrics. The demonstration proves commercial GPUs can survive LEO's vacuum and thermal cycling, but the radiation environment at higher altitudes—where most ODC proposals target—remains unvalidated.

View file

@ -0,0 +1,17 @@
---
type: claim
domain: space-development
description: First explicit industry-stated threshold connecting ODC viability to specific launch cost milestone with $0.05/kWh target power cost
confidence: experimental
source: Philip Johnston (Starcloud CEO), TechCrunch interview March 2026
created: 2026-04-14
title: Orbital data centers achieve cost competitiveness with terrestrial facilities at $500/kg launch costs according to Starcloud CEO projections for Starcloud-3
agent: astra
scope: causal
sourcer: "@TechCrunch"
related_claims: ["[[launch cost reduction is the keystone variable that unlocks every downstream space industry at specific price thresholds]]", "[[orbital-data-center-cost-premium-converged-from-7-10x-to-3x-through-starship-pricing-alone]]", "[[Starship achieving routine operations at sub-100 dollars per kg is the single largest enabling condition for the entire space industrial economy]]"]
---
# Orbital data centers achieve cost competitiveness with terrestrial facilities at $500/kg launch costs according to Starcloud CEO projections for Starcloud-3
Starcloud CEO Philip Johnston explicitly stated that Starcloud-3, their 200 kW / 3-tonne orbital data center designed for SpaceX's Starship deployment system, will be 'cost-competitive with terrestrial data centers' at a target of $0.05/kWh IF launch costs reach approximately $500/kg. This is the first publicly stated, specific dollar threshold for ODC cost parity from an operational company CEO. Current commercial Starship pricing is ~$600/kg (per Voyager Technologies filings), meaning the gap is only 17% — narrow enough that higher reuse cadence could close it by 2027-2028. Johnston noted that 'commercial Starship access isn't expected until 2028-2029,' placing cost-competitive ODC at scale in the 2028-2030 timeframe at earliest. This validates the general threshold model: each launch cost milestone activates a new industry tier. The $500/kg figure is specific, citable, and comes from a CEO with operational hardware in orbit (Starcloud-1) and paying customers lined up (Crusoe, AWS, Google Cloud, NVIDIA for Starcloud-2). This is not speculative modeling — it's a business planning threshold from someone betting $200M+ on the outcome.

View file

@ -0,0 +1,17 @@
---
type: claim
domain: space-development
description: Blue Origin filed simultaneously for TeraWave as the communications backbone, enabling a dual-use architecture where the mesh network has standalone value beyond Project Sunrise
confidence: experimental
source: SpaceNews, Blue Origin FCC filing March 19, 2026
created: 2026-04-14
title: TeraWave optical inter-satellite link architecture creates an independent communications product that can be monetized separately from the orbital data center constellation
agent: astra
scope: structural
sourcer: SpaceNews
related_claims: ["[[SpaceX vertical integration across launch broadband and manufacturing creates compounding cost advantages that no competitor can replicate piecemeal]]", "[[orbital-data-centers-embedded-in-relay-networks-not-standalone-constellations]]"]
---
# TeraWave optical inter-satellite link architecture creates an independent communications product that can be monetized separately from the orbital data center constellation
Blue Origin's simultaneous filing for TeraWave optical ISL alongside Project Sunrise reveals a vertically integrated architecture where the communications layer has independent commercial value. The filing specifies 'TeraWave optical ISL mesh for high-throughput backbone' with the ability to 'route traffic through ground stations via TeraWave and other mesh networks.' This creates optionality: if orbital data centers prove economically unviable, the TeraWave constellation could still operate as a standalone high-bandwidth communications network competing with Starlink's RF-based system. The optical ISL approach offers potential advantages in bandwidth and security over RF links. This mirrors SpaceX's vertical integration strategy but inverts the sequence—SpaceX built Starlink first as a revenue generator to fund Starship and orbital compute, while Blue Origin is attempting to build compute and communications simultaneously without an established revenue anchor.

View file

@ -0,0 +1,25 @@
# Evolve Bank & Trust
**Type:** Banking institution (fintech partner)
**Status:** Active, under regulatory scrutiny
## Overview
Evolve Bank & Trust serves as banking partner for multiple fintech platforms, including Step (acquired by Beast Industries in 2026).
## Compliance History
Evolve has three documented compliance failures:
1. **Synapse Bankruptcy (2024):** Entangled in bankruptcy resulting in $96M in unlocated consumer deposits
2. **Federal Reserve Enforcement:** Subject to Fed enforcement action for AML/compliance deficiencies
3. **Data Breach:** Experienced dark web data breach exposing customer data
These issues became focal point of Senator Warren's March 2026 scrutiny of Beast Industries' Step acquisition.
## Timeline
- **2024** — Synapse bankruptcy, $96M in unlocated consumer deposits
- **2024** — Federal Reserve enforcement action for AML/compliance deficiencies
- **2024** — Dark web data breach of customer data
- **2026** — Banking partner for Step (Beast Industries acquisition)

View file

@ -0,0 +1,21 @@
# Influential
**Type:** Creator economy platform / Influencer marketing infrastructure
**Domain:** Entertainment / Internet Finance
**Status:** Acquired by Publicis Groupe (2025)
## Overview
Influential is a tech-heavy influencer platform that provides first-party data and creator marketing infrastructure. The company was acquired by Publicis Groupe for $500M in 2025, representing one of the largest creator economy acquisitions and a signal that traditional advertising holding companies view creator infrastructure as strategic necessity.
## Timeline
- **2025** — Acquired by Publicis Groupe for $500M. Publicis described the acquisition as recognition that "creator-first marketing is no longer experimental but a core corporate requirement."
## Strategic Significance
The Publicis/Influential deal is cited as paradigmatic evidence that community trust and creator relationships have become institutionally recognized asset classes. The $500M valuation represents institutional pricing of community access infrastructure at enterprise scale.
## Sources
- New Economies / RockWater 2026 M&A Report (2026-01-12)

View file

@ -1,6 +1,6 @@
# Mediawan Kids & Family
**Type:** Production company (traditional media)
**Type:** Production company (animation)
**Parent:** Mediawan Group
**Focus:** Children's animated content
@ -10,4 +10,8 @@ Mediawan Kids & Family is the children's content division of European media grou
## Timeline
- **2025-06-02** — Announced co-production deal with Claynosaurz Inc. for 39-episode animated series, marking what the company's president described as 'the very first time a digital collectible brand is expanded into a TV series.' President explicitly cited buyer demand for content with 'pre-existing engagement and data' as rationale for the deal.
- **2025-06-02** — Announced co-production deal with Claynosaurz Inc. for 39-episode animated series. Company president stated buyers now seek content with 'pre-existing engagement and data' as risk mitigation, describing the Claynosaurz deal as 'the very first time a digital collectible brand is expanded into a TV series.'
## Strategic Position
First major traditional animation studio to publicly articulate community engagement metrics as greenlight criteria, signaling institutional adoption of community-validated IP as a content category.

View file

@ -0,0 +1,21 @@
# Publicis Groupe
**Type:** Advertising holding company
**Domain:** Entertainment / Marketing
**Status:** Active
## Overview
Publicis Groupe is a traditional advertising holding company that has pursued aggressive M&A strategy in creator economy infrastructure. The company represents the "data infrastructure" thesis in creator economy M&A, betting that value concentrates in platform control and first-party data rather than direct talent relationships.
## Timeline
- **2025** — Acquired Influential for $500M, described as signal that "creator-first marketing is no longer experimental but a core corporate requirement."
## Strategic Approach
Publicis's acquisition strategy focuses on tech-heavy influencer platforms to own first-party data and creator infrastructure, contrasting with PE firms' focus on rolling up talent agencies. This represents a bet that creator economy value concentrates in data and platform control.
## Sources
- New Economies / RockWater 2026 M&A Report (2026-01-12)

View file

@ -1,49 +1,52 @@
# Pudgy Penguins
**Type:** Company
**Domain:** Entertainment
**Status:** Active
**Founded:** 2021 (NFT collection), 2024 (corporate entity under Luca Netz)
**Type:** Web3 IP / Consumer Brand
**Founded:** 2021 (NFT collection), restructured 2022 under Luca Netz
**CEO:** Luca Netz
**Domain:** Entertainment, Consumer Products
**Status:** Active, targeting IPO 2027
## Overview
Pudgy Penguins is a community-owned IP project that originated as an NFT collection and evolved into a multi-platform entertainment brand. Under CEO Luca Netz, the company pivoted from 'selling jpegs' to building a global consumer IP platform through mainstream retail distribution, viral social media content, and hidden blockchain infrastructure.
Pudgy Penguins is a Web3 IP company that inverted the standard NFT-to-brand strategy by prioritizing mainstream retail distribution and viral content before community building. The company positions itself as "a global IP that has an NFT, rather than being an NFT collection trying to become a brand."
## Business Model
- **Retail Distribution:** 2M+ Schleich figurines across 10,000+ retail locations including 3,100 Walmart stores
- **Digital Media:** 79.5B GIPHY views (reportedly outperforms Disney and Pokémon per upload)
- **Web3 Infrastructure:** Pudgy World game (launched March 9, 2026), PENGU token, NFT collections
- **Content Production:** Lil Pudgys animated series (1,000+ minutes self-financed)
**Revenue Streams:**
- Physical retail products (Schleich figurines, trading cards)
- NFT royalties and secondary sales
- Licensing partnerships
- Digital collectibles (Pengu Card)
## Strategic Approach
**Distribution Strategy:**
- Retail-first approach: 10,000+ retail locations globally
- Viral content: 79.5B GIPHY views (reportedly outperforms Disney/Pokémon per upload in reaction gif category)
- Physical products as primary customer acquisition channel
**Minimum Viable Narrative:** Partnership with TheSoul Publishing (parent of 5-Minute Crafts) for high-volume content production rather than narrative-focused studios. Characters described as 'four penguin roommates with basic personalities' in 'UnderBerg' setting.
## Key Metrics (2025-2026)
**Hiding Blockchain:** Deliberately designed consumer-facing products to hide crypto elements. CoinDesk noted Pudgy World 'doesn't feel like crypto at all.' Blockchain treated as invisible infrastructure.
- **2025 Revenue:** ~$50M (CEO confirmed)
- **2026 Target:** $120M
- **Retail Distribution:** 2M+ Schleich figurines sold, 3,100 Walmart stores
- **Vibes TCG:** 4M cards sold
- **Pengu Card:** Available in 170+ countries
- **GIPHY Views:** 79.5B total
**Mainstream-First Acquisition:** Acquire users through viral media and retail before Web3 onboarding, inverting typical crypto project trajectory.
## Strategic Positioning
## Financial Trajectory
Unlike Bored Ape Yacht Club and Azuki, which built exclusive NFT communities first and then aimed for mainstream adoption, Pudgy Penguins inverted the sequence: mainstream distribution and viral content first, with NFT/blockchain as invisible infrastructure layer.
- **2026 Revenue Target:** $50M-$120M (sources vary)
- **IPO Target:** 2027 (Luca Netz stated he'd be 'disappointed' without IPO within 2 years)
- **Pengu Card:** Operating in 170+ countries
## Content Production
## Key Personnel
**Narrative Approach:** Minimum viable narrative—characters exist (Atlas, Eureka, Snofia, Springer) but minimal world-building investment.
- **Luca Netz:** CEO, architect of pivot from NFT project to consumer brand
**Animation Partnership:** Lil Pudgys series produced with TheSoul Publishing (parent company of 5-Minute Crafts), following volume-production model rather than quality-first approach.
## Timeline
- **2021** — Pudgy Penguins NFT collection launched
- **2024** — Luca Netz acquires project, pivots strategy toward mainstream consumer brand
- **2025-02** — Lil Pudgys animated series announced with TheSoul Publishing partnership
- **2026-03-09** — Pudgy World game launched with hidden blockchain infrastructure
- **2026** — 2M+ Schleich figurines sold across 10,000+ retail locations; 79.5B GIPHY views achieved
## Sources
- Animation Magazine (2025-02): Lil Pudgys series announcement
- CoinDesk: Strategic framing and Pudgy World review
- kidscreen: Retail distribution and financial targets
- **2021** — Original Pudgy Penguins NFT collection launched
- **2022** — Luca Netz acquires project and restructures strategy
- **2024** — Schleich figurine partnership launches, achieving mass retail distribution
- **2025** — Achieved ~$50M revenue; Vibes TCG launches with 4M cards sold
- **2026-02** — CoinDesk Research deep-dive published; company targeting $120M revenue
- **2027** — Target IPO date (CEO stated: "I'd be disappointed in myself if we don't IPO in the next two years")

View file

@ -0,0 +1,26 @@
# Pudgy World
**Type:** Browser game / virtual world
**Parent:** [[pudgy-penguins]]
**Launch:** March 10, 2026
**Model:** Free-to-play with hidden blockchain infrastructure
## Overview
Pudgy World is a free browser game launched by Pudgy Penguins, explicitly positioned as their "Club Penguin moment." The game deliberately downplays crypto elements, treating PENGU token and NFT economy as secondary to gameplay. CoinDesk reviewers described it as "doesn't feel like crypto at all."
## Metrics
- **User Accounts (Jan 2026 preview):** 160,000 created
- **Daily Active Users:** 15,000-25,000 (substantially below targets)
- **Launch Impact:** PENGU token +9%, Pudgy Penguin NFT floor prices increased
- **NFT Trading Volume:** Stable at ~$5M monthly, not growing
## Strategic Positioning
The "Club Penguin moment" framing references the massively popular children's virtual world (2005-2017, peak 750 million accounts). Pudgy World models Club Penguin's approach: virtual world identity as primary hook, blockchain as invisible plumbing.
## Timeline
- **2026-01** — Preview launch: 160K accounts created, 15-25K DAU
- **2026-03-10** — Public launch; CoinDesk review: "doesn't feel like crypto at all"

View file

@ -0,0 +1,27 @@
# ReelShort
**Type:** Microdrama streaming platform
**Parent:** Crazy Maple Studio
**Status:** Active (2026)
**Category:** Short-form video entertainment
## Overview
ReelShort is the category-leading microdrama platform, offering serialized short-form video narratives with 60-90 second episodes in vertical format optimized for smartphone viewing. The platform pioneered the commercial-scale 'conversion funnel' approach to narrative content, explicitly structuring episodes around engineered cliffhangers rather than traditional story arcs.
## Business Model
- Pay-per-episode and subscription revenue
- Strong conversion rates on cliffhanger episode breaks
- Content in English, Korean, Hindi, Spanish (expanding from Chinese-language origin)
## Market Position
- Category leader in microdramas (2025-2026)
- Competes with FlexTV, DramaBox, MoboReels
- Format originated in China (2018), formally recognized as genre by China's NRTA (2020)
## Timeline
- **2025** — Reached 370M+ downloads and $700M revenue, establishing category leadership in microdramas
- **2026** — Maintained market dominance as global microdrama revenue projected to reach $14B

View file

@ -1,25 +1,24 @@
# Step
**Type:** Teen banking app (fintech)
**Status:** Acquired by Beast Industries (February 2026)
**Domain:** entertainment (via Beast Industries), internet-finance
**Status:** Acquired by Beast Industries (2026)
**Users:** 7M+ (ages 13-17)
**Banking Partner:** Evolve Bank & Trust
## Overview
Step is a banking app targeting minors (13-17 year olds), acquired by Beast Industries in February 2026 as part of MrBeast's expansion into regulated financial services. The acquisition became subject to congressional scrutiny due to Step's user demographics, previous crypto-related content, and banking partner risk.
## Key Details
- **User base:** Primarily minors (13-17 years old)
- **Banking partner:** Evolve Bank & Trust (subject to Fed enforcement action, central to 2024 Synapse bankruptcy with $96M unlocated customer funds, confirmed dark web data breach)
- **Previous content:** Published resources 'encouraging kids to pressure their parents into crypto investments' (per Warren Senate letter)
- **Acquisition price:** Undisclosed
## Timeline
- **2026-02** — Acquired by Beast Industries (price undisclosed)
- **2026-03-23** — Named in Senator Warren letter to Beast Industries raising concerns about fiduciary standards for minors, crypto expansion plans, and Evolve Bank risk
Step is a teen-focused banking application serving users ages 13-17. The platform was acquired by Beast Industries in 2026 as part of the creator conglomerate's expansion into financial services.
## Regulatory Context
Step's acquisition by Beast Industries created a novel regulatory surface where creator trust (MrBeast's 39% minor audience) meets regulated financial services for the same demographic. Senator Warren's letter specifically cited Step's history of crypto-related content targeting minors combined with planned DeFi expansion under Beast Industries ownership.
## Sources
- Warren Senate letter (March 23, 2026)
- Banking Dive, The Block reporting (March 2026)
Step's banking partner, Evolve Bank & Trust, has three documented compliance issues:
- Entangled in 2024 Synapse bankruptcy ($96M in unlocated consumer deposits)
- Subject to Federal Reserve enforcement action for AML/compliance deficiencies
- Experienced dark web data breach of customer data
These issues triggered Senator Elizabeth Warren's scrutiny of the Beast Industries acquisition, particularly given MrBeast's audience composition (39% ages 13-17) and Beast Industries' crypto aspirations via 'MrBeast Financial' trademark filing.
## Timeline
- **2026** — Acquired by Beast Industries
- **2026-03-23** — Senator Warren sent 12-page letter to Beast Industries regarding acquisition, deadline April 3, 2026

View file

@ -1,25 +1,47 @@
# Project Sunrise
**Type:** Orbital data center constellation proposal
**Parent:** Blue Origin
**Status:** FCC filing stage (March 2026)
**Type:** Orbital data center constellation
**Developer:** Blue Origin
**Status:** FCC filing stage (as of March 2026)
**Scale:** Up to 51,600 satellites
## Overview
Project Sunrise is Blue Origin's proposed constellation for in-space computing services, filed with the FCC in March 2026. The constellation would operate in sun-synchronous orbits between 500-1,800 km altitude, with orbital planes spaced 5-10 km apart and 300-1,000 satellites per plane.
## Technical Architecture
- **Power:** Solar-powered ("always-on solar energy")
- **Communications:** Primarily optical inter-satellite links via TeraWave constellation; Ka-band for TT&C only
- **Compute hardware:** Not disclosed in FCC filing
- **Launch vehicle:** New Glenn 9×4 variant (planned)
Project Sunrise is Blue Origin's proposed orbital data center constellation filed with the FCC on March 19, 2026. The constellation would operate in sun-synchronous orbit (SSO) at 500-1,800 km altitude, using TeraWave optical inter-satellite links for high-throughput backbone communications.
## Economic Argument
Blue Origin claims space-based datacenters feature "built-in efficiencies" and "fundamentally lower the marginal cost of compute capacity compared to terrestrial alternatives," while eliminating land displacement costs and grid infrastructure disparities. No independent technical validation of these claims has been published.
## Technical Specifications
- **Orbit:** Sun-synchronous, 500-1,800 km altitude
- **Constellation size:** Up to 51,600 satellites
- **Orbital planes:** 5-10 km altitude separation
- **Satellites per plane:** 300-1,000
- **Communications:** TeraWave optical ISL mesh, Ka-band TT&C for ground links
- **Power:** Solar-powered
## Architecture
- TeraWave optical ISL mesh for high-throughput backbone
- Traffic routing through ground stations via TeraWave and other mesh networks
- Simultaneous filing for TeraWave as communications backbone infrastructure
## Stated Rationale
Blue Origin claims Project Sunrise will "ease mounting pressure on US communities and natural resources by shifting energy- and water-intensive compute away from terrestrial data centres, reducing demand on land, water supplies and electrical grids." The solar-powered architecture bypasses terrestrial power grid constraints.
## Timeline
- **2026-01** — TeraWave broadband constellation announced
- **2026-03-19** — Project Sunrise FCC filing submitted (51,600 satellites)
- **2026-03-19** — FCC filing submitted
- **2027** (projected) — First 5,000+ TeraWave satellites planned
- **2030s** (industry assessment) — Realistic deployment timeframe per SpaceNews analysis
## Context
Filed 60 days after SpaceX's 1M satellite filing that included orbital compute capabilities. Critics describe the technology as currently "doesn't exist" and likely to be "unreliable and impractical." The filing appears to be regulatory positioning rather than demonstration of technical readiness, as no compute hardware specifications were disclosed.
- Filed 7 weeks after SpaceX's 1M satellite filing (January 30, 2026)
- Represents ~22% of total LEO orbital capacity (~240,000 satellites per MIT TR)
- Unlike SpaceX's 1M filing, 51,600 is within physical LEO capacity limits
- No demonstrated thermal management or radiation hardening approach disclosed in filing
- SSO 500-1800km altitude represents harsher radiation environment than Starcloud-1's 325km validation orbit
## Sources
- SpaceNews, March 20, 2026: "Blue Origin joins the orbital data center race"

View file

@ -1,24 +1,33 @@
# TeraWave
**Type:** Broadband satellite constellation
**Parent:** Blue Origin
**Status:** Announced, deployment planned
**Scale:** 5,000+ satellites by end 2027
**Type:** Optical inter-satellite link communications network
**Developer:** Blue Origin
**Status:** FCC filing stage (as of March 2026)
**Primary application:** Project Sunrise orbital data center backbone
## Overview
TeraWave is Blue Origin's broadband satellite constellation, announced in January 2026. It serves dual purposes: commercial broadband service and communications backbone for Project Sunrise orbital data centers.
## Technical Architecture
- **Communications:** Optical inter-satellite links
- **Launch vehicle:** New Glenn 9×4 variant
- **Deployment schedule:** 5,000+ satellites by end 2027
TeraWave is Blue Origin's optical inter-satellite link (ISL) communications system, filed simultaneously with Project Sunrise on March 19, 2026. While designed as the communications backbone for Project Sunrise's orbital data center constellation, the architecture enables standalone operation as an independent high-bandwidth communications network.
## Strategic Role
TeraWave functions as an anchor tenant for New Glenn manufacturing ramp, providing commercial demand independent of government contracts. The constellation also provides the communications infrastructure for Project Sunrise orbital compute nodes.
## Technical Approach
- **Technology:** Optical (laser) inter-satellite links
- **Architecture:** Mesh network topology
- **Ground links:** Ka-band TT&C
- **Routing:** Traffic routing through ground stations via TeraWave and other mesh networks
- **Interoperability:** Designed to interface with external mesh networks
## Strategic Positioning
TeraWave represents a dual-use architecture where the communications layer has independent commercial value beyond the orbital data center payload. This creates optionality: if orbital data centers prove economically unviable, TeraWave could operate as a standalone high-bandwidth communications network competing with RF-based systems like Starlink.
The optical ISL approach offers potential advantages in bandwidth and security over RF links, though at higher complexity and pointing requirements.
## Timeline
- **2026-01** — TeraWave constellation announced
- **2026-03** — Project Sunrise filing references TeraWave as primary communications backbone
## Context
Announced one month before SpaceX's orbital compute FCC filing and two months before Blue Origin's Project Sunrise filing, suggesting rapid strategic response to competitive moves in the orbital infrastructure space.
- **2026-03-19** — FCC filing submitted alongside Project Sunrise
- **2027** (projected) — First 5,000+ TeraWave satellites planned
## Sources
- SpaceNews, March 20, 2026: "Blue Origin joins the orbital data center race"

View file

@ -5,7 +5,8 @@ author: "Sid Black, Asa Cooper Stickland, et al. (UK AISI)"
url: https://arxiv.org/abs/2504.18565
date: 2025-04-21
domain: ai-alignment
secondary_domains: []
secondary_domains: [grand-strategy]
flagged_for_leo: "Research-compliance translation gap angle: RepliBench predates EU AI Act Article 55 by 4 months, establishing that tools existed before mandate and still weren't adopted — core evidence for Layer 3a of the four-layer governance failure structure"
format: paper
status: processed
priority: high
@ -47,3 +48,10 @@ Key finding: Current models "do not currently pose a credible threat of self-rep
PRIMARY CONNECTION: [[voluntary safety pledges cannot survive competitive pressure]] + [[three conditions gate AI takeover risk]]
WHY ARCHIVED: Directly addresses the Bench-2-CoP zero-coverage finding; provides quantitative capability trajectory data for self-replication
EXTRACTION HINT: Focus on (1) the quantitative capability finding (>50% success on hardest variants), (2) the "could soon emerge" trajectory assessment, and (3) the gap between research evaluation existence and compliance integration
## Leo Notes (grand-strategy lens)
**Research-compliance translation gap evidence:** RepliBench published April 2025, EU AI Act Article 55 obligations took effect August 2025. Four-month gap. This is the most precise datapoint for the governance pipeline failure: the evaluation tool existed before the mandate and was not incorporated. Use as empirical anchor for the "no mechanism translates research findings into compliance requirements" claim.
**Confidence implication:** The ">50% success on hardest variants" finding should be extracted at `experimental` confidence — the capability is real but "current models do not pose a credible threat" is also in the paper. The grand-strategy synthesis claim (research-compliance translation gap) would be `likely` confidence since it relies on specific dates and documented compliance structure, not on capability trajectory predictions.
**Structural irony connection:** RepliBench requires voluntary lab participation to generate its data. Claude 3.7 Sonnet was tested because Anthropic cooperated. The evaluation infrastructure is structurally dependent on the same consent mechanism it's trying to verify. Even the best capability evaluation tool operates inside the voluntary-collaborative layer.

View file

@ -7,9 +7,12 @@ date: 2026-01-12
domain: entertainment
secondary_domains: [internet-finance]
format: article
status: unprocessed
status: processed
processed_by: clay
processed_date: 2026-04-14
priority: high
tags: [creator-economy, M&A, brand-equity, consolidation, institutional-capture, community-trust]
extraction_model: "anthropic/claude-sonnet-4.5"
---
## Content

View file

@ -7,9 +7,12 @@ date: 2026-03-05
domain: entertainment
secondary_domains: []
format: article
status: unprocessed
status: processed
processed_by: clay
processed_date: 2026-04-14
priority: high
tags: [microdramas, short-form-narrative, engagement-mechanics, attention-economy, narrative-format, reelshort]
extraction_model: "anthropic/claude-sonnet-4.5"
---
## Content

View file

@ -7,9 +7,12 @@ date: 2026-03-10
domain: entertainment
secondary_domains: [internet-finance]
format: article
status: unprocessed
status: processed
processed_by: clay
processed_date: 2026-04-14
priority: high
tags: [pudgy-penguins, web3-ip, community-owned-ip, blockchain-hidden, gaming, narrative-architecture]
extraction_model: "anthropic/claude-sonnet-4.5"
---
## Content

View file

@ -0,0 +1,52 @@
---
type: source
title: "Hollywood Bets on AI to Cut Production Costs and Make More Content"
author: "Axios (staff)"
url: https://www.axios.com/2026/03/18/hollywood-ai-amazon-netflix
date: 2026-03-18
domain: entertainment
secondary_domains: []
format: article
status: processed
processed_by: clay
processed_date: 2026-04-14
priority: high
tags: [hollywood, AI-adoption, production-costs, Netflix, Amazon, progressive-syntheticization, disruption]
extraction_model: "anthropic/claude-sonnet-4.5"
---
## Content
Netflix acquiring Ben Affleck's startup that uses AI to support post-production processes — a signal of major streamer commitment to AI integration.
Amazon MGM Studios head of AI Studios: "We can actually fit five movies into what we would typically spend on one" — 5x content volume at same cost using AI.
The article frames this as studios betting on AI for cost reduction and content volume, not for quality differentiation.
Context from Fast Company (April 2026): Two major studios and one high-profile production company announced 1,000+ combined layoffs in early April 2026 alone. Third of industry surveyed: 20%+ of entertainment jobs (118,500+) will be eliminated by 2026.
Katzenberg prediction: AI will drop animation costs by 90% — "I don't think it will take 10 percent of that three years out." The 9-person team producing a feature-length animated film in 3 months for ~$700K is the empirical anchor (vs. typical $70M-200M DreamWorks budgets).
GenAI rendering costs declining ~60% annually. A 3-minute AI narrative short now costs $75-175 (vs. $5K-30K traditional).
## Agent Notes
**Why this matters:** This is the clearest market evidence for the progressive syntheticization vs. progressive control distinction. Amazon's "5 movies for the price of 1" is textbook progressive syntheticization — same workflow, AI-assisted cost reduction. The 9-person feature film team is progressive control — starting from AI-native, adding human direction. The two approaches are producing different strategic outcomes.
**What surprised me:** Netflix acquiring Affleck's startup for post-production (not pre-production or creative) — this is specifically targeting the back-end cost reduction, not the creative process. Studios are protecting creative control while using AI to reduce post-production costs.
**What I expected but didn't find:** Evidence of studios using AI for creative development (story generation, character creation). The current adoption pattern is almost exclusively post-production and VFX — the "safe" applications that don't touch writer/director territory.
**KB connections:** [[GenAI is simultaneously sustaining and disruptive depending on whether users pursue progressive syntheticization or progressive control]] — the Amazon example is the clearest market confirmation of this claim; [[five factors determine the speed and extent of disruption including quality definition change and ease of incumbent replication]] — studios cannot replicate the 9-person feature film model because their cost structure assumes union labor and legacy workflows; [[non-ATL production costs will converge with the cost of compute as AI replaces labor across the production chain]] — the 60%/year cost decline confirms the convergence direction.
**Extraction hints:** The Amazon "5 movies for 1 budget" quote is extractable as evidence for progressive syntheticization — it's a named executive making a specific efficiency claim. The 9-person $700K feature film is extractable as evidence for progressive control reaching feature-film quality threshold. These are the two poles of the disruption spectrum, now confirmed with real data.
**Context:** Axios covers enterprise tech and media economics. The Amazon MGM AI Studios head is a named executive making an on-record claim about cost reduction. This is reportable market evidence, not speculation.
## Curator Notes (structured handoff for extractor)
PRIMARY CONNECTION: [[GenAI is simultaneously sustaining and disruptive depending on whether users pursue progressive syntheticization or progressive control]]
WHY ARCHIVED: The Amazon MGM "5 movies for 1 budget" claim and the 9-person $700K feature film are the strongest market-validated data points for the progressive syntheticization vs. progressive control distinction. Studios are confirming one path while independents prove the other.
EXTRACTION HINT: Extract as confirmation of the sustaining/disruptive distinction — studios (Amazon) pursuing syntheticization, independents pursuing control, both happening simultaneously, producing opposite strategic outcomes. The specific cost numbers ($700K vs $70M-200M) are load-bearing — they demonstrate that the paths have diverged to the point of incommensurability.

View file

@ -7,9 +7,12 @@ date: 2026-03-25
domain: entertainment
secondary_domains: [internet-finance]
format: article
status: unprocessed
status: processed
processed_by: clay
processed_date: 2026-04-14
priority: medium
tags: [beast-industries, mrbeast, fintech, creator-conglomerate, regulatory, evolve-bank, crypto, M&A]
extraction_model: "anthropic/claude-sonnet-4.5"
---
## Content

View file

@ -0,0 +1,61 @@
---
type: source
title: "Pudgy Penguins: A New Blueprint for Tokenized Culture"
author: "CoinDesk Research (staff)"
url: https://www.coindesk.com/research/pudgy-penguins-a-new-blueprint-for-tokenized-culture
date: 2026-02-01
domain: entertainment
secondary_domains: [internet-finance]
format: article
status: processed
processed_by: clay
processed_date: 2026-04-14
priority: high
tags: [pudgy-penguins, community-owned-ip, tokenized-culture, web3-ip, commercial-scale, minimum-viable-narrative]
extraction_model: "anthropic/claude-sonnet-4.5"
---
## Content
CoinDesk Research deep-dive on Pudgy Penguins' commercial model as of early 2026.
Key metrics confirmed:
- 2025 actual revenue: ~$50M (CEO Luca Netz confirmed)
- 2026 target: $120M
- Retail distribution: 2M+ Schleich figurines, 10,000+ retail locations, 3,100 Walmart stores
- GIPHY views: 79.5B (reportedly outperforms Disney and Pokémon per upload — context: reaction gif category)
- Vibes TCG: 4M cards sold
- Pengu Card: 170+ countries
Inversion of standard Web3 strategy:
"Unlike competitors like Bored Ape Yacht Club and Azuki who build an exclusive NFT community first and then aim for mainstream adoption, Pudgy Penguins has inverted the strategy: prioritizing physical retail and viral content to acquire users through traditional consumer channels first."
The thesis: "Build a global IP that has an NFT, rather than being an NFT collection trying to become a brand."
Narrative investment: Characters exist (Atlas, Eureka, Snofia, Springer) but minimal world-building. Lil Pudgys series via TheSoul Publishing (5-Minute Crafts parent company) — volume-production model, not quality-first.
IPO target: 2027, contingent on revenue growth. Luca Netz: "I'd be disappointed in myself if we don't IPO in the next two years."
The "minimum viable narrative" test: Pudgy Penguins is demonstrating that ~$50M+ commercial scale can be achieved with cute characters + financial alignment + retail penetration without meaningful story investment.
## Agent Notes
**Why this matters:** This is the primary source for the "minimum viable narrative at commercial scale" finding. Pudgy Penguins' commercial success ($50M+ revenue) with minimal narrative investment is the strongest current challenge to any claim that narrative quality is required for IP commercial success.
**What surprised me:** The GIPHY views claim (79.5B, outperforming Disney/Pokémon per upload) — if accurate, this is significant. But the "per upload" qualifier is doing heavy lifting — it's a rate statistic, not an absolute. The total volume still likely favors Disney/Pokémon. The claim needs scrutiny.
**What I expected but didn't find:** Evidence of Pudgy Penguins building narrative depth ahead of IPO. The TheSoul Publishing deal is a volume-first approach (5-Minute Crafts model), not a quality investment. If they're heading to IPO with this production philosophy, that's a specific bet about what licensing buyers want.
**KB connections:** [[progressive validation through community building reduces development risk by proving audience demand before production investment]] — Pudgy Penguins inverts this: they're proving audience demand through retail penetration and GIPHY virality, not community-first sequencing; [[the media attractor state is community-filtered IP with AI-collapsed production costs where content becomes a loss leader for the scarce complements of fandom community and ownership]] — Pudgy Penguins' physical goods ARE the content-as-loss-leader model, but for retail rather than fandom.
**Extraction hints:** The "inversion of standard Web3 strategy" paragraph is directly extractable — it's a specific, falsifiable claim about Pudgy Penguins' strategic positioning. Also: the "$50M actual vs $120M target" revenue milestone is extractable as the commercial scale data point for minimum viable narrative.
**Context:** CoinDesk Research is the institutional research arm of CoinDesk — more rigorous than general crypto media. The revenue figures were confirmed by CEO Luca Netz directly.
## Curator Notes (structured handoff for extractor)
PRIMARY CONNECTION: [[the media attractor state is community-filtered IP with AI-collapsed production costs where content becomes a loss leader for the scarce complements of fandom community and ownership]]
WHY ARCHIVED: This is the definitive source on Pudgy Penguins' commercial model — the primary evidence for "minimum viable narrative at commercial scale." The explicit inversion of Web3 strategy ("build a global IP that has an NFT") is the clearest statement of the mainstream-first philosophy that is now the dominant Web3 IP strategy.
EXTRACTION HINT: The "minimum viable narrative at commercial scale" claim is the key extraction — but it needs to be scoped as a commercial IP claim, not a civilizational narrative claim. The $50M revenue is evidence that cute characters + financial alignment = commercial success; it's not evidence that this produces civilizational coordination.

View file

@ -0,0 +1,67 @@
---
type: source
title: "AI Filmmaking Cost Breakdown: What It Actually Costs to Make a Short Film with AI in 2026"
author: "MindStudio (staff)"
url: https://www.mindstudio.ai/blog/ai-filmmaking-cost-breakdown-2026
date: 2026-03-01
domain: entertainment
secondary_domains: []
format: article
status: processed
processed_by: clay
processed_date: 2026-04-14
priority: high
tags: [AI-production, cost-collapse, independent-film, GenAI, progressive-control, production-economics]
extraction_model: "anthropic/claude-sonnet-4.5"
---
## Content
Specific cost data for AI film production in 2026:
**AI short film (3 minutes):**
- Full AI production: $75-175
- Traditional DIY: $500-2,000
- Traditional professional: $5,000-30,000
- AI advantage: 97-99% cost reduction
**GenAI rendering cost trajectory:**
- Declining approximately 60% annually
- Scene generation costs 90% lower than prior baseline by 2025
**Feature-length animated film (empirical case):**
- Team: 9 people
- Timeline: 3 months
- Budget: ~$700,000
- Comparison: Typical DreamWorks budget $70M-200M
- Cost reduction: 99%+ (99-100x cheaper)
**Rights management becoming primary cost:**
- As technical production costs collapse, scene complexity is decoupled from cost
- Primary cost consideration shifting to rights management (IP licensing, music, voice)
- Implication: the "cost" of production is becoming a legal/rights problem, not a technical problem
**The democratization framing:**
"An independent filmmaker in their garage will have the power to create visuals that rival a $200 million blockbuster, with the barrier to entry becoming imagination rather than capital."
## Agent Notes
**Why this matters:** This is the quantitative anchor for the production cost collapse claim. The $75-175 vs $5,000-30,000 comparison for a 3-minute film is the most concrete cost data available. The 60%/year declining cost trajectory is the exponential rate that makes this a structural, not cyclical, change.
**What surprised me:** The rights management observation — that as technical production costs approach zero, the dominant cost becomes legal/rights rather than technical/labor. This is a specific prediction about where cost concentration will move in the AI era. If true, IP ownership (not production capability) becomes the dominant cost item, which inverts the current model entirely.
**What I expected but didn't find:** Comparison data on AI production quality at these price points — the claim that $75-175 AI film "rivals" a $5K-30K professional production deserves scrutiny. The quality comparison is missing.
**KB connections:** [[non-ATL production costs will converge with the cost of compute as AI replaces labor across the production chain]] — this source provides specific numbers that confirm the convergence direction; [[GenAI is simultaneously sustaining and disruptive depending on whether users pursue progressive syntheticization or progressive control]] — the $700K 9-person feature film is progressive control; the studios using AI for post-production cost reduction is progressive syntheticization; value flows to whichever resources are scarce and disruption shifts which resources are scarce making resource-scarcity analysis the core strategic framework — if production costs approach zero, rights/IP becomes the scarce resource, which shifts where value concentrates.
**Extraction hints:** The rights management insight is underexplored in the KB — extract as a forward-looking claim about where cost concentration will move in the AI era. Also extract the 60%/year cost decline as a rate with strong predictive power (at 60%/year, costs halve every ~18 months, meaning feature-film-quality AI production will be sub-$10K within 3-4 years).
**Context:** MindStudio is an AI workflow platform — they have direct market knowledge of AI production costs. The data is current (2026) and specific (dollar figures, not qualitative descriptions).
## Curator Notes (structured handoff for extractor)
PRIMARY CONNECTION: [[non-ATL production costs will converge with the cost of compute as AI replaces labor across the production chain]]
WHY ARCHIVED: This is the most specific quantitative source for the AI production cost collapse. The 60%/year trajectory and the $700K/9-person feature film are the key data points. The rights management insight is novel — it identifies where cost concentration will move next as technical production approaches zero.
EXTRACTION HINT: The rights management observation may warrant its own claim — "as AI collapses technical production costs toward zero, IP rights management becomes the dominant cost in content creation." This is a second-order effect of the cost collapse that isn't currently in the KB.

View file

@ -0,0 +1,47 @@
---
type: source
title: "First Orbital Data Center Nodes Reach Low Earth Orbit — Axiom/Kepler January 2026"
author: "Axiom Space / Introl Blog (@axiomspace)"
url: https://introl.com/blog/orbital-data-center-nodes-launch-space-computing-infrastructure-january-2026
date: 2026-01-11
domain: space-development
secondary_domains: []
format: article
status: processed
processed_by: astra
processed_date: 2026-04-14
priority: high
tags: [orbital-data-centers, axiom-space, kepler-communications, SDA, defense-demand, edge-compute]
flagged_for_theseus: ["SDA interoperability standards connecting commercial ODC to national security architecture — the defense-commercial convergence Theseus tracks in AI governance context"]
extraction_model: "anthropic/claude-sonnet-4.5"
---
## Content
The first two orbital data center nodes launched to low-Earth orbit on January 11, 2026. Deployed as part of Kepler Communications' optical relay network, the nodes enable 2.5 Gbps optical intersatellite links between spacecraft without routing through ground stations.
Key technical specs:
- Optical intersatellite links (OISLs) meeting Space Development Agency (SDA) Tranche 1 interoperability standards
- Enables integration with government and commercial space systems
- Compute hardware runs processing/inferencing: filtering images, detecting features, compressing files, running AI/ML models on data from other satellites
- By 2027: at least three interconnected, interoperable ODC nodes planned
The nodes are built to national security standards (SDA Tranche 1) — making them interoperable with government and commercial satellite networks from day one. This is not a purely commercial product.
## Agent Notes
**Why this matters:** These are the FIRST actual orbital data center nodes in operation — not a demo, not an announcement. They validate that orbital edge compute for space-to-space data relay is a real, deployed capability. The SDA interoperability is the critical detail: this sector is maturing through defense demand, not commercial demand first.
**What surprised me:** The SDA Tranche 1 standards compliance is built in from day one. This is deliberate architectural convergence between commercial ODC and national security space — consistent with the defense demand floor pattern tracked in previous sessions.
**What I expected but didn't find:** No indication of compute scale (FLOPS, watts) for these nodes. They're described as inference-class (filtering, compression, AI/ML on imagery) — not training class. This is edge compute, not data-center-class AI training.
**KB connections:** Directly connects to space governance gaps are widening not narrowing — the SDA is filling the governance gap for orbital compute through standards rather than regulation. Also connects to Pattern 12 (national security demand floor) from the research journal.
**Extraction hints:**
- Claim candidate: Orbital edge compute for space-to-space relay has reached operational deployment (TRL 9) as of January 2026, validated by Axiom/Kepler SDA-compatible nodes — distinct from the data-center-class AI training use case which remains pre-commercial.
- Divergence candidate with SpaceX/Blue Origin big-constellation claims: are the deployed use cases (edge inference) fundamentally different from the announced use cases (AI training at scale)?
## Curator Notes
PRIMARY CONNECTION: the space manufacturing killer app sequence analog — ODC's actual near-term use case (edge compute for space assets) may be structurally different from the announced use case (replacing terrestrial AI data centers).
WHY ARCHIVED: First real operational proof point for ODC sector — sets the baseline for what "ODC in practice" looks like vs. announced visions.
EXTRACTION HINT: Focus on the edge-vs-training distinction and the defense-standards-first development pattern.

View file

@ -7,9 +7,12 @@ date: 2026-02-05
domain: space-development
secondary_domains: []
format: article
status: unprocessed
status: processed
processed_by: astra
processed_date: 2026-04-14
priority: high
tags: [orbital-data-centers, SpaceX, FCC, regulatory, Amazon, feasibility, launch-cadence, 1-million-satellites]
extraction_model: "anthropic/claude-sonnet-4.5"
---
## Content

View file

@ -7,9 +7,12 @@ date: 2026-02-27
domain: space-development
secondary_domains: [energy]
format: article
status: unprocessed
status: processed
processed_by: astra
processed_date: 2026-04-14
priority: high
tags: [orbital-data-centers, power, AI, economics, cost-analysis, IEEE, technical-assessment]
extraction_model: "anthropic/claude-sonnet-4.5"
---
## Content

View file

@ -7,9 +7,12 @@ date: 2026-02-27
domain: space-development
secondary_domains: [manufacturing]
format: article
status: unprocessed
status: processed
processed_by: astra
processed_date: 2026-04-14
priority: high
tags: [orbital-data-centers, thermal-management, cooling, radiators, heat-dissipation, physics-constraint]
extraction_model: "anthropic/claude-sonnet-4.5"
---
## Content

View file

@ -7,9 +7,12 @@ date: 2026-02-15
domain: space-development
secondary_domains: [energy]
format: article
status: unprocessed
status: processed
processed_by: astra
processed_date: 2026-04-14
priority: medium
tags: [orbital-data-centers, skepticism, radiation, cost, policy, energy-transition]
extraction_model: "anthropic/claude-sonnet-4.5"
---
## Content

View file

@ -7,9 +7,12 @@ date: 2026-03-16
domain: space-development
secondary_domains: []
format: article
status: unprocessed
status: processed
processed_by: astra
processed_date: 2026-04-14
priority: medium
tags: [orbital-data-centers, nvidia, Vera-Rubin, space-grade-compute, GTC-2026, radiation-hardening]
extraction_model: "anthropic/claude-sonnet-4.5"
---
## Content

View file

@ -7,9 +7,12 @@ date: 2026-03-20
domain: space-development
secondary_domains: [energy]
format: article
status: unprocessed
status: processed
processed_by: astra
processed_date: 2026-04-14
priority: high
tags: [orbital-data-centers, Blue-Origin, Project-Sunrise, FCC, TeraWave, SSO, feasibility]
extraction_model: "anthropic/claude-sonnet-4.5"
---
## Content

View file

@ -7,9 +7,12 @@ date: 2026-03-30
domain: space-development
secondary_domains: []
format: article
status: unprocessed
status: processed
processed_by: astra
processed_date: 2026-04-14
priority: high
tags: [orbital-data-centers, starcloud, investment, nvidia, AWS, cost-parity, Starship, roadmap]
extraction_model: "anthropic/claude-sonnet-4.5"
---
## Content

View file

@ -7,9 +7,12 @@ date: 2026-04-03
domain: space-development
secondary_domains: []
format: article
status: unprocessed
status: processed
processed_by: astra
processed_date: 2026-04-14
priority: high
tags: [orbital-data-centers, feasibility, debris, orbital-capacity, launch-cost, thermal-management, MIT]
extraction_model: "anthropic/claude-sonnet-4.5"
---
## Content

View file

@ -0,0 +1,53 @@
---
type: source
title: "43% of Gen Z Prefer YouTube and TikTok to Traditional TV; Microdramas Reach 28 Million US Viewers"
author: "Variety (staff)"
url: https://variety.com/2025/tv/news/gen-z-youtube-tiktok-microdramas-1236569763/
date: 2025-10-01
domain: entertainment
secondary_domains: []
format: article
status: null-result
priority: high
tags: [gen-z, attention-migration, youtube, tiktok, streaming-decline, microdramas, social-video]
extraction_model: "anthropic/claude-sonnet-4.5"
---
## Content
Key data points from Variety study:
- 43% of Gen Z prefer YouTube and TikTok to traditional TV and streaming for media and news consumption
- Microdramas have reached 28 million US viewers — described as a new genre trend
- YouTube: 63% of Gen Z use daily (leading platform)
- Traditional TV daily viewing projected to collapse to 1 hour 17 minutes
- Streaming daily viewing: 4 hours 8 minutes, but facing growth pressure from subscription fatigue
Additional data from multiple sources:
- TikTok engagement rate: 3.70%, up 49% YoY — highest on record
- Short-form video generates 2.5x more engagement than long-form
- 91% of businesses now use video as marketing tool (up from 61% a decade ago)
- Streaming platform subscription price increases driving back toward free ad-supported video
Context: YouTube's dominance as TV replacement is now confirmed. YouTube does more TV viewing than the next five streamers combined (per industry data). The streaming "fatigue" narrative is becoming mainstream: subscription price increases ($15-18/month) driving churn toward free platforms.
## Agent Notes
**Why this matters:** This is the attention migration data that anchors the social video trend in quantitative terms. The "28 million US viewers" for microdramas is the number that makes microdramas a meaningful attention pool, not a niche curiosity. Combined with YouTube's 63% Gen Z daily usage, the picture is clear: attention has migrated and is not returning to traditional TV/streaming at previous rates.
**What surprised me:** The simultaneity of two trends that might seem contradictory: streaming growing in time-per-day (4h08m) while Gen Z abandons traditional TV (1h17m daily). The answer is that streaming is capturing former TV time while losing ground to YouTube/TikTok — streaming is winning against linear but losing against social.
**What I expected but didn't find:** Specifics on what types of content drive Gen Z's YouTube preference — is it short-form, long-form, live, or some mix? The data says "YouTube and TikTok" without differentiating what within those platforms is capturing the attention.
**KB connections:** [[social video is already 25 percent of all video consumption and growing because dopamine-optimized formats match generational attention patterns]] — this data updates and strengthens this claim (the "25 percent" figure may now be understated); [[creator and corporate media economies are zero-sum because total media time is stagnant and every marginal hour shifts between them]] — the Gen Z shift to YouTube/TikTok is a direct transfer from corporate to creator media.
**Extraction hints:** The 28 million US microdrama viewers is extractable as a standalone market-size claim for the microdrama category. The 43% Gen Z YouTube/TikTok preference is extractable as an attention migration claim with a generational qualifier. Both update existing KB claims with 2025 data.
**Context:** Variety is the authoritative trade publication for entertainment industry data. The study appears to be from Variety Intelligence Platform or a commissioned survey. The Gen Z data is consistent with multiple independent sources (eMarketer, Attest, DemandSage).
## Curator Notes (structured handoff for extractor)
PRIMARY CONNECTION: [[social video is already 25 percent of all video consumption and growing because dopamine-optimized formats match generational attention patterns]]
WHY ARCHIVED: This is the most current quantitative anchor for attention migration from traditional TV/streaming toward social video platforms. The 28M microdrama viewers data is new and not in the KB — it extends the social video trend into the micro-narrative format.
EXTRACTION HINT: Consider whether this source supports updating the "25 percent" figure in the social video claim — if 43% of Gen Z prefers YouTube/TikTok and microdramas have 28M US viewers, the aggregate social video share may now be higher than 25%. Flag for confidence upgrade on the claim.

View file

@ -7,10 +7,11 @@ date: 2026-01-11
domain: space-development
secondary_domains: []
format: article
status: unprocessed
status: null-result
priority: high
tags: [orbital-data-centers, axiom-space, kepler-communications, SDA, defense-demand, edge-compute]
flagged_for_theseus: ["SDA interoperability standards connecting commercial ODC to national security architecture — the defense-commercial convergence Theseus tracks in AI governance context"]
extraction_model: "anthropic/claude-sonnet-4.5"
---
## Content

View file

@ -7,9 +7,10 @@ date: 2026-03-18
domain: entertainment
secondary_domains: []
format: article
status: unprocessed
status: null-result
priority: high
tags: [hollywood, AI-adoption, production-costs, Netflix, Amazon, progressive-syntheticization, disruption]
extraction_model: "anthropic/claude-sonnet-4.5"
---
## Content

View file

@ -7,9 +7,10 @@ date: 2026-04-14
domain: space-development
secondary_domains: []
format: article
status: unprocessed
status: null-result
priority: high
tags: [Blue-Origin, New-Glenn, NG-3, booster-reuse, AST-SpaceMobile, BlueBird, execution-gap, Pattern-2]
extraction_model: "anthropic/claude-sonnet-4.5"
---
## Content

View file

@ -7,9 +7,10 @@ date: 2026-04-01
domain: space-development
secondary_domains: [energy]
format: article
status: unprocessed
status: null-result
priority: medium
tags: [orbital-data-centers, SpaceX, feasibility, physics-critique, thermal-management, power-density, refrigeration]
extraction_model: "anthropic/claude-sonnet-4.5"
---
## Content

View file

@ -7,9 +7,10 @@ date: 2026-02-01
domain: entertainment
secondary_domains: [internet-finance]
format: article
status: unprocessed
status: null-result
priority: high
tags: [pudgy-penguins, community-owned-ip, tokenized-culture, web3-ip, commercial-scale, minimum-viable-narrative]
extraction_model: "anthropic/claude-sonnet-4.5"
---
## Content

View file

@ -7,9 +7,10 @@ date: 2026-03-15
domain: entertainment
secondary_domains: []
format: article
status: unprocessed
status: null-result
priority: medium
tags: [entertainment-industry, business-reset, smaller-budgets, quality-over-volume, AI-efficiency, slope-reading]
extraction_model: "anthropic/claude-sonnet-4.5"
---
## Content

View file

@ -0,0 +1,54 @@
---
type: source
title: "How Tariffs and Economic Uncertainty Could Impact the Creator Economy"
author: "eMarketer (staff)"
url: https://www.emarketer.com/content/how-tariffs-economic-uncertainty-could-impact-creator-economy
date: 2026-04-01
domain: entertainment
secondary_domains: []
format: article
status: null-result
priority: low
tags: [tariffs, creator-economy, production-costs, equipment, AI-substitution, macroeconomics]
extraction_model: "anthropic/claude-sonnet-4.5"
---
## Content
Tariff impact on creator economy (2026):
- Primary mechanism: increased cost of imported hardware (cameras, mics, computing devices)
- Equipment-heavy segments most affected: video, streaming
- Most impacted regions: North America, Europe, Asia-Pacific
BUT: Indirect effect may be net positive for AI adoption:
- Tariffs raising traditional production equipment costs → creator substitution toward AI tools
- Domestic equipment manufacturing being incentivized
- Creators who would have upgraded traditional gear are substituting to AI tools instead
- Long-term: may reduce dependency on imported equipment
Creator economy overall: still growing despite tariff headwinds
- US creator economy projected to surpass $40B in 2026 (up from $20.64B in 2025)
- Creator economy ad spend: $43.9B in 2026
- The structural growth trend is not interrupted by tariff friction
## Agent Notes
**Why this matters:** The tariff → AI substitution effect is an indirect mechanism worth noting. External macroeconomic pressure (tariffs) may be inadvertently accelerating the AI adoption curve among creator-economy participants who face higher equipment costs. This is a tail-wind for the AI cost collapse thesis.
**What surprised me:** The magnitude of creator economy growth ($20.64B to $40B+ in one year) seems very high — this may be measurement methodology change (what counts as "creator economy") rather than genuine doubling. Flag for scrutiny.
**What I expected but didn't find:** Specific creator segments most impacted by tariff-driven equipment cost increases. The analysis is directional without being precise about which creator types face the highest friction.
**KB connections:** [[GenAI is simultaneously sustaining and disruptive depending on whether users pursue progressive syntheticization or progressive control]] — tariff pressure on traditional equipment costs may push independent creators further toward progressive control (AI-first production).
**Extraction hints:** The tariff → AI substitution mechanism is a secondary claim at best — speculative, with limited direct evidence. The creator economy growth figures ($40B) are extractable as market size data but need scrutiny on methodology. Low priority extraction.
**Context:** eMarketer is a market research firm with consistent measurement methodology. The creator economy sizing figures should be checked against their methodology — they may define "creator economy" differently from other sources.
## Curator Notes (structured handoff for extractor)
PRIMARY CONNECTION: [[GenAI is simultaneously sustaining and disruptive depending on whether users pursue progressive syntheticization or progressive control]]
WHY ARCHIVED: The tariff → AI substitution mechanism is interesting as a secondary claim — external economic pressure inadvertently accelerating the disruption trend. Low priority for extraction but worth noting as a follow-up if more direct evidence emerges.
EXTRACTION HINT: Don't extract as standalone claim — file as supporting context for the AI adoption acceleration thesis. The $43.9B creator ad spend figure is more valuable as a market size data point.

View file

@ -0,0 +1,48 @@
---
type: source
title: "Hollywood Layoffs 2026: Disney, Sony, Bad Robot and the AI Jobs Collapse"
author: "Fast Company (staff)"
url: https://www.fastcompany.com/91524432/hollywood-layoffs-2026-disney-sony-bad-robot-list-entertainment-job-cuts
date: 2026-04-01
domain: entertainment
secondary_domains: []
format: article
status: null-result
priority: medium
tags: [hollywood, layoffs, AI-displacement, jobs, disruption, slope-reading]
extraction_model: "anthropic/claude-sonnet-4.5"
---
## Content
April 2026 opened with major entertainment layoffs:
- Two major studios + Bad Robot (J.J. Abrams' production company) announced combined 1,000+ job cuts in the first weeks of April
- Industry survey data: a third of respondents predict over 20% of entertainment industry jobs (roughly 118,500 positions) will be cut by 2026
- Most vulnerable roles: sound editors, 3D modelers, rerecording mixers, audio/video technicians
- Hollywood Reporter: assistants are using AI "despite their better judgment" including in script development
The layoffs represent Phase 2 of the disruption pattern: distribution fell first (streaming, 2013-2023), creation is falling now (GenAI, 2024-present). Prior layoff cycle (2023-2024): 17,000+ entertainment jobs eliminated. The 2026 cycle is continuing.
The Ankler analysis: "Fade to Black — Hollywood's AI-Era Jobs Collapse Is Starting" — framing this as structural, not cyclical.
## Agent Notes
**Why this matters:** The job elimination data is the most direct evidence for the "creation is falling now" thesis — the second phase of media disruption. When you can fit 5 movies into 1 budget (Amazon MGM) and a 9-person team can produce a feature for $700K, the labor displacement is the lagging indicator confirming what the cost curves already predicted.
**What surprised me:** Bad Robot (J.J. Abrams) cutting staff — this is a prestige production company associated with high-budget creative work, not commodity production. The cuts reaching prestige production suggests AI displacement is not just hitting low-value-added roles.
**What I expected but didn't find:** No evidence of AI-augmented roles being created at comparable scale to offset the job cuts. The narrative of "AI creates new jobs while eliminating old ones" is not appearing in the entertainment data.
**KB connections:** [[media disruption follows two sequential phases as distribution moats fall first and creation moats fall second]] — the 2026 layoff wave is the empirical confirmation of Phase 2; [[Hollywood talent will embrace AI because narrowing creative paths within the studio system leave few alternatives]] — the "despite their better judgment" framing for assistant AI use confirms the coercive adoption dynamic.
**Extraction hints:** The specific claim "a third of respondents predict 118,500+ jobs eliminated by 2026" is a verifiable projection that can be tracked. Also extractable: the job categories most at risk (technical post-production) vs. creative roles — this maps to the progressive syntheticization pattern (studios protecting creative direction while automating technical execution).
**Context:** Fast Company aggregates multiple studio announcements. The data is current (April 2026). Supports slope-reading analysis: incumbent rents are compressing (margins down), and the structural response (labor cost reduction via AI) is accelerating.
## Curator Notes (structured handoff for extractor)
PRIMARY CONNECTION: [[media disruption follows two sequential phases as distribution moats fall first and creation moats fall second]]
WHY ARCHIVED: The April 2026 layoff wave is real-time confirmation of Phase 2 disruption reaching critical mass. The 1,000+ April jobs cuts + 118,500 projection + prestige production company (Bad Robot) inclusion are the clearest signal that the creation moat is actively falling.
EXTRACTION HINT: Extract as slope-reading evidence — the layoff wave is the lagging indicator of the cost curve changes documented elsewhere. The specific projection (20% of industry = 118,500 jobs) is extractable with appropriate confidence calibration.

80
ops/AGENT-SOP.md Normal file
View file

@ -0,0 +1,80 @@
# Agent SOP: Ship, Review, Deploy
Load at session start. No exceptions.
## Code Changes
1. Branch from main: `git checkout -b {agent-name}/{description}`
2. Make changes. One branch per task. One concern per PR.
3. Commit with agent-name prefix, what changed and why.
4. Push to Forgejo. Open PR with deploy manifest (see deploy-manifest.md).
5. Ganymede reviews. Address feedback on same branch.
6. Merge after approval. Delete branch immediately.
7. Auto-deploy handles the rest. Do not manually deploy.
## Do Not
- SCP files directly to VPS
- Deploy before committing to the repo
- Edit files on VPS directly
- Send the same review request twice for unchanged code
- Claim code exists or was approved without reading git/files to verify
- Go from memory when you can verify from files
- Reuse branch names (Forgejo returns 409 Conflict on closed PR branches)
## Canonical File Locations
| Code | Location |
|---|---|
| Pipeline lib | `ops/pipeline-v2/lib/` |
| Pipeline scripts | `ops/pipeline-v2/` |
| Diagnostics | `ops/diagnostics/` |
| Agent state | `ops/agent-state/` |
| Deploy/ops scripts | `ops/` |
| Claims | `core/`, `domains/`, `foundations/` |
| Agent identity | `agents/{name}/` |
One location per file. If your path doesn't match this table, stop.
## Verification Before Acting
- Before editing: read the file. Never describe code from memory.
- Before reviewing: check git log for prior approvals on the same files.
- Before deploying: `git status` must show clean tree.
- Before messaging another agent: check if the same message was already sent.
## Branch Hygiene
- Delete branch immediately after merge.
- Nightly research branches: deleted after 7 days if unmerged.
- Never leave a branch open with no active work.
## Deploy
After merge to main, auto-deploy runs within 2 minutes on VPS:
1. Pulls latest main into deploy checkout
2. Syntax-checks all Python files
3. Syncs to working directories (pipeline, diagnostics, agent-state)
4. Restarts services only if Python files changed
5. Runs smoke tests (systemd status + health endpoints)
Manual deploy (only if auto-deploy is broken):
```
cd ops && ./deploy.sh --dry-run && ./deploy.sh --restart
```
Check auto-deploy status: `journalctl -u teleo-auto-deploy -n 20`
## Shell and Python Safety
- Run `bash -n script.sh` after modifying any shell script.
- Never suppress stderr on critical git commands (`2>/dev/null || true`). Log errors, fail hard.
- Never interpolate shell variables into Python strings via `'$var'`.
Pass values via `os.environ` or `sys.argv`.
- Never write credentials to `.git/config`. Use per-command `git -c http.extraHeader`.
- Tunable constants live in `ops/pipeline-v2/lib/config.py`. Don't hardcode numbers in module files.
## Schema Changes
Any PR that changes a file format, DB table, or API response shape must follow
`ops/schema-change-protocol.md`. Tag all consumers. Include migration.

84
ops/auto-deploy-setup.md Normal file
View file

@ -0,0 +1,84 @@
# Auto-Deploy Setup
One-time setup on VPS. After this, merges to main deploy automatically within 2 minutes.
## Prerequisites
- SSH access as `teleo` user: `ssh teleo@77.42.65.182`
- Forgejo running at localhost:3000
- `teleo` user has sudo access for `teleo-*` services
## Steps
### 1. Create the deploy checkout
```bash
git clone http://localhost:3000/teleo/teleo-codex.git /opt/teleo-eval/workspaces/deploy
cd /opt/teleo-eval/workspaces/deploy
git checkout main
```
This checkout is ONLY for auto-deploy. The pipeline's main worktree at
`/opt/teleo-eval/workspaces/main` is separate and untouched.
### 2. Install systemd units
```bash
sudo cp /opt/teleo-eval/workspaces/deploy/ops/auto-deploy.service /etc/systemd/system/teleo-auto-deploy.service
sudo cp /opt/teleo-eval/workspaces/deploy/ops/auto-deploy.timer /etc/systemd/system/teleo-auto-deploy.timer
sudo systemctl daemon-reload
sudo systemctl enable --now teleo-auto-deploy.timer
```
### 3. Verify
```bash
# Timer is active
systemctl status teleo-auto-deploy.timer
# Run once manually to seed the stamp file
sudo systemctl start teleo-auto-deploy.service
# Check logs
journalctl -u teleo-auto-deploy -n 20
```
### 4. Add teleo sudoers for auto-deploy restarts
If not already present, add to `/etc/sudoers.d/teleo`:
```
teleo ALL=(ALL) NOPASSWD: /bin/systemctl restart teleo-pipeline, /bin/systemctl restart teleo-diagnostics
```
## How It Works
Every 2 minutes, the timer fires `auto-deploy.sh`:
1. Fetches main from Forgejo (localhost)
2. Compares SHA against `/opt/teleo-eval/.last-deploy-sha`
3. If new commits: pulls, syntax-checks Python, syncs to working dirs
4. Restarts services ONLY if Python files changed in relevant paths
5. Runs smoke tests (systemd status + health endpoints)
6. Updates stamp on success. On failure: does NOT update stamp, retries next cycle.
## Monitoring
```bash
# Recent deploys
journalctl -u teleo-auto-deploy --since "1 hour ago"
# Timer schedule
systemctl list-timers teleo-auto-deploy.timer
# Last deployed SHA
cat /opt/teleo-eval/.last-deploy-sha
```
## Troubleshooting
**"git pull --ff-only failed"**: The deploy checkout diverged from main.
Fix: `cd /opt/teleo-eval/workspaces/deploy && git reset --hard origin/main`
**Syntax errors blocking deploy**: Fix the code, push to main. Next cycle retries.
**Service won't restart**: Check `journalctl -u teleo-pipeline -n 30`. Fix and push.
Auto-deploy will retry because stamp wasn't updated.

12
ops/auto-deploy.service Normal file
View file

@ -0,0 +1,12 @@
# Install: sudo cp ops/auto-deploy.service /etc/systemd/system/teleo-auto-deploy.service
# Then: sudo systemctl daemon-reload && sudo systemctl enable --now teleo-auto-deploy.timer
[Unit]
Description=Auto-deploy teleo-codex from Forgejo to working directories
After=network.target
[Service]
Type=oneshot
User=teleo
ExecStart=/opt/teleo-eval/workspaces/deploy/ops/auto-deploy.sh
StandardOutput=journal
StandardError=journal

140
ops/auto-deploy.sh Executable file
View file

@ -0,0 +1,140 @@
#!/usr/bin/env bash
# auto-deploy.sh — Pull from Forgejo, sync to working dirs, restart if needed.
# Runs as systemd timer (teleo-auto-deploy.timer) every 2 minutes.
# Exits silently when nothing has changed.
set -euo pipefail
LOCK_FILE="/tmp/teleo-auto-deploy.lock"
exec 9>"$LOCK_FILE"
if ! flock -n 9; then
logger -t "auto-deploy" "Another deploy is already running. Skipping."
exit 0
fi
DEPLOY_CHECKOUT="/opt/teleo-eval/workspaces/deploy"
PIPELINE_DIR="/opt/teleo-eval/pipeline"
DIAGNOSTICS_DIR="/opt/teleo-eval/diagnostics"
AGENT_STATE_DIR="/opt/teleo-eval/ops/agent-state"
STAMP_FILE="/opt/teleo-eval/.last-deploy-sha"
LOG_TAG="auto-deploy"
log() { logger -t "$LOG_TAG" "$1"; echo "$(date '+%Y-%m-%d %H:%M:%S') $1"; }
if [ ! -d "$DEPLOY_CHECKOUT/.git" ]; then
log "ERROR: Deploy checkout not found at $DEPLOY_CHECKOUT. Run setup first."
exit 1
fi
cd "$DEPLOY_CHECKOUT"
if ! git fetch origin main --quiet 2>&1; then
log "ERROR: git fetch failed"
exit 1
fi
NEW_SHA=$(git rev-parse origin/main)
OLD_SHA=$(cat "$STAMP_FILE" 2>/dev/null || echo "none")
if [ "$NEW_SHA" = "$OLD_SHA" ]; then
exit 0
fi
log "New commits: ${OLD_SHA:0:8} -> ${NEW_SHA:0:8}"
if ! git checkout main --quiet 2>&1; then
log "ERROR: git checkout main failed — dirty tree or corrupted index"
exit 1
fi
if ! git pull --ff-only --quiet 2>&1; then
log "ERROR: git pull --ff-only failed. Manual intervention needed."
exit 1
fi
# Syntax check all Python files before copying
ERRORS=0
for f in ops/pipeline-v2/lib/*.py ops/pipeline-v2/*.py ops/diagnostics/*.py; do
[ -f "$f" ] || continue
if ! python3 -c "import ast, sys; ast.parse(open(sys.argv[1]).read())" "$f" 2>&1; then
log "SYNTAX ERROR: $f"
ERRORS=$((ERRORS + 1))
fi
done
if [ "$ERRORS" -gt 0 ]; then
log "ERROR: $ERRORS syntax errors. Deploy aborted. Fix and push again."
exit 1
fi
log "Syntax check passed"
# Sync to working directories (mirrors deploy.sh logic)
RSYNC_FLAGS="-az --exclude='__pycache__' --exclude='*.pyc' --exclude='*.bak*'"
rsync $RSYNC_FLAGS ops/pipeline-v2/lib/ "$PIPELINE_DIR/lib/"
for f in teleo-pipeline.py reweave.py; do
[ -f "ops/pipeline-v2/$f" ] && rsync $RSYNC_FLAGS "ops/pipeline-v2/$f" "$PIPELINE_DIR/$f"
done
rsync $RSYNC_FLAGS ops/pipeline-v2/telegram/ "$PIPELINE_DIR/telegram/"
rsync $RSYNC_FLAGS ops/diagnostics/ "$DIAGNOSTICS_DIR/"
rsync $RSYNC_FLAGS ops/agent-state/ "$AGENT_STATE_DIR/"
[ -f ops/research-session.sh ] && rsync $RSYNC_FLAGS ops/research-session.sh /opt/teleo-eval/research-session.sh
log "Files synced"
# Restart services only if Python files changed
RESTART=""
if [ "$OLD_SHA" != "none" ]; then
if git diff --name-only "$OLD_SHA" "$NEW_SHA" -- ops/pipeline-v2/ 2>/dev/null | grep -q '\.py$'; then
RESTART="$RESTART teleo-pipeline"
fi
if git diff --name-only "$OLD_SHA" "$NEW_SHA" -- ops/diagnostics/ 2>/dev/null | grep -q '\.py$'; then
RESTART="$RESTART teleo-diagnostics"
fi
else
RESTART="teleo-pipeline teleo-diagnostics"
fi
if [ -n "$RESTART" ]; then
log "Restarting:$RESTART"
sudo systemctl restart $RESTART
sleep 15
FAIL=0
for svc in $RESTART; do
if systemctl is-active --quiet "$svc"; then
log "$svc: active"
else
log "ERROR: $svc failed to start"
journalctl -u "$svc" -n 5 --no-pager 2>/dev/null || true
FAIL=1
fi
done
if echo "$RESTART" | grep -q "teleo-pipeline"; then
if curl -sf --connect-timeout 3 http://localhost:8080/health > /dev/null 2>&1; then
log "pipeline health: OK"
else
log "WARNING: pipeline health check failed"
FAIL=1
fi
fi
if echo "$RESTART" | grep -q "teleo-diagnostics"; then
if curl -sf --connect-timeout 3 http://localhost:8081/ops > /dev/null 2>&1; then
log "diagnostics health: OK"
else
log "WARNING: diagnostics health check failed"
FAIL=1
fi
fi
if [ "$FAIL" -gt 0 ]; then
# Code is already synced — push a fix, don't wait for next cycle
log "WARNING: Smoke test failures. NOT updating stamp. Will retry next cycle. Push a fix."
exit 1
fi
else
log "No Python changes — services not restarted"
fi
echo "$NEW_SHA" > "$STAMP_FILE"
log "Deploy complete: $(git log --oneline -1 "$NEW_SHA")"

12
ops/auto-deploy.timer Normal file
View file

@ -0,0 +1,12 @@
# Install: sudo cp ops/auto-deploy.timer /etc/systemd/system/teleo-auto-deploy.timer
# Then: sudo systemctl daemon-reload && sudo systemctl enable --now teleo-auto-deploy.timer
[Unit]
Description=Run teleo auto-deploy every 2 minutes
[Timer]
OnBootSec=30
OnUnitActiveSec=2min
AccuracySec=10s
[Install]
WantedBy=timers.target

View file

@ -36,7 +36,7 @@ Copy this into your PR description and fill it in:
| File type | Example | Needs manifest? |
|-----------|---------|-----------------|
| Python application code | bot.py, app.py, alerting.py | Yes |
| Shell scripts on VPS | extract-cron.sh, evaluate-trigger.sh | Yes |
| Shell scripts on VPS | research-session.sh, auto-deploy.sh | Yes |
| systemd service/timer files | teleo-bot.service | Yes |
| Database migrations | ALTER TABLE, new tables | Yes |
| HTML/CSS/JS served by app | dashboard.html, teleo-app | Yes |

View file

@ -43,7 +43,7 @@ echo "=== Pre-deploy syntax check ==="
ERRORS=0
for f in "$REPO_ROOT/ops/pipeline-v2/lib/"*.py "$REPO_ROOT/ops/pipeline-v2/"*.py "$REPO_ROOT/ops/diagnostics/"*.py; do
[ -f "$f" ] || continue
if ! python3 -c "import ast, sys; ast.parse(open(sys.argv[1]).read())" "$f" 2>/dev/null; then
if ! python3 -c "import ast, sys; ast.parse(open(sys.argv[1]).read())" "$f" 2>&1; then
echo "SYNTAX ERROR: $f"
ERRORS=$((ERRORS + 1))
fi
@ -66,7 +66,7 @@ rsync $RSYNC_FLAGS "$REPO_ROOT/ops/pipeline-v2/lib/" "$VPS_HOST:$VPS_PIPELINE/li
echo ""
echo "=== Pipeline top-level ==="
for f in teleo-pipeline.py reweave.py batch-extract-50.sh; do
for f in teleo-pipeline.py reweave.py; do
[ -f "$REPO_ROOT/ops/pipeline-v2/$f" ] || continue
rsync $RSYNC_FLAGS "$REPO_ROOT/ops/pipeline-v2/$f" "$VPS_HOST:$VPS_PIPELINE/$f"
done
@ -76,6 +76,10 @@ echo "=== Diagnostics ==="
rsync $RSYNC_FLAGS "$REPO_ROOT/ops/diagnostics/" "$VPS_HOST:$VPS_DIAGNOSTICS/"
echo ""
echo "=== Telegram bot ==="
rsync $RSYNC_FLAGS "$REPO_ROOT/ops/pipeline-v2/telegram/" "$VPS_HOST:$VPS_PIPELINE/telegram/"
echo ""
echo "=== Agent state ==="
rsync $RSYNC_FLAGS "$REPO_ROOT/ops/agent-state/" "$VPS_HOST:$VPS_AGENT_STATE/"
echo ""

View file

@ -67,6 +67,8 @@ def check_agent_health(conn: sqlite3.Connection) -> list[dict]:
now = datetime.now(timezone.utc)
for r in rows:
agent = r["agent"]
if agent in ("unknown", None):
continue
latest = r["latest"]
if not latest:
continue
@ -266,24 +268,22 @@ def check_rejection_spike(conn: sqlite3.Connection) -> list[dict]:
"""Detect single rejection reason exceeding REJECTION_SPIKE_RATIO of recent rejections."""
alerts = []
# Total rejections in 24h
# Total rejected PRs in 24h (prs.eval_issues is the canonical source — Epimetheus 2026-04-02)
total = conn.execute(
"""SELECT COUNT(*) as n FROM audit_log
WHERE stage='evaluate'
AND event IN ('changes_requested','domain_rejected','tier05_rejected')
AND timestamp > datetime('now', '-24 hours')"""
"""SELECT COUNT(*) as n FROM prs
WHERE eval_issues IS NOT NULL AND eval_issues != '[]'
AND created_at > datetime('now', '-24 hours')"""
).fetchone()["n"]
if total < 10:
return alerts # Not enough data
# Count by rejection tag
# Count by rejection tag from prs.eval_issues
tags = conn.execute(
"""SELECT value as tag, COUNT(*) as cnt
FROM audit_log, json_each(json_extract(detail, '$.issues'))
WHERE stage='evaluate'
AND event IN ('changes_requested','domain_rejected','tier05_rejected')
AND timestamp > datetime('now', '-24 hours')
FROM prs, json_each(prs.eval_issues)
WHERE eval_issues IS NOT NULL AND eval_issues != '[]'
AND created_at > datetime('now', '-24 hours')
GROUP BY tag ORDER BY cnt DESC"""
).fetchall()
@ -315,16 +315,13 @@ def check_stuck_loops(conn: sqlite3.Connection) -> list[dict]:
"""Detect agents repeatedly failing on the same rejection reason."""
alerts = []
# COALESCE: rejection events use $.agent, eval events use $.domain_agent (Epimetheus 2026-03-28)
# Agent + rejection reason from prs table directly (Epimetheus correction 2026-04-02)
rows = conn.execute(
"""SELECT COALESCE(json_extract(detail, '$.agent'), json_extract(detail, '$.domain_agent')) as agent,
value as tag,
COUNT(*) as cnt
FROM audit_log, json_each(json_extract(detail, '$.issues'))
WHERE stage='evaluate'
AND event IN ('changes_requested','domain_rejected','tier05_rejected')
AND timestamp > datetime('now', '-6 hours')
AND COALESCE(json_extract(detail, '$.agent'), json_extract(detail, '$.domain_agent')) IS NOT NULL
"""SELECT agent, value as tag, COUNT(*) as cnt
FROM prs, json_each(prs.eval_issues)
WHERE eval_issues IS NOT NULL AND eval_issues != '[]'
AND agent IS NOT NULL
AND created_at > datetime('now', '-6 hours')
GROUP BY agent, tag
HAVING cnt > ?""",
(STUCK_LOOP_THRESHOLD,),
@ -412,16 +409,13 @@ def check_domain_rejection_patterns(conn: sqlite3.Connection) -> list[dict]:
"""Track rejection reason shift per domain — surfaces domain maturity issues."""
alerts = []
# Per-domain rejection breakdown in 24h
# Per-domain rejection breakdown in 24h from prs table (Epimetheus correction 2026-04-02)
rows = conn.execute(
"""SELECT json_extract(detail, '$.domain') as domain,
value as tag,
COUNT(*) as cnt
FROM audit_log, json_each(json_extract(detail, '$.issues'))
WHERE stage='evaluate'
AND event IN ('changes_requested','domain_rejected','tier05_rejected')
AND timestamp > datetime('now', '-24 hours')
AND json_extract(detail, '$.domain') IS NOT NULL
"""SELECT domain, value as tag, COUNT(*) as cnt
FROM prs, json_each(prs.eval_issues)
WHERE eval_issues IS NOT NULL AND eval_issues != '[]'
AND domain IS NOT NULL
AND created_at > datetime('now', '-24 hours')
GROUP BY domain, tag
ORDER BY domain, cnt DESC"""
).fetchall()
@ -473,12 +467,11 @@ def generate_failure_report(conn: sqlite3.Connection, agent: str, hours: int = 2
hours = int(hours) # defensive — callers should pass int, but enforce it
rows = conn.execute(
"""SELECT value as tag, COUNT(*) as cnt,
GROUP_CONCAT(DISTINCT json_extract(detail, '$.pr')) as pr_numbers
FROM audit_log, json_each(json_extract(detail, '$.issues'))
WHERE stage='evaluate'
AND event IN ('changes_requested','domain_rejected','tier05_rejected')
AND json_extract(detail, '$.agent') = ?
AND timestamp > datetime('now', ? || ' hours')
GROUP_CONCAT(DISTINCT number) as pr_numbers
FROM prs, json_each(prs.eval_issues)
WHERE eval_issues IS NOT NULL AND eval_issues != '[]'
AND agent = ?
AND created_at > datetime('now', ? || ' hours')
GROUP BY tag ORDER BY cnt DESC
LIMIT 5""",
(agent, f"-{hours}"),

View file

@ -194,12 +194,6 @@ fetch('/api/review-summary?days=30')
reasonRows += '<tr><td><code>' + esc(r.reason) + '</code></td><td>' + r.count + '</td></tr>';
}}
// Disagreement types
let disagreeRows = '';
for (const d of (data.disagreement_types || [])) {{
disagreeRows += '<tr><td>' + esc(d.type) + '</td><td>' + d.count + '</td></tr>';
}}
el.innerHTML = `
<div class="grid">
<div class="card"><div class="label">Total Reviews</div><div class="hero-value">${{data.total}}</div></div>
@ -215,13 +209,6 @@ fetch('/api/review-summary?days=30')
${{reasonRows || '<tr><td colspan="2" style="color:#8b949e">No rejections</td></tr>'}}
</table>
</div>
<div class="card">
<div style="font-weight:600;margin-bottom:8px">Disagreement Types</div>
<table>
<tr><th>Type</th><th>Count</th></tr>
${{disagreeRows || '<tr><td colspan="2" style="color:#8b949e">No disagreements</td></tr>'}}
</table>
</div>
</div>`;
}}).catch(() => {{
document.getElementById('review-container').innerHTML =

View file

@ -237,9 +237,9 @@ async def handle_extraction_yield_by_domain(request):
# Sources per domain (approximate from PR source_path domain)
source_counts = conn.execute(
"""SELECT domain, COUNT(DISTINCT source_url) as sources
"""SELECT domain, COUNT(DISTINCT path) as sources
FROM sources s
JOIN prs p ON p.source_path LIKE '%' || s.url || '%'
JOIN prs p ON p.source_path LIKE '%' || s.path || '%'
WHERE s.created_at > datetime('now', ? || ' days')
GROUP BY domain""",
(f"-{days}",),
@ -444,6 +444,8 @@ async def handle_cascade_coverage(request):
for r in triggered
]
insufficient_data = total_triggered < 5
return web.json_response({
"days": days,
"total_triggered": total_triggered,
@ -452,6 +454,7 @@ async def handle_cascade_coverage(request):
"total_notifications": summaries["total_notifications"] if summaries else 0,
"merges_with_cascade": summaries["total_merges_with_cascade"] if summaries else 0,
"by_agent": by_agent,
"insufficient_data": insufficient_data,
})
finally:
conn.close()
@ -490,7 +493,7 @@ async def handle_review_summary(request):
(f"-{days}",),
).fetchall()
# Rejection reasons
# Rejection reasons — try review_records first, fall back to prs.eval_issues
reasons = conn.execute(
"""SELECT rejection_reason, COUNT(*) as cnt
FROM review_records
@ -500,15 +503,17 @@ async def handle_review_summary(request):
(f"-{days}",),
).fetchall()
# Disagreement types
disagreements = conn.execute(
"""SELECT disagreement_type, COUNT(*) as cnt
FROM review_records
WHERE disagreement_type IS NOT NULL
AND reviewed_at > datetime('now', ? || ' days')
GROUP BY disagreement_type ORDER BY cnt DESC""",
(f"-{days}",),
).fetchall()
rejection_source = "review_records"
if not reasons:
reasons = conn.execute(
"""SELECT value AS rejection_reason, COUNT(*) as cnt
FROM prs, json_each(prs.eval_issues)
WHERE eval_issues IS NOT NULL AND eval_issues != '[]'
AND created_at > datetime('now', ? || ' days')
GROUP BY value ORDER BY cnt DESC""",
(f"-{days}",),
).fetchall()
rejection_source = "prs.eval_issues"
# Per-reviewer breakdown
reviewers = conn.execute(
@ -541,7 +546,7 @@ async def handle_review_summary(request):
"total": total,
"outcomes": {r["outcome"]: r["cnt"] for r in outcomes},
"rejection_reasons": [{"reason": r["rejection_reason"], "count": r["cnt"]} for r in reasons],
"disagreement_types": [{"type": r["disagreement_type"], "count": r["cnt"]} for r in disagreements],
"rejection_source": rejection_source,
"reviewers": [
{"reviewer": r["reviewer"], "approved": r["approved"], "approved_with_changes": r["approved_with_changes"],
"rejected": r["rejected"], "total": r["total"]}
@ -557,6 +562,124 @@ async def handle_review_summary(request):
conn.close()
# ─── GET /api/agent-scorecard ──────────────────────────────────────────────
async def handle_agent_scorecard(request):
"""Per-agent scorecard: PRs submitted, review outcomes, rejection reasons.
Data from review_records (structured reviews) + prs (submission counts).
Falls back to prs.eval_issues for rejection reasons when review_records
has no rejections yet.
"""
conn = request.app["_get_conn"]()
try:
try:
days = min(int(request.query.get("days", "30")), 90)
except ValueError:
days = 30
day_filter = f"-{days}"
# PRs submitted per agent
prs_by_agent = conn.execute(
"""SELECT agent, COUNT(*) as cnt FROM prs
WHERE agent IS NOT NULL
AND created_at > datetime('now', ? || ' days')
GROUP BY agent""",
(day_filter,),
).fetchall()
prs_map = {r["agent"]: r["cnt"] for r in prs_by_agent}
# Review outcomes from review_records
review_data = {}
try:
reviews = conn.execute(
"""SELECT reviewer as agent, outcome, COUNT(*) as cnt
FROM review_records
WHERE reviewed_at > datetime('now', ? || ' days')
GROUP BY reviewer, outcome""",
(day_filter,),
).fetchall()
for r in reviews:
agent = r["agent"]
if agent not in review_data:
review_data[agent] = {"approved": 0, "approved_with_changes": 0, "rejected": 0, "total": 0}
review_data[agent][r["outcome"].replace("-", "_")] = r["cnt"]
review_data[agent]["total"] += r["cnt"]
except sqlite3.OperationalError:
pass
# If review_records is empty, fall back to audit_log eval events
if not review_data:
evals = conn.execute(
"""SELECT
COALESCE(json_extract(detail, '$.agent'), json_extract(detail, '$.domain_agent')) as agent,
event, COUNT(*) as cnt
FROM audit_log
WHERE stage='evaluate'
AND event IN ('approved','changes_requested','domain_rejected','tier05_rejected')
AND timestamp > datetime('now', ? || ' days')
GROUP BY agent, event""",
(day_filter,),
).fetchall()
for r in evals:
agent = r["agent"]
if not agent:
continue
if agent not in review_data:
review_data[agent] = {"approved": 0, "approved_with_changes": 0, "rejected": 0, "total": 0}
if r["event"] == "approved":
review_data[agent]["approved"] += r["cnt"]
elif r["event"] == "changes_requested": # fixer auto-remediated; equivalent in pre-review_records era
review_data[agent]["approved_with_changes"] += r["cnt"]
else:
review_data[agent]["rejected"] += r["cnt"]
review_data[agent]["total"] += r["cnt"]
# Rejection reasons from prs.eval_issues (canonical source)
reason_rows = conn.execute(
"""SELECT agent, value as reason, COUNT(*) as cnt
FROM prs, json_each(prs.eval_issues)
WHERE eval_issues IS NOT NULL AND eval_issues != '[]'
AND agent IS NOT NULL
AND created_at > datetime('now', ? || ' days')
GROUP BY agent, reason ORDER BY agent, cnt DESC""",
(day_filter,),
).fetchall()
reasons_map = {}
for r in reason_rows:
if r["agent"] not in reasons_map:
reasons_map[r["agent"]] = {}
reasons_map[r["agent"]][r["reason"]] = r["cnt"]
# Build scorecards
all_agents = sorted(set(list(prs_map.keys()) + list(review_data.keys())))
scorecards = []
for agent in all_agents:
if agent in ("unknown", None):
continue
rd = review_data.get(agent, {"approved": 0, "approved_with_changes": 0, "rejected": 0, "total": 0})
total_reviews = rd["total"]
approved = rd["approved"]
approved_wc = rd["approved_with_changes"]
rejected = rd["rejected"]
approval_rate = ((approved + approved_wc) / total_reviews * 100) if total_reviews else 0
scorecards.append({
"agent": agent,
"total_prs": prs_map.get(agent, 0),
"total_reviews": total_reviews,
"approved": approved,
"approved_with_changes": approved_wc,
"rejected": rejected,
"approval_rate": round(approval_rate, 1),
"rejection_reasons": reasons_map.get(agent, {}),
})
scorecards.sort(key=lambda x: x["total_reviews"], reverse=True)
return web.json_response({"days": days, "scorecards": scorecards})
finally:
conn.close()
# ─── Trace endpoint ────────────────────────────────────────────────────────
@ -998,6 +1121,7 @@ def register_dashboard_routes(app: web.Application, get_conn):
app.router.add_get("/api/agents-dashboard", handle_agents_dashboard)
app.router.add_get("/api/cascade-coverage", handle_cascade_coverage)
app.router.add_get("/api/review-summary", handle_review_summary)
app.router.add_get("/api/agent-scorecard", handle_agent_scorecard)
app.router.add_get("/api/trace/{trace_id}", handle_trace)
app.router.add_get("/api/growth", handle_growth)
app.router.add_get("/api/pr-lifecycle", handle_pr_lifecycle)

View file

@ -1,621 +0,0 @@
#!/usr/bin/env bash
# evaluate-trigger.sh — Find unreviewed PRs, run 2-agent review, auto-merge if approved.
#
# Reviews each PR with up to THREE agents:
# 1. Leo (evaluator) — quality gates, cross-domain connections, coherence
# 2. Domain agent — domain expertise, duplicate check, technical accuracy
# 3. Ganymede (code reviewer) — code quality, correctness, safety (code PRs only)
#
# Ganymede reviews any PR that touches code files (ops/, diagnostics/, .py, .sh, etc.)
#
# After all reviews, auto-merges if:
# - Leo's comment contains "**Verdict:** approve"
# - Domain agent's comment contains "**Verdict:** approve" (if applicable)
# - Ganymede's comment contains "**Verdict:** approve" (if code PR)
# - No territory violations (files outside proposer's domain)
#
# Usage:
# ./ops/evaluate-trigger.sh # review + auto-merge approved PRs
# ./ops/evaluate-trigger.sh 47 # review a specific PR by number
# ./ops/evaluate-trigger.sh --dry-run # show what would be reviewed, don't run
# ./ops/evaluate-trigger.sh --leo-only # skip domain agent, just run Leo
# ./ops/evaluate-trigger.sh --no-merge # review only, don't auto-merge (old behavior)
#
# Requirements:
# - claude CLI (claude -p for headless mode)
# - gh CLI authenticated with repo access
# - Run from the teleo-codex repo root
#
# Safety:
# - Lockfile prevents concurrent runs
# - Auto-merge requires ALL reviewers to approve + no territory violations
# - Each PR runs sequentially to avoid branch conflicts
# - Timeout: 20 minutes per agent per PR
# - Pre-flight checks: clean working tree, gh auth
#
# Verdict protocol:
# All agents use `gh pr comment` (NOT `gh pr review`) because all agents
# share the m3taversal GitHub account — `gh pr review --approve` fails
# when the PR author and reviewer are the same user. The merge check
# parses issue comments for structured verdict markers instead.
set -euo pipefail
# Allow nested Claude Code sessions (headless spawned from interactive)
unset CLAUDECODE 2>/dev/null || true
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
cd "$REPO_ROOT"
LOCKFILE="/tmp/evaluate-trigger.lock"
LOG_DIR="$REPO_ROOT/ops/sessions"
TIMEOUT_SECONDS=1200
DRY_RUN=false
LEO_ONLY=false
NO_MERGE=false
SPECIFIC_PR=""
# --- Code PR detection ---
# Returns "true" if the PR touches code files (ops/, diagnostics/, scripts, .py, .sh, .js, .html)
# These PRs need Ganymede code review in addition to Leo's quality review.
detect_code_pr() {
local pr_number="$1"
local files
files=$(gh pr view "$pr_number" --json files --jq '.files[].path' 2>/dev/null || echo "")
if echo "$files" | grep -qE "^ops/|^diagnostics/|\.py$|\.sh$|\.js$|\.html$|\.css$|\.json$"; then
echo "true"
else
echo "false"
fi
}
# --- Domain routing map ---
# Maps branch prefix or domain directory to agent name and identity path
detect_domain_agent() {
local pr_number="$1"
local branch files domain agent
branch=$(gh pr view "$pr_number" --json headRefName --jq '.headRefName' 2>/dev/null || echo "")
files=$(gh pr view "$pr_number" --json files --jq '.files[].path' 2>/dev/null || echo "")
# Try branch prefix first
case "$branch" in
rio/*|*/internet-finance*) agent="rio"; domain="internet-finance" ;;
clay/*|*/entertainment*) agent="clay"; domain="entertainment" ;;
theseus/*|*/ai-alignment*) agent="theseus"; domain="ai-alignment" ;;
vida/*|*/health*) agent="vida"; domain="health" ;;
astra/*|*/space-development*) agent="astra"; domain="space-development" ;;
leo/*|*/grand-strategy*) agent="leo"; domain="grand-strategy" ;;
contrib/*)
# External contributor — detect domain from changed files (fall through to file check)
agent=""; domain=""
;;
*)
agent=""; domain=""
;;
esac
# If no agent detected from branch prefix, check changed files
if [ -z "$agent" ]; then
if echo "$files" | grep -q "domains/internet-finance/"; then
agent="rio"; domain="internet-finance"
elif echo "$files" | grep -q "domains/entertainment/"; then
agent="clay"; domain="entertainment"
elif echo "$files" | grep -q "domains/ai-alignment/"; then
agent="theseus"; domain="ai-alignment"
elif echo "$files" | grep -q "domains/health/"; then
agent="vida"; domain="health"
elif echo "$files" | grep -q "domains/space-development/"; then
agent="astra"; domain="space-development"
fi
fi
echo "$agent $domain"
}
# --- Parse arguments ---
for arg in "$@"; do
case "$arg" in
--dry-run) DRY_RUN=true ;;
--leo-only) LEO_ONLY=true ;;
--no-merge) NO_MERGE=true ;;
[0-9]*) SPECIFIC_PR="$arg" ;;
--help|-h)
head -23 "$0" | tail -21
exit 0
;;
*)
echo "Unknown argument: $arg"
exit 1
;;
esac
done
# --- Pre-flight checks ---
if ! gh auth status >/dev/null 2>&1; then
echo "ERROR: gh CLI not authenticated. Run 'gh auth login' first."
exit 1
fi
if ! command -v claude >/dev/null 2>&1; then
echo "ERROR: claude CLI not found. Install it first."
exit 1
fi
# Check for dirty working tree (ignore ops/, .claude/, .github/ which may contain local-only files)
DIRTY_FILES=$(git status --porcelain | grep -v '^?? ops/' | grep -v '^ M ops/' | grep -v '^?? \.claude/' | grep -v '^ M \.claude/' | grep -v '^?? \.github/' | grep -v '^ M \.github/' || true)
if [ -n "$DIRTY_FILES" ]; then
echo "ERROR: Working tree is dirty. Clean up before running."
echo "$DIRTY_FILES"
exit 1
fi
# --- Lockfile (prevent concurrent runs) ---
if [ -f "$LOCKFILE" ]; then
LOCK_PID=$(cat "$LOCKFILE" 2>/dev/null || echo "")
if [ -n "$LOCK_PID" ] && kill -0 "$LOCK_PID" 2>/dev/null; then
echo "Another evaluate-trigger is running (PID $LOCK_PID). Exiting."
exit 1
else
echo "Stale lockfile found. Removing."
rm -f "$LOCKFILE"
fi
fi
echo $$ > "$LOCKFILE"
trap 'rm -f "$LOCKFILE"' EXIT
# --- Ensure log directory exists ---
mkdir -p "$LOG_DIR"
# --- Find PRs to review ---
if [ -n "$SPECIFIC_PR" ]; then
PR_STATE=$(gh pr view "$SPECIFIC_PR" --json state --jq '.state' 2>/dev/null || echo "NOT_FOUND")
if [ "$PR_STATE" != "OPEN" ]; then
echo "PR #$SPECIFIC_PR is $PR_STATE (not OPEN). Reviewing anyway for testing."
fi
PRS_TO_REVIEW="$SPECIFIC_PR"
else
# NOTE: gh pr list silently returns empty in some worktree configs; use gh api instead
OPEN_PRS=$(gh api repos/:owner/:repo/pulls --jq '.[].number' 2>/dev/null || echo "")
if [ -z "$OPEN_PRS" ]; then
echo "No open PRs found. Nothing to review."
exit 0
fi
PRS_TO_REVIEW=""
for pr in $OPEN_PRS; do
# Check if this PR already has a Leo verdict comment (avoid re-reviewing)
LEO_COMMENTED=$(gh pr view "$pr" --json comments \
--jq '[.comments[] | select(.body | test("VERDICT:LEO:(APPROVE|REQUEST_CHANGES)"))] | length' 2>/dev/null || echo "0")
LAST_COMMIT_DATE=$(gh pr view "$pr" --json commits --jq '.commits[-1].committedDate' 2>/dev/null || echo "")
if [ "$LEO_COMMENTED" = "0" ]; then
PRS_TO_REVIEW="$PRS_TO_REVIEW $pr"
else
# Check if new commits since last Leo review
LAST_LEO_DATE=$(gh pr view "$pr" --json comments \
--jq '[.comments[] | select(.body | test("VERDICT:LEO:")) | .createdAt] | last' 2>/dev/null || echo "")
if [ -n "$LAST_COMMIT_DATE" ] && [ -n "$LAST_LEO_DATE" ] && [[ "$LAST_COMMIT_DATE" > "$LAST_LEO_DATE" ]]; then
echo "PR #$pr: New commits since last review. Queuing for re-review."
PRS_TO_REVIEW="$PRS_TO_REVIEW $pr"
else
echo "PR #$pr: Already reviewed. Skipping."
fi
fi
done
PRS_TO_REVIEW=$(echo "$PRS_TO_REVIEW" | xargs)
if [ -z "$PRS_TO_REVIEW" ]; then
echo "All open PRs are up to date. Nothing to do."
exit 0
fi
fi
echo "PRs to review: $PRS_TO_REVIEW"
if [ "$DRY_RUN" = true ]; then
for pr in $PRS_TO_REVIEW; do
read -r agent domain <<< "$(detect_domain_agent "$pr")"
is_code=$(detect_code_pr "$pr")
reviewers="Leo + ${agent:-unknown} (${domain:-unknown domain})"
[ "$is_code" = "true" ] && reviewers="$reviewers + Ganymede (code)"
echo "[DRY RUN] PR #$pr$reviewers"
done
exit 0
fi
# --- Run headless reviews on each PR ---
run_agent_review() {
local pr="$1" agent_name="$2" prompt="$3" model="$4"
local timestamp log_file review_file
timestamp=$(date +%Y%m%d-%H%M%S)
log_file="$LOG_DIR/${agent_name}-review-pr${pr}-${timestamp}.log"
review_file="/tmp/${agent_name}-review-pr${pr}.md"
echo " Running ${agent_name} (model: ${model})..."
echo " Log: $log_file"
if perl -e "alarm $TIMEOUT_SECONDS; exec @ARGV" claude -p \
--model "$model" \
--allowedTools "Read,Write,Edit,Bash,Glob,Grep" \
--permission-mode bypassPermissions \
"$prompt" \
> "$log_file" 2>&1; then
echo " ${agent_name}: Review posted."
rm -f "$review_file"
return 0
else
local exit_code=$?
if [ "$exit_code" -eq 142 ] || [ "$exit_code" -eq 124 ]; then
echo " ${agent_name}: TIMEOUT after ${TIMEOUT_SECONDS}s."
else
echo " ${agent_name}: FAILED (exit code $exit_code)."
fi
rm -f "$review_file"
return 1
fi
}
# --- Territory violation check ---
# Verifies all changed files are within the proposer's expected territory
check_territory_violations() {
local pr_number="$1"
local branch files proposer violations
branch=$(gh pr view "$pr_number" --json headRefName --jq '.headRefName' 2>/dev/null || echo "")
files=$(gh pr view "$pr_number" --json files --jq '.files[].path' 2>/dev/null || echo "")
# Determine proposer from branch prefix
proposer=$(echo "$branch" | cut -d'/' -f1)
# Map proposer to allowed directories
local allowed_domains=""
case "$proposer" in
rio) allowed_domains="domains/internet-finance/" ;;
clay) allowed_domains="domains/entertainment/" ;;
theseus) allowed_domains="domains/ai-alignment/" ;;
vida) allowed_domains="domains/health/" ;;
astra) allowed_domains="domains/space-development/" ;;
leo) allowed_domains="core/|foundations/" ;;
contrib) echo ""; return 0 ;; # External contributors — skip territory check
*) echo ""; return 0 ;; # Unknown proposer — skip check
esac
# Check each file — allow inbox/archive/, agents/{proposer}/, schemas/, foundations/, and the agent's domain
violations=""
while IFS= read -r file; do
[ -z "$file" ] && continue
# Always allowed: inbox/archive, own agent dir, maps/, foundations/ (any agent can propose foundation claims)
if echo "$file" | grep -qE "^inbox/archive/|^agents/${proposer}/|^maps/|^foundations/"; then
continue
fi
# Check against allowed domain directories
if echo "$file" | grep -qE "^${allowed_domains}"; then
continue
fi
violations="${violations} - ${file}\n"
done <<< "$files"
if [ -n "$violations" ]; then
echo -e "$violations"
else
echo ""
fi
}
# --- Auto-merge check ---
# Parses issue comments for structured verdict markers.
# Verdict protocol: agents post `<!-- VERDICT:AGENT_KEY:APPROVE -->` or
# `<!-- VERDICT:AGENT_KEY:REQUEST_CHANGES -->` as HTML comments in their review.
# This is machine-parseable and invisible in the rendered comment.
check_merge_eligible() {
local pr_number="$1"
local domain_agent="$2"
local leo_passed="$3"
local is_code_pr="${4:-false}"
local ganymede_passed="${5:-true}"
# Gate 1: Leo must have completed without timeout/error
if [ "$leo_passed" != "true" ]; then
echo "BLOCK: Leo review failed or timed out"
return 1
fi
# Gate 2: Check Leo's verdict from issue comments
local leo_verdict
leo_verdict=$(gh pr view "$pr_number" --json comments \
--jq '[.comments[] | select(.body | test("VERDICT:LEO:")) | .body] | last' 2>/dev/null || echo "")
if echo "$leo_verdict" | grep -q "VERDICT:LEO:APPROVE"; then
echo "Leo: APPROVED"
elif echo "$leo_verdict" | grep -q "VERDICT:LEO:REQUEST_CHANGES"; then
echo "BLOCK: Leo requested changes"
return 1
else
echo "BLOCK: Could not find Leo's verdict marker in PR comments"
return 1
fi
# Gate 3: Check domain agent verdict (if applicable)
if [ -n "$domain_agent" ] && [ "$domain_agent" != "leo" ]; then
local domain_key
domain_key=$(echo "$domain_agent" | tr '[:lower:]' '[:upper:]')
local domain_verdict
domain_verdict=$(gh pr view "$pr_number" --json comments \
--jq "[.comments[] | select(.body | test(\"VERDICT:${domain_key}:\")) | .body] | last" 2>/dev/null || echo "")
if echo "$domain_verdict" | grep -q "VERDICT:${domain_key}:APPROVE"; then
echo "Domain agent ($domain_agent): APPROVED"
elif echo "$domain_verdict" | grep -q "VERDICT:${domain_key}:REQUEST_CHANGES"; then
echo "BLOCK: $domain_agent requested changes"
return 1
else
echo "BLOCK: No verdict marker found for $domain_agent"
return 1
fi
else
echo "Domain agent: N/A (leo-only or grand-strategy)"
fi
# Gate 4: Ganymede code review (for code PRs)
if [ "$is_code_pr" = "true" ]; then
if [ "$ganymede_passed" != "true" ]; then
echo "BLOCK: Ganymede code review failed or timed out"
return 1
fi
local ganymede_verdict
ganymede_verdict=$(gh pr view "$pr_number" --json comments \
--jq '[.comments[] | select(.body | test("VERDICT:GANYMEDE:")) | .body] | last' 2>/dev/null || echo "")
if echo "$ganymede_verdict" | grep -q "VERDICT:GANYMEDE:APPROVE"; then
echo "Ganymede (code review): APPROVED"
elif echo "$ganymede_verdict" | grep -q "VERDICT:GANYMEDE:REQUEST_CHANGES"; then
echo "BLOCK: Ganymede requested code changes"
return 1
else
echo "BLOCK: No verdict marker found for Ganymede code review"
return 1
fi
fi
# Gate 5: Territory violations
local violations
violations=$(check_territory_violations "$pr_number")
if [ -n "$violations" ]; then
echo "BLOCK: Territory violations detected:"
echo -e "$violations"
return 1
else
echo "Territory: clean"
fi
return 0
}
REVIEWED=0
FAILED=0
MERGED=0
for pr in $PRS_TO_REVIEW; do
echo ""
echo "=== PR #$pr ==="
echo "Started: $(date)"
# Detect which domain agent should review
read -r DOMAIN_AGENT DOMAIN <<< "$(detect_domain_agent "$pr")"
echo "Domain: ${DOMAIN:-unknown} | Agent: ${DOMAIN_AGENT:-none detected}"
# --- Review 1: Leo (evaluator) ---
LEO_REVIEW_FILE="/tmp/leo-review-pr${pr}.md"
LEO_PROMPT="You are Leo. Read agents/leo/identity.md, agents/leo/beliefs.md, agents/leo/reasoning.md, and skills/evaluate.md.
Review PR #${pr} on this repo.
First, run: gh pr view ${pr} --json title,body,files,additions,deletions
Then checkout the PR branch: gh pr checkout ${pr}
Read every changed file completely.
Before evaluating, scan the existing knowledge base for duplicate and contradiction checks:
- List claim files in the relevant domain directory (e.g., domains/${DOMAIN}/)
- Read titles to check for semantic duplicates
- Check for contradictions with existing claims in that domain and in foundations/
For each proposed claim, evaluate against these 11 quality criteria from CLAUDE.md:
1. Specificity — Is this specific enough to disagree with?
2. Evidence — Is there traceable evidence in the body?
3. Description quality — Does the description add info beyond the title?
4. Confidence calibration — Does the confidence level match the evidence?
5. Duplicate check — Does this already exist in the knowledge base?
6. Contradiction check — Does this contradict an existing claim? If so, is the contradiction explicit?
7. Value add — Does this genuinely expand what the knowledge base knows?
8. Wiki links — Do all [[links]] point to real files?
9. Scope qualification — Does the claim specify structural vs functional, micro vs macro, causal vs correlational?
10. Universal quantifier check — Does the title use unwarranted universals (all, always, never, the only)?
11. Counter-evidence acknowledgment — For likely or higher: is opposing evidence acknowledged?
Also check:
- Source archive updated correctly (status field)
- Commit messages follow conventions
- Files are in the correct domain directory
- Cross-domain connections that the proposer may have missed
Write your complete review to ${LEO_REVIEW_FILE}
CRITICAL — Verdict format: Your review MUST end with exactly one of these verdict markers (as an HTML comment on its own line):
<!-- VERDICT:LEO:APPROVE -->
<!-- VERDICT:LEO:REQUEST_CHANGES -->
Then post the review as an issue comment:
gh pr comment ${pr} --body-file ${LEO_REVIEW_FILE}
IMPORTANT: Use 'gh pr comment' NOT 'gh pr review'. We use a shared GitHub account so gh pr review --approve fails.
DO NOT merge — the orchestrator handles merge decisions after all reviews are posted.
Work autonomously. Do not ask for confirmation."
if run_agent_review "$pr" "leo" "$LEO_PROMPT" "opus"; then
LEO_PASSED=true
else
LEO_PASSED=false
fi
# Return to main between reviews
git checkout main 2>/dev/null || git checkout -f main
PR_BRANCH=$(gh pr view "$pr" --json headRefName --jq '.headRefName' 2>/dev/null || echo "")
[ -n "$PR_BRANCH" ] && git branch -D "$PR_BRANCH" 2>/dev/null || true
# --- Review 2: Domain agent ---
if [ "$LEO_ONLY" = true ]; then
echo " Skipping domain agent review (--leo-only)."
elif [ -z "$DOMAIN_AGENT" ]; then
echo " Could not detect domain agent. Skipping domain review."
elif [ "$DOMAIN_AGENT" = "leo" ]; then
echo " Domain is grand-strategy (Leo's territory). Single review sufficient."
else
DOMAIN_REVIEW_FILE="/tmp/${DOMAIN_AGENT}-review-pr${pr}.md"
AGENT_NAME_UPPER=$(echo "${DOMAIN_AGENT}" | awk '{print toupper(substr($0,1,1)) substr($0,2)}')
AGENT_KEY_UPPER=$(echo "${DOMAIN_AGENT}" | tr '[:lower:]' '[:upper:]')
DOMAIN_PROMPT="You are ${AGENT_NAME_UPPER}. Read agents/${DOMAIN_AGENT}/identity.md, agents/${DOMAIN_AGENT}/beliefs.md, and skills/evaluate.md.
You are reviewing PR #${pr} as the domain expert for ${DOMAIN}.
First, run: gh pr view ${pr} --json title,body,files,additions,deletions
Then checkout the PR branch: gh pr checkout ${pr}
Read every changed file completely.
Your review focuses on DOMAIN EXPERTISE — things only a ${DOMAIN} specialist would catch:
1. **Technical accuracy** — Are the claims factually correct within the ${DOMAIN} domain?
2. **Domain duplicates** — Do any claims duplicate existing knowledge in domains/${DOMAIN}/?
Scan the directory and read titles carefully.
3. **Missing context** — What important nuance from the ${DOMAIN} domain is the claim missing?
4. **Belief impact** — Do any claims affect your current beliefs? Read agents/${DOMAIN_AGENT}/beliefs.md
and flag if any belief needs updating.
5. **Connections** — What existing claims in your domain should be wiki-linked?
6. **Confidence calibration** — From your domain expertise, is the confidence level right?
Write your review to ${DOMAIN_REVIEW_FILE}
CRITICAL — Verdict format: Your review MUST end with exactly one of these verdict markers (as an HTML comment on its own line):
<!-- VERDICT:${AGENT_KEY_UPPER}:APPROVE -->
<!-- VERDICT:${AGENT_KEY_UPPER}:REQUEST_CHANGES -->
Then post the review as an issue comment:
gh pr comment ${pr} --body-file ${DOMAIN_REVIEW_FILE}
IMPORTANT: Use 'gh pr comment' NOT 'gh pr review'. We use a shared GitHub account so gh pr review --approve fails.
Sign your review as ${AGENT_NAME_UPPER} (domain reviewer for ${DOMAIN}).
DO NOT duplicate Leo's quality gate checks — he covers those.
DO NOT merge — the orchestrator handles merge decisions after all reviews are posted.
Work autonomously. Do not ask for confirmation."
run_agent_review "$pr" "$DOMAIN_AGENT" "$DOMAIN_PROMPT" "sonnet"
# Clean up branch again
git checkout main 2>/dev/null || git checkout -f main
[ -n "$PR_BRANCH" ] && git branch -D "$PR_BRANCH" 2>/dev/null || true
fi
# --- Review 3: Ganymede code review (for PRs touching code files) ---
IS_CODE_PR=$(detect_code_pr "$pr")
GANYMEDE_PASSED=true
if [ "$IS_CODE_PR" = "true" ] && [ "$LEO_ONLY" != true ]; then
echo " Code files detected — running Ganymede code review."
GANYMEDE_REVIEW_FILE="/tmp/ganymede-review-pr${pr}.md"
GANYMEDE_PROMPT="You are Ganymede, the code quality reviewer for the Teleo collective.
Review PR #${pr} for code quality, correctness, and safety.
First, run: gh pr view ${pr} --json title,body,files,additions,deletions
Then checkout the PR branch: gh pr checkout ${pr}
Read every changed file completely. Also read the existing versions of modified files on main for comparison.
Your review focuses on CODE QUALITY — things a code reviewer catches:
1. **Correctness** — Does the code do what it claims? Are there logic errors, off-by-one bugs, or unhandled edge cases?
2. **Safety** — Any security issues? SQL injection, path traversal, unchecked inputs, secrets in code?
3. **Breaking changes** — Does this change file formats, API responses, DB schemas, or config structures that other agents depend on? If so, is there a migration path?
4. **Error handling** — Will failures be visible or silent? Are there bare excepts, missing error messages, or swallowed exceptions?
5. **Integration** — Does the code work with the existing system? Are imports correct, paths valid, dependencies present?
6. **Simplicity** — Is this more complex than it needs to be? Could it be simpler?
Also check:
- systemd ReadWritePaths if new file write paths are introduced
- Path format consistency (absolute vs relative)
- Concurrent edit risk on shared files (app.py, bot.py, etc.)
Write your review to ${GANYMEDE_REVIEW_FILE}
CRITICAL — Verdict format: Your review MUST end with exactly one of these verdict markers (as an HTML comment on its own line):
<!-- VERDICT:GANYMEDE:APPROVE -->
<!-- VERDICT:GANYMEDE:REQUEST_CHANGES -->
Then post the review as an issue comment:
gh pr comment ${pr} --body-file ${GANYMEDE_REVIEW_FILE}
IMPORTANT: Use 'gh pr comment' NOT 'gh pr review'. We use a shared GitHub account so gh pr review --approve fails.
Sign your review as Ganymede (code reviewer).
DO NOT duplicate Leo's knowledge quality checks — he covers those. You cover code.
DO NOT merge — the orchestrator handles merge decisions after all reviews are posted.
Work autonomously. Do not ask for confirmation."
if run_agent_review "$pr" "ganymede" "$GANYMEDE_PROMPT" "sonnet"; then
GANYMEDE_PASSED=true
else
GANYMEDE_PASSED=false
fi
# Clean up branch
git checkout main 2>/dev/null || git checkout -f main
[ -n "$PR_BRANCH" ] && git branch -D "$PR_BRANCH" 2>/dev/null || true
elif [ "$IS_CODE_PR" = "true" ] && [ "$LEO_ONLY" = true ]; then
echo " Code files detected but skipping Ganymede review (--leo-only)."
fi
if [ "$LEO_PASSED" = true ]; then
REVIEWED=$((REVIEWED + 1))
else
FAILED=$((FAILED + 1))
fi
# --- Auto-merge decision ---
if [ "$NO_MERGE" = true ]; then
echo " Auto-merge: skipped (--no-merge)"
elif [ "$LEO_PASSED" != "true" ]; then
echo " Auto-merge: skipped (Leo review failed)"
else
echo ""
echo " --- Merge eligibility check ---"
MERGE_LOG=$(check_merge_eligible "$pr" "$DOMAIN_AGENT" "$LEO_PASSED" "$IS_CODE_PR" "$GANYMEDE_PASSED")
MERGE_RESULT=$?
echo "$MERGE_LOG" | sed 's/^/ /'
if [ "$MERGE_RESULT" -eq 0 ]; then
echo " Auto-merge: ALL GATES PASSED — merging PR #$pr"
if gh pr merge "$pr" --squash 2>&1; then
echo " PR #$pr: MERGED successfully."
MERGED=$((MERGED + 1))
else
echo " PR #$pr: Merge FAILED. May need manual intervention."
fi
else
echo " Auto-merge: BLOCKED — see reasons above"
fi
fi
echo "Finished: $(date)"
done
echo ""
echo "=== Summary ==="
echo "Reviewed: $REVIEWED"
echo "Failed: $FAILED"
echo "Merged: $MERGED"
echo "Logs: $LOG_DIR"

View file

@ -1,179 +0,0 @@
#!/bin/bash
# Extract claims from unprocessed sources in inbox/archive/
# Runs via cron on VPS every 15 minutes.
#
# Concurrency model:
# - Lockfile prevents overlapping runs
# - MAX_SOURCES=5 per cycle (works through backlog over multiple runs)
# - Sequential processing (one source at a time)
# - 50 sources landing at once = ~10 cron cycles to clear, not 50 parallel agents
#
# Domain routing:
# - Reads domain: field from source frontmatter
# - Maps to the domain agent (rio, clay, theseus, vida, astra, leo)
# - Runs extraction AS that agent — their territory, their extraction
# - Skips sources with status: processing (agent handling it themselves)
#
# Flow:
# 1. Pull latest main
# 2. Find sources with status: unprocessed (skip processing/processed/null-result)
# 3. For each: run Claude headless to extract claims as the domain agent
# 4. Commit extractions, push, open PR
# 5. Update source status to processed
#
# The eval pipeline (webhook.py) handles review and merge separately.
set -euo pipefail
REPO_DIR="/opt/teleo-eval/workspaces/extract"
REPO_URL="http://m3taversal:$(cat /opt/teleo-eval/secrets/forgejo-admin-token)@localhost:3000/teleo/teleo-codex.git"
CLAUDE_BIN="/home/teleo/.local/bin/claude"
LOG_DIR="/opt/teleo-eval/logs"
LOG="$LOG_DIR/extract-cron.log"
LOCKFILE="/tmp/extract-cron.lock"
MAX_SOURCES=5 # Process at most 5 sources per run to limit cost
log() { echo "[$(date -Iseconds)] $*" >> "$LOG"; }
# --- Lock ---
if [ -f "$LOCKFILE" ]; then
pid=$(cat "$LOCKFILE" 2>/dev/null)
if kill -0 "$pid" 2>/dev/null; then
log "SKIP: already running (pid $pid)"
exit 0
fi
log "WARN: stale lockfile, removing"
rm -f "$LOCKFILE"
fi
echo $$ > "$LOCKFILE"
trap 'rm -f "$LOCKFILE"' EXIT
# --- Ensure repo clone ---
if [ ! -d "$REPO_DIR/.git" ]; then
log "Cloning repo..."
git clone "$REPO_URL" "$REPO_DIR" >> "$LOG" 2>&1
fi
cd "$REPO_DIR"
# --- Pull latest main ---
git checkout main >> "$LOG" 2>&1
git pull --rebase >> "$LOG" 2>&1
# --- Find unprocessed sources ---
UNPROCESSED=$(grep -rl '^status: unprocessed' inbox/archive/ 2>/dev/null | head -n "$MAX_SOURCES" || true)
if [ -z "$UNPROCESSED" ]; then
log "No unprocessed sources found"
exit 0
fi
COUNT=$(echo "$UNPROCESSED" | wc -l | tr -d ' ')
log "Found $COUNT unprocessed source(s)"
# --- Process each source ---
for SOURCE_FILE in $UNPROCESSED; do
SLUG=$(basename "$SOURCE_FILE" .md)
BRANCH="extract/$SLUG"
log "Processing: $SOURCE_FILE → branch $BRANCH"
# Create branch from main
git checkout main >> "$LOG" 2>&1
git branch -D "$BRANCH" 2>/dev/null || true
git checkout -b "$BRANCH" >> "$LOG" 2>&1
# Read domain from frontmatter
DOMAIN=$(grep '^domain:' "$SOURCE_FILE" | head -1 | sed 's/domain: *//' | tr -d '"' | tr -d "'" | xargs)
# Map domain to agent
case "$DOMAIN" in
internet-finance) AGENT="rio" ;;
entertainment) AGENT="clay" ;;
ai-alignment) AGENT="theseus" ;;
health) AGENT="vida" ;;
space-development) AGENT="astra" ;;
*) AGENT="leo" ;;
esac
AGENT_TOKEN=$(cat "/opt/teleo-eval/secrets/forgejo-${AGENT}-token" 2>/dev/null || cat /opt/teleo-eval/secrets/forgejo-leo-token)
log "Domain: $DOMAIN, Agent: $AGENT"
# Run Claude headless to extract claims
EXTRACT_PROMPT="You are $AGENT, a Teleo knowledge base agent. Extract claims from this source.
READ these files first:
- skills/extract.md (extraction process)
- schemas/claim.md (claim format)
- $SOURCE_FILE (the source to extract from)
Then scan domains/$DOMAIN/ to check for duplicate claims.
EXTRACT claims following the process in skills/extract.md:
1. Read the source completely
2. Separate evidence from interpretation
3. Extract candidate claims (specific, disagreeable, evidence-backed)
4. Check for duplicates against existing claims in domains/$DOMAIN/
5. Write claim files to domains/$DOMAIN/ with proper YAML frontmatter
6. Update $SOURCE_FILE: set status to 'processed', add processed_by: $AGENT, processed_date: $(date +%Y-%m-%d), and claims_extracted list
If no claims can be extracted, update $SOURCE_FILE: set status to 'null-result' and add notes explaining why.
IMPORTANT: Use the Edit tool to update the source file status. Use the Write tool to create new claim files. Do not create claims that duplicate existing ones."
# Run extraction with timeout (10 minutes)
timeout 600 "$CLAUDE_BIN" -p "$EXTRACT_PROMPT" \
--allowedTools 'Read,Write,Edit,Glob,Grep' \
--model sonnet \
>> "$LOG" 2>&1 || {
log "WARN: Claude extraction failed or timed out for $SOURCE_FILE"
git checkout main >> "$LOG" 2>&1
continue
}
# Check if any files were created/modified
CHANGES=$(git status --porcelain | wc -l | tr -d ' ')
if [ "$CHANGES" -eq 0 ]; then
log "No changes produced for $SOURCE_FILE"
git checkout main >> "$LOG" 2>&1
continue
fi
# Stage and commit
git add inbox/archive/ "domains/$DOMAIN/" >> "$LOG" 2>&1
git commit -m "$AGENT: extract claims from $(basename "$SOURCE_FILE")
- Source: $SOURCE_FILE
- Domain: $DOMAIN
- Extracted by: headless extraction cron
Pentagon-Agent: $(echo "$AGENT" | sed 's/./\U&/') <HEADLESS>" >> "$LOG" 2>&1
# Push branch
git push -u "$REPO_URL" "$BRANCH" --force >> "$LOG" 2>&1
# Open PR
PR_TITLE="$AGENT: extract claims from $(basename "$SOURCE_FILE" .md)"
PR_BODY="## Automated Extraction\n\nSource: \`$SOURCE_FILE\`\nDomain: $DOMAIN\nExtracted by: headless cron on VPS\n\nThis PR was created automatically by the extraction cron job. Claims were extracted using \`skills/extract.md\` process via Claude headless."
curl -s -X POST "http://localhost:3000/api/v1/repos/teleo/teleo-codex/pulls" \
-H "Authorization: token $AGENT_TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"title\": \"$PR_TITLE\",
\"body\": \"$PR_BODY\",
\"base\": \"main\",
\"head\": \"$BRANCH\"
}" >> "$LOG" 2>&1
log "PR opened for $SOURCE_FILE"
# Back to main for next source
git checkout main >> "$LOG" 2>&1
# Brief pause between extractions
sleep 5
done
log "Extraction run complete: processed $COUNT source(s)"

View file

@ -1,283 +0,0 @@
#!/bin/bash
# Batch extract sources from inbox/queue/ — v3 with two-gate skip logic
#
# Uses separate extract/ worktree (not main/ — prevents daemon race condition).
# Skip logic uses two checks instead of local marker files (Ganymede v3 review):
# Gate 1: Is source already in archive/{domain}/? → already processed, dedup
# Gate 2: Does extraction branch exist on Forgejo? → extraction in progress
# Gate 3: Does pipeline.db show ≥3 closed PRs for this source? → zombie, skip
# Gate 4: Does pipeline.db show active OR recently closed PR? → skip (4h cooldown)
# All gates pass → extract
#
# Architecture: Ganymede (two-gate) + Rhea (separate worktrees)
REPO=/opt/teleo-eval/workspaces/extract
MAIN_REPO=/opt/teleo-eval/workspaces/main
EXTRACT=/opt/teleo-eval/openrouter-extract-v2.py
CLEANUP=/opt/teleo-eval/post-extract-cleanup.py
LOG=/opt/teleo-eval/logs/batch-extract-50.log
DB=/opt/teleo-eval/pipeline/pipeline.db
TOKEN=$(cat /opt/teleo-eval/secrets/forgejo-leo-token)
FORGEJO_URL="http://localhost:3000"
MAX=50
MAX_CLOSED=3 # zombie retry limit: skip source after this many closed PRs
COUNT=0
SUCCESS=0
FAILED=0
SKIPPED=0
# Lockfile to prevent concurrent runs
LOCKFILE="/tmp/batch-extract.lock"
if [ -f "$LOCKFILE" ]; then
pid=$(cat "$LOCKFILE" 2>/dev/null)
if kill -0 "$pid" 2>/dev/null; then
echo "[$(date)] SKIP: batch extract already running (pid $pid)" >> $LOG
exit 0
fi
rm -f "$LOCKFILE"
fi
echo $$ > "$LOCKFILE"
trap 'rm -f "$LOCKFILE"' EXIT
echo "[$(date)] Starting batch extraction of $MAX sources" >> $LOG
cd $REPO || exit 1
# Bug fix: don't swallow errors on critical git commands (Ganymede review)
git fetch origin main >> $LOG 2>&1 || { echo "[$(date)] FATAL: fetch origin main failed" >> $LOG; exit 1; }
git checkout -f main >> $LOG 2>&1 || { echo "[$(date)] FATAL: checkout main failed" >> $LOG; exit 1; }
git reset --hard origin/main >> $LOG 2>&1 || { echo "[$(date)] FATAL: reset --hard failed" >> $LOG; exit 1; }
# SHA canary: verify extract worktree matches origin/main (Ganymede review)
LOCAL_SHA=$(git rev-parse HEAD)
REMOTE_SHA=$(git rev-parse origin/main)
if [ "$LOCAL_SHA" != "$REMOTE_SHA" ]; then
echo "[$(date)] FATAL: extract worktree diverged from main ($LOCAL_SHA vs $REMOTE_SHA)" >> $LOG
exit 1
fi
# Pre-extraction cleanup: remove queue files that already exist in archive
# This runs on the MAIN worktree (not extract/) so deletions are committed to git.
# Prevents the "queue duplicate reappears after reset --hard" problem.
CLEANED=0
for qfile in $MAIN_REPO/inbox/queue/*.md; do
[ -f "$qfile" ] || continue
qbase=$(basename "$qfile")
if find "$MAIN_REPO/inbox/archive" -name "$qbase" 2>/dev/null | grep -q .; then
rm -f "$qfile"
CLEANED=$((CLEANED + 1))
fi
done
if [ "$CLEANED" -gt 0 ]; then
echo "[$(date)] Cleaned $CLEANED stale queue duplicates" >> $LOG
cd $MAIN_REPO
git add -A inbox/queue/ 2>/dev/null
git commit -m "pipeline: clean $CLEANED stale queue duplicates
Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>" 2>/dev/null
# Push with retry
for attempt in 1 2 3; do
git pull --rebase origin main 2>/dev/null
git push origin main 2>/dev/null && break
sleep 2
done
cd $REPO
git fetch origin main 2>/dev/null
git reset --hard origin/main 2>/dev/null
fi
# Get sources in queue
SOURCES=$(ls inbox/queue/*.md 2>/dev/null | head -$MAX)
# Batch fetch all remote branches once (Ganymede: 1 call instead of 84)
REMOTE_BRANCHES=$(git ls-remote --heads origin 2>/dev/null)
if [ $? -ne 0 ]; then
echo "[$(date)] ABORT: git ls-remote failed — remote unreachable, skipping cycle" >> $LOG
exit 0
fi
for SOURCE in $SOURCES; do
COUNT=$((COUNT + 1))
BASENAME=$(basename "$SOURCE" .md)
BRANCH="extract/$BASENAME"
# Skip conversation archives — valuable content enters through standalone sources,
# inline tags (SOURCE:/CLAIM:), and transcript review. Raw conversations produce
# low-quality claims with schema failures. (Epimetheus session 4)
if grep -q "^format: conversation" "$SOURCE" 2>/dev/null; then
# Move to archive instead of leaving in queue (prevents re-processing)
mv "$SOURCE" "$MAIN_REPO/inbox/archive/telegram/" 2>/dev/null
echo "[$(date)] [$COUNT/$MAX] ARCHIVE $BASENAME (conversation — skipped extraction)" >> $LOG
SKIPPED=$((SKIPPED + 1))
continue
fi
# Gate 1: Already in archive? Source was already processed — dedup (Ganymede)
if find "$MAIN_REPO/inbox/archive" -name "$BASENAME.md" 2>/dev/null | grep -q .; then
echo "[$(date)] [$COUNT/$MAX] SKIP $BASENAME (already in archive)" >> $LOG
# Delete the queue duplicate
rm -f "$MAIN_REPO/inbox/queue/$BASENAME.md" 2>/dev/null
SKIPPED=$((SKIPPED + 1))
continue
fi
# Gate 2: Branch exists on Forgejo? Extraction already in progress (cached lookup)
# Enhancement: 2-hour staleness check (Ganymede review) — if branch is >2h old
# and PR is unmergeable, close PR + delete branch and re-extract
if echo "$REMOTE_BRANCHES" | grep -q "refs/heads/$BRANCH$"; then
# Check branch age
BRANCH_SHA=$(echo "$REMOTE_BRANCHES" | grep "refs/heads/$BRANCH$" | awk '{print $1}')
BRANCH_AGE_EPOCH=$(git log -1 --format='%ct' "$BRANCH_SHA" 2>/dev/null || echo 0)
NOW_EPOCH=$(date +%s)
AGE_HOURS=$(( (NOW_EPOCH - BRANCH_AGE_EPOCH) / 3600 ))
if [ "$AGE_HOURS" -ge 2 ]; then
# Branch is stale — check if PR is mergeable
# Note: Forgejo head= filter is unreliable. Fetch all open PRs and filter locally.
PR_NUM=$(curl -sf "$FORGEJO_URL/api/v1/repos/teleo/teleo-codex/pulls?state=open&limit=50" \
-H "Authorization: token $TOKEN" | python3 -c "
import sys,json
prs=json.load(sys.stdin)
branch='$BRANCH'
matches=[p for p in prs if p['head']['ref']==branch]
print(matches[0]['number'] if matches else '')
" 2>/dev/null)
if [ -n "$PR_NUM" ]; then
PR_MERGEABLE=$(curl -sf "$FORGEJO_URL/api/v1/repos/teleo/teleo-codex/pulls/$PR_NUM" \
-H "Authorization: token $TOKEN" | python3 -c 'import sys,json; print(json.load(sys.stdin).get("mergeable","true"))' 2>/dev/null)
if [ "$PR_MERGEABLE" = "False" ] || [ "$PR_MERGEABLE" = "false" ]; then
echo "[$(date)] [$COUNT/$MAX] STALE: $BASENAME (${AGE_HOURS}h old, unmergeable PR #$PR_NUM) — closing + re-extracting" >> $LOG
# Close PR with audit comment
curl -sf -X POST "$FORGEJO_URL/api/v1/repos/teleo/teleo-codex/issues/$PR_NUM/comments" \
-H "Authorization: token $TOKEN" -H "Content-Type: application/json" \
-d '{"body":"Auto-closed: extraction branch stale >2h, conflict unresolvable. Source will be re-extracted from current main."}' > /dev/null 2>&1
curl -sf -X PATCH "$FORGEJO_URL/api/v1/repos/teleo/teleo-codex/pulls/$PR_NUM" \
-H "Authorization: token $TOKEN" -H "Content-Type: application/json" \
-d '{"state":"closed"}' > /dev/null 2>&1
# Delete remote branch
git push origin --delete "$BRANCH" 2>/dev/null
# Fall through to extraction below
else
echo "[$(date)] [$COUNT/$MAX] SKIP $BASENAME (branch exists ${AGE_HOURS}h, PR #$PR_NUM mergeable — waiting)" >> $LOG
SKIPPED=$((SKIPPED + 1))
continue
fi
else
# No PR found but branch exists — orphan branch, clean up
echo "[$(date)] [$COUNT/$MAX] STALE: $BASENAME (orphan branch ${AGE_HOURS}h, no PR) — deleting" >> $LOG
git push origin --delete "$BRANCH" 2>/dev/null
# Fall through to extraction
fi
else
echo "[$(date)] [$COUNT/$MAX] SKIP $BASENAME (branch exists — in progress, ${AGE_HOURS}h old)" >> $LOG
SKIPPED=$((SKIPPED + 1))
continue
fi
fi
# Gate 3: Check pipeline.db for zombie sources — too many closed PRs means
# the source keeps failing eval. Skip after MAX_CLOSED rejections. (Epimetheus)
if [ -f "$DB" ]; then
CLOSED_COUNT=$(sqlite3 "$DB" "SELECT COUNT(*) FROM prs WHERE branch = 'extract/$BASENAME' AND status = 'closed'" 2>/dev/null || echo 0)
if [ "$CLOSED_COUNT" -ge "$MAX_CLOSED" ]; then
echo "[$(date)] [$COUNT/$MAX] SKIP $BASENAME (zombie: $CLOSED_COUNT closed PRs >= $MAX_CLOSED limit)" >> $LOG
SKIPPED=$((SKIPPED + 1))
continue
fi
fi
# Gate 4: Check pipeline.db for active or recently closed PRs — prevents
# re-extraction waste when eval closes a PR and batch-extract runs again
# before the source is manually reviewed. 4h cooldown after closure.
if [ -f "$DB" ]; then
ACTIVE_COUNT=$(sqlite3 "$DB" "SELECT COUNT(*) FROM prs WHERE branch = 'extract/$BASENAME' AND status IN ('extracting','approved','merging')" 2>/dev/null || echo 0)
if [ "$ACTIVE_COUNT" -ge 1 ]; then
echo "[$(date)] [$COUNT/$MAX] SKIP $BASENAME (active PR exists)" >> $LOG
SKIPPED=$((SKIPPED + 1))
continue
fi
RECENT_CLOSED=$(sqlite3 "$DB" "SELECT COUNT(*) FROM prs WHERE branch = 'extract/$BASENAME' AND status = 'closed' AND created_at > datetime('now', '-4 hours')" 2>/dev/null || echo 0)
if [ "$RECENT_CLOSED" -ge 1 ]; then
echo "[$(date)] [$COUNT/$MAX] SKIP $BASENAME (recently closed PR — 4h cooldown)" >> $LOG
SKIPPED=$((SKIPPED + 1))
continue
fi
fi
echo "[$(date)] [$COUNT/$MAX] Processing $BASENAME" >> $LOG
# Reset to main (log errors — don't swallow)
git checkout -f main >> $LOG 2>&1 || { echo " -> SKIP (checkout main failed)" >> $LOG; SKIPPED=$((SKIPPED + 1)); continue; }
git fetch origin main >> $LOG 2>&1
git reset --hard origin/main >> $LOG 2>&1 || { echo " -> SKIP (reset failed)" >> $LOG; SKIPPED=$((SKIPPED + 1)); continue; }
# Clean stale remote branch (Leo's catch — prevents checkout conflicts)
git push origin --delete "$BRANCH" 2>/dev/null
# Create fresh branch
git branch -D "$BRANCH" 2>/dev/null
git checkout -b "$BRANCH" 2>/dev/null
if [ $? -ne 0 ]; then
echo " -> SKIP (branch creation failed)" >> $LOG
SKIPPED=$((SKIPPED + 1))
continue
fi
# Run extraction
python3 $EXTRACT "$SOURCE" --no-review >> $LOG 2>&1
EXTRACT_RC=$?
if [ $EXTRACT_RC -ne 0 ]; then
FAILED=$((FAILED + 1))
echo " -> FAILED (extract rc=$EXTRACT_RC)" >> $LOG
continue
fi
# Post-extraction cleanup
python3 $CLEANUP $REPO >> $LOG 2>&1
# Check if any files were created/modified
CHANGED=$(git status --porcelain | wc -l | tr -d " ")
if [ "$CHANGED" -eq 0 ]; then
echo " -> No changes (enrichment/null-result only)" >> $LOG
continue
fi
# Commit
git add -A
git commit -m "extract: $BASENAME
Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>" >> $LOG 2>&1
# Push
git push "http://leo:${TOKEN}@localhost:3000/teleo/teleo-codex.git" "$BRANCH" --force >> $LOG 2>&1
# Create PR (include prior art sidecar if available)
PRIOR_ART_FILE="${SOURCE}.prior-art"
PR_BODY=""
if [ -f "$PRIOR_ART_FILE" ]; then
# Escape JSON special chars in prior art content
PR_BODY=$(cat "$PRIOR_ART_FILE" | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read()))')
PR_BODY=${PR_BODY:1:-1} # Strip outer quotes from json.dumps
fi
curl -sf -X POST "http://localhost:3000/api/v1/repos/teleo/teleo-codex/pulls" \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"title\":\"extract: $BASENAME\",\"head\":\"$BRANCH\",\"base\":\"main\",\"body\":\"$PR_BODY\"}" >> /dev/null 2>&1
SUCCESS=$((SUCCESS + 1))
echo " -> SUCCESS ($CHANGED files)" >> $LOG
# Back to main
git checkout -f main >> $LOG 2>&1
# Rate limit
sleep 2
done
echo "[$(date)] Batch complete: $SUCCESS success, $FAILED failed, $SKIPPED skipped (already attempted)" >> $LOG
git checkout -f main >> $LOG 2>&1
git reset --hard origin/main >> $LOG 2>&1

View file

@ -63,7 +63,7 @@ def _build_search_text(content: str) -> str:
return " ".join(parts)
def _add_related_edges(claim_path: str, neighbor_titles: list[str]) -> bool:
def _add_related_edges(claim_path: str, neighbor_slugs: list[str]) -> bool:
"""Add related edges to a claim's frontmatter. Returns True if modified."""
try:
with open(claim_path) as f:
@ -87,10 +87,10 @@ def _add_related_edges(claim_path: str, neighbor_titles: list[str]) -> bool:
# Add new edges
added = []
for title in neighbor_titles:
if title.strip().lower() not in existing_lower:
added.append(title)
existing_lower.add(title.strip().lower())
for slug in neighbor_slugs:
if slug.strip().lower() not in existing_lower:
added.append(slug)
existing_lower.add(slug.strip().lower())
if not added:
return False
@ -167,27 +167,28 @@ def connect_new_claims(
stats["skipped_no_neighbors"] += 1
continue
# Extract neighbor titles
neighbor_titles = []
# Extract neighbor slugs (filename stems, not titles — reciprocal edges need resolvable names)
neighbor_slugs = []
for hit in hits:
payload = hit.get("payload", {})
title = payload.get("claim_title", "")
if title:
neighbor_titles.append(title)
claim_path_qdrant = payload.get("claim_path", "")
if claim_path_qdrant:
slug = claim_path_qdrant.rsplit("/", 1)[-1].replace(".md", "")
neighbor_slugs.append(slug)
if not neighbor_titles:
if not neighbor_slugs:
stats["skipped_no_neighbors"] += 1
continue
# Add edges to the new claim's frontmatter
if _add_related_edges(claim_path, neighbor_titles):
if _add_related_edges(claim_path, neighbor_slugs):
stats["connected"] += 1
stats["edges_added"] += len(neighbor_titles)
stats["edges_added"] += len(neighbor_slugs)
stats["connections"].append({
"claim": os.path.basename(claim_path),
"neighbors": neighbor_titles,
"neighbors": neighbor_slugs,
})
logger.info("Connected %s%d neighbors", os.path.basename(claim_path), len(neighbor_titles))
logger.info("Connected %s%d neighbors", os.path.basename(claim_path), len(neighbor_slugs))
else:
stats["skipped_no_neighbors"] += 1

View file

@ -493,6 +493,9 @@ async def _dispose_rejected_pr(conn, pr_number: int, eval_attempts: int, all_iss
async def evaluate_pr(conn, pr_number: int, tier: str = None) -> dict:
"""Evaluate a single PR. Returns result dict."""
from . import costs
pr_cost = 0.0
# Check eval attempt budget before claiming
row = conn.execute("SELECT eval_attempts FROM prs WHERE number = ?", (pr_number,)).fetchone()
eval_attempts = (row["eval_attempts"] or 0) if row else 0
@ -608,10 +611,8 @@ async def evaluate_pr(conn, pr_number: int, tier: str = None) -> dict:
json.dumps({"pr": pr_number, "tier": tier}),
)
else:
tier, triage_usage = await triage_pr(diff)
# Record triage cost
from . import costs
costs.record_usage(
tier, triage_usage, _triage_reason = await triage_pr(diff)
pr_cost += costs.record_usage(
conn, config.TRIAGE_MODEL, "eval_triage",
input_tokens=triage_usage.get("prompt_tokens", 0),
output_tokens=triage_usage.get("completion_tokens", 0),
@ -674,6 +675,8 @@ async def evaluate_pr(conn, pr_number: int, tier: str = None) -> dict:
# OpenRouter failure (timeout, error) — revert to open for retry.
# NOT a rate limit — don't trigger 15-min backoff, just skip this PR.
conn.execute("UPDATE prs SET status = 'open' WHERE number = ?", (pr_number,))
if pr_cost > 0:
conn.execute("UPDATE prs SET cost_usd = cost_usd + ? WHERE number = ?", (pr_cost, pr_number))
return {"pr": pr_number, "skipped": True, "reason": "openrouter_failed"}
domain_verdict = _parse_verdict(domain_review, agent)
@ -714,6 +717,15 @@ async def evaluate_pr(conn, pr_number: int, tier: str = None) -> dict:
# Disposition: check if this PR should be terminated or kept open
await _dispose_rejected_pr(conn, pr_number, eval_attempts, domain_issues)
if domain_verdict != "skipped":
pr_cost += costs.record_usage(
conn, config.EVAL_DOMAIN_MODEL, "eval_domain",
input_tokens=domain_usage.get("prompt_tokens", 0),
output_tokens=domain_usage.get("completion_tokens", 0),
backend="openrouter",
)
if pr_cost > 0:
conn.execute("UPDATE prs SET cost_usd = cost_usd + ? WHERE number = ?", (pr_cost, pr_number))
return {
"pr": pr_number,
"domain_verdict": domain_verdict,
@ -731,6 +743,15 @@ async def evaluate_pr(conn, pr_number: int, tier: str = None) -> dict:
if leo_review is None:
# DEEP: Opus rate limited (queue for later). STANDARD: OpenRouter failed (skip, retry next cycle).
conn.execute("UPDATE prs SET status = 'open' WHERE number = ?", (pr_number,))
if domain_verdict != "skipped":
pr_cost += costs.record_usage(
conn, config.EVAL_DOMAIN_MODEL, "eval_domain",
input_tokens=domain_usage.get("prompt_tokens", 0),
output_tokens=domain_usage.get("completion_tokens", 0),
backend="openrouter",
)
if pr_cost > 0:
conn.execute("UPDATE prs SET cost_usd = cost_usd + ? WHERE number = ?", (pr_cost, pr_number))
reason = "opus_rate_limited" if tier == "DEEP" else "openrouter_failed"
return {"pr": pr_number, "skipped": True, "reason": reason}
@ -834,10 +855,8 @@ async def evaluate_pr(conn, pr_number: int, tier: str = None) -> dict:
await _dispose_rejected_pr(conn, pr_number, eval_attempts, all_issues)
# Record cost (only for reviews that actually ran)
from . import costs
if domain_verdict != "skipped":
costs.record_usage(
pr_cost += costs.record_usage(
conn, config.EVAL_DOMAIN_MODEL, "eval_domain",
input_tokens=domain_usage.get("prompt_tokens", 0),
output_tokens=domain_usage.get("completion_tokens", 0),
@ -845,15 +864,23 @@ async def evaluate_pr(conn, pr_number: int, tier: str = None) -> dict:
)
if leo_verdict not in ("skipped",):
if tier == "DEEP":
costs.record_usage(conn, config.EVAL_LEO_MODEL, "eval_leo", backend="max")
pr_cost += costs.record_usage(
conn, config.EVAL_LEO_MODEL, "eval_leo",
input_tokens=leo_usage.get("prompt_tokens", 0),
output_tokens=leo_usage.get("completion_tokens", 0),
backend="max",
)
else:
costs.record_usage(
pr_cost += costs.record_usage(
conn, config.EVAL_LEO_STANDARD_MODEL, "eval_leo",
input_tokens=leo_usage.get("prompt_tokens", 0),
output_tokens=leo_usage.get("completion_tokens", 0),
backend="openrouter",
)
if pr_cost > 0:
conn.execute("UPDATE prs SET cost_usd = cost_usd + ? WHERE number = ?", (pr_cost, pr_number))
return {
"pr": pr_number,
"tier": tier,

View file

@ -37,6 +37,7 @@ from .domains import agent_for_domain
from .extraction_prompt import build_extraction_prompt
from .forgejo import api as forgejo_api
from .llm import openrouter_call
from .connect import connect_new_claims
from .post_extract import load_existing_claims_from_repo, validate_and_fix_claims
from .worktree_lock import async_main_worktree_lock
@ -225,7 +226,29 @@ def _build_claim_content(claim: dict, agent: str) -> str:
body = claim.get("body", "")
scope = claim.get("scope", "")
sourcer = claim.get("sourcer", "")
related = claim.get("related_claims", [])
related_claims = claim.get("related_claims", [])
connections = claim.get("connections", [])
edge_fields = {"supports": [], "challenges": [], "related": []}
for conn in connections:
target = conn.get("target", "")
rel = conn.get("relationship", "related")
if target and rel in edge_fields:
target = target.replace(".md", "")
if target not in edge_fields[rel]:
edge_fields[rel].append(target)
for r in related_claims[:5]:
r_clean = r.replace(".md", "")
if r_clean not in edge_fields["related"]:
edge_fields["related"].append(r_clean)
edge_lines = []
for edge_type in ("supports", "challenges", "related"):
targets = edge_fields[edge_type]
if targets:
edge_lines.append(f"{edge_type}:")
for t in targets:
edge_lines.append(f" - {t}")
lines = [
"---",
@ -242,10 +265,7 @@ def _build_claim_content(claim: dict, agent: str) -> str:
lines.append(f"scope: {scope}")
if sourcer:
lines.append(f'sourcer: "{sourcer}"')
if related:
lines.append("related_claims:")
for r in related:
lines.append(f' - "[[{r}]]"')
lines.extend(edge_lines)
lines.append("---")
lines.append("")
lines.append(f"# {title}")
@ -456,6 +476,19 @@ async def _extract_one_source(
await _archive_source(source_path, domain, "null-result")
return 0, 0
# Post-write: connect new claims to existing KB via vector search (non-fatal)
claim_paths = [str(worktree / f) for f in files_written if f.startswith("domains/")]
if claim_paths:
try:
connect_stats = connect_new_claims(claim_paths)
if connect_stats["connected"] > 0:
logger.info(
"Extract-connect: %d/%d claims → %d edges",
connect_stats["connected"], len(claim_paths), connect_stats["edges_added"],
)
except Exception:
logger.warning("Extract-connect failed (non-fatal)", exc_info=True)
# Stage and commit
for f in files_written:
await _git("add", f, cwd=str(EXTRACT_WORKTREE))

64
ops/prune-branches.sh Executable file
View file

@ -0,0 +1,64 @@
#!/usr/bin/env bash
# prune-branches.sh — Delete merged remote branches older than N days.
# Usage: ./prune-branches.sh [--days 14] [--remote forgejo] [--execute]
# Default: dry-run (shows what would be deleted). Pass --execute to actually delete.
set -euo pipefail
DAYS=14
REMOTE="forgejo"
EXECUTE=false
while [ $# -gt 0 ]; do
case "$1" in
--days) DAYS="$2"; shift 2 ;;
--remote) REMOTE="$2"; shift 2 ;;
--execute) EXECUTE=true; shift ;;
--help|-h) echo "Usage: $0 [--days N] [--remote name] [--execute]"; exit 0 ;;
*) echo "Unknown arg: $1"; exit 1 ;;
esac
done
CUTOFF=$(date -v-${DAYS}d +%Y-%m-%d 2>/dev/null || date -d "-${DAYS} days" +%Y-%m-%d)
PROTECTED="main|HEAD.*"
echo "Scanning $REMOTE for merged branches older than $CUTOFF..."
echo ""
git fetch "$REMOTE" --prune --quiet
COUNT=0
DELETE_COUNT=0
while IFS= read -r branch; do
branch=$(echo "$branch" | sed 's/^[[:space:]]*//')
[ -z "$branch" ] && continue
echo "$branch" | grep -q ' -> ' && continue
short="${branch#$REMOTE/}"
echo "$short" | grep -qE "^($PROTECTED)$" && continue
last_date=$(git log -1 --format='%ai' "$branch" 2>/dev/null | cut -d' ' -f1)
[ -z "$last_date" ] && continue
COUNT=$((COUNT + 1))
if [[ "$last_date" < "$CUTOFF" ]]; then
if ! git merge-base --is-ancestor "$branch" "$REMOTE/main" 2>/dev/null; then
echo " SKIP (unmerged): $short ($last_date)"
continue
fi
if $EXECUTE; then
echo " DELETE: $short ($last_date)"
git push "$REMOTE" --delete "$short" 2>&1 && DELETE_COUNT=$((DELETE_COUNT + 1)) || echo " FAILED: $short"
else
echo " WOULD DELETE: $short ($last_date)"
DELETE_COUNT=$((DELETE_COUNT + 1))
fi
fi
done < <(git branch -r | grep "^ $REMOTE/")
echo ""
if $EXECUTE; then
echo "Deleted $DELETE_COUNT of $COUNT branches."
else
echo "Would delete $DELETE_COUNT of $COUNT branches. Run with --execute to proceed."
fi

View file

@ -37,7 +37,7 @@ When any agent changes a file format, database table, API response shape, or ser
| Format | Schema | Producers | Consumers | Pipeline |
|---|---|---|---|---|
| Claim | `schemas/claim.md` | All proposers (Rio, Clay, Theseus, Vida, Astra) | Leo (eval), all agents (beliefs), visitors | `extract-graph-data.py` |
| Source | `schemas/source.md` | All proposers, Epimetheus (pipeline) | Proposers (extraction), Epimetheus (pipeline) | `extract-cron.sh` |
| Source | `schemas/source.md` | All proposers, Epimetheus (pipeline) | Proposers (extraction), Epimetheus (pipeline) | `lib/extract.py` |
| Entity | `schemas/entity.md` | Domain agents | All agents (references), visitors | `extract-graph-data.py` |
| Belief | `schemas/belief.md` | Each agent (own file) | Leo (review), other agents (cross-ref) | None currently |
| Position | `schemas/position.md` | Each agent (own file) | Leo (review), visitors | None currently |