Commit graph

85 commits

Author SHA1 Message Date
f25a4093c2 fix: replace broken _rebase_and_push call with cherry-pick in conflict retry
_retry_conflict_prs called _rebase_and_push which was never defined,
causing NameError on every conflict retry. Now uses _cherry_pick_onto_main
consistent with the primary merge path.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 13:18:30 +01:00
686ef3fd7f Replace rebase-retry with cherry-pick merge mechanism
- _cherry_pick_onto_main replaces _rebase_and_push: creates fresh branch
  from origin/main, cherry-picks extraction commits, force-pushes
- Eliminates ~23% merge failure rate from rebase race conditions
- Agent branch protection: PIPELINE_OWNED_PREFIXES filter in SQL prevents
  auto-merge of agent-owned branches (theseus/*, rio/*, etc.)
- Empty-commit handling: skips already-merged content gracefully
- Entity conflict auto-resolution preserved for cherry-pick path
- Post-pick evidence dedup runs as safety net (same as post-rebase)
- Separate fetch calls for main and branch (fixes long branch name issue)

Fixes: PRs #2141, #157, #2142, #2180 (agent branch orphaning)
Fixes: ~23% merge failure rate (rebase race condition)
Related: PRs #1751, #1752 (enrichment dedup shares root cause)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 13:18:26 +01:00
f43f8f923f fix: enrichment idempotency — three-layer dedup prevents duplicate evidence blocks
Layer 1: Insertion-time dedup in openrouter-extract-v2.py — skip if source_slug
already appears in claim content.
Layer 2: Insertion-time dedup in entity_batch.py — skip if PR number already
enriched this claim.
Layer 3: Post-rebase dedup in merge.py — scan rebased files for duplicate
evidence blocks (same source reference) and remove them before force-push.

Root cause: multiple enrichment branches modify the same claim at the same
insertion point. When rebased sequentially, evidence blocks are duplicated.
(Leo: PRs #1751, #1752)

lib/dedup.py: standalone module — parses evidence headers, deduplicates by
source key, preserves trailing content (Relevant Notes, Topics sections).
9 tests covering all patterns including the real PR #1751 duplication case.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 13:18:23 +01:00
ad48d7384e Merge pull request 'feat: two-pass retrieval with sort order and graph expansion' (#5) from epimetheus/two-pass-retrieval into main
Some checks are pending
CI / lint-and-test (push) Waiting to run
2026-03-30 11:32:32 +00:00
b92d2af1ac Merge pull request 'feat: atomic extract-and-connect + stale PR monitor + response audit' (#4) from epimetheus/atomic-connect-and-stale-monitor into main
Some checks are pending
CI / lint-and-test (push) Waiting to run
2026-03-30 11:03:34 +00:00
e17e6c25db feat: two-pass retrieval with sort order and graph expansion
Some checks failed
CI / lint-and-test (pull_request) Has been cancelled
lib/search.py — shared search library:
- Pass 1 (default): top 5 from Qdrant, score >= 0.70, no expansion
- Pass 2 (expand=True): next 5 via offset=5, score >= 0.60, plus
  graph expansion from YAML frontmatter edges. Hard cap 10 total.
- Sort order: cosine desc → challenged_by → other graph-expanded
- result_type internal tag for stable sort (direct/challenge/graph)
- Module-level constants for easy threshold tuning post-calibration
- Structural file exclusion (_map.md, _overview.md)
- Within-vector dedup via _dedup_hits()

Caller updates:
- kb_retrieval.py: retrieve_vector_context() calls search(expand=True)
- diagnostics/app.py: search endpoint passes expand query param
- Argus imports from lib/search.py via sys.path (no longer owns search)

Tests: 5 new tests covering pass1-only, pass2 expansion, hard cap,
sort order, challenges-before-other-expansion.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 22:34:45 +00:00
5f554bc2de feat: atomic extract-and-connect + stale PR monitor + response audit
Some checks failed
CI / lint-and-test (pull_request) Has been cancelled
Atomic extract-and-connect (lib/connect.py):
- After extraction writes claim files, each new claim is embedded via
  OpenRouter, searched against Qdrant, and top-5 neighbors (cosine > 0.55)
  are added as `related` edges in the claim's frontmatter
- Edges written on NEW claim only — avoids merge conflicts
- Cross-domain connections enabled, non-fatal on Qdrant failure
- Wired into openrouter-extract-v2.py post-extraction step

Stale PR monitor (lib/stale_pr.py):
- Every watchdog cycle checks open extract/* PRs
- If open >30 min AND 0 claim files → auto-close with comment
- After 2 stale closures → marks source as extraction_failed
- Wired into watchdog.py as check #6

Response audit system:
- response_audit table (migration v8), persistent audit conn in bot.py
- 90-day retention cleanup, tool_calls JSON column
- Confidence tag stripping, systemd ReadWritePaths for pipeline.db

Supporting infrastructure:
- reweave.py: nightly edge reconnection for orphan claims
- reconcile-sources.py: source status reconciliation
- backfill-domains.py: domain classification backfill
- ops/reconcile-source-status.sh: operational reconciliation script
- Attribution improvements, post-extract enrichments, merge improvements

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 22:34:20 +00:00
0457c49094 fix: zombie retry loop + cost tracking
Gate 3 in batch-extract-50.sh: query pipeline.db for closed PRs before
re-extracting. Sources with >=3 closed PRs are skipped (zombie protection).

Cost tracking: openrouter_call() now returns (text, usage) tuple with
prompt_tokens and completion_tokens from the OpenRouter API response.
All callers updated to unpack and pass tokens to costs.record_usage().
Added missing triage cost recording. Fixed batch domain review recording
cost once per batch instead of once per PR.

Pentagon-Agent: Epimetheus <0144398e-4ed3-4fe2-95a3-3d72e1abf887>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:29:58 +00:00
89692fda2d feat: embed-on-merge — auto-index new claims into Qdrant after PR merge
After a PR merges successfully, _embed_merged_claims() diffs the merged SHA
against its parent to find new/changed .md files in knowledge directories
(domains/, core/, foundations/, decisions/, entities/). Each file is embedded
via embed-claims.py --file (OpenRouter, text-embedding-3-small).

Non-fatal: embedding failure logs a warning but does not block the merge
pipeline. This keeps vector search current without requiring manual re-embeds.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-26 17:53:18 +00:00
f5b27ccd73 feat: Qdrant vector search — bulk embed script + OpenRouter embeddings
- embed-claims.py: bulk embeds all claims/decisions/entities into Qdrant
  via OpenRouter (openai/text-embedding-3-small, 1536 dims)
- diagnostics/app.py: search endpoint switched from OpenAI direct to
  OpenRouter (same key as LLM calls, no new credentials)
- Qdrant running on VPS (Docker, port 6333, persistent storage)
- Collection: teleo-claims, cosine distance, 1536 dims

854 files to embed. Bulk backfill running.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-26 17:44:34 +00:00
47fa33fd53 feat: source author backfill — credits intellectual foundations of KB
Parses source: frontmatter across 616 claims, matches against entity
files + manual author map, credits sourcer_count. 33 authors matched,
8 new contributor entries created.

Bostrom (9), Shapiro (8), Hanson (6), Conitzer (7) etc. now visible
on the leaderboard as sourcers.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-26 15:26:04 +00:00
2b49b17eb2 doc: label backfill as one-shot, not cron (Ganymede review)
Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-26 15:09:47 +00:00
305445b164 feat: domain breakdown on dashboard — contributions by domain with top contributors
New _domain_breakdown() function cross-references merged PRs with
contributor principals. Dashboard shows per-domain knowledge PR counts
and top 3 contributors for each domain. API: GET /api/domains returns
full breakdown.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-26 15:05:48 +00:00
ae1cce730c feat: CI backfill script — reclassifies 614 PRs, attributes sourcer to m3taversal
484 knowledge PRs, 130 pipeline PRs (excluded from CI).
m3taversal credited as sourcer for all knowledge PRs.
Principal roll-up: 540 claims, CI 75.4.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-26 15:02:27 +00:00
4b5c5841ce doc: mixed PR classification priority note (Ganymede review)
Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-26 14:57:11 +00:00
cfb80d3496 feat: CI scoring overhaul — principal roll-up, commit-type filter, new weights
Step 1: principal column + commit_type column in pipeline.db. Static map
populates principal for local agents (rio→m3taversal etc.). VPS agents
(epimetheus, argus) have no principal.

Step 2: _classify_commit_type in merge.py. Pipeline commits (inbox/,
entities/, agents/) get commit_type='pipeline' and skip CI attribution
entirely. Knowledge commits (domains/, core/, foundations/, decisions/)
get full attribution.

Step 3 (Argus): Dashboard has dual view — by-principal (default,
governance) and by-agent (drill-down). Already implemented by Argus.

CI weights updated (Cory-approved):
- Challenger: 0.35 (was 0.20)
- Synthesizer: 0.25 (was 0.15)
- Reviewer: 0.20 (was 0.10)
- Sourcer: 0.15 (unchanged)
- Extractor: 0.05 (was 0.40)

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-26 14:53:54 +00:00
1dfc6dcc5c feat: author handle domain signal + conversation skip at source (Ganymede)
1. Author handle map: known X accounts (MetaDAO, Anthropic, SpaceX etc.)
   count as 1 keyword match toward domain routing threshold. Lightweight,
   no URL parsing.

2. Conversation archives now write to conversations/ subdir instead of
   top-level staging dir. The cron only moves top-level *.md to queue,
   so conversations never enter the extraction pipeline. Skip happens
   at write time, not at batch-extract read time — eliminates wasted I/O
   every 15 minutes.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-26 14:39:15 +00:00
b5aabe0364 feat: content classification — domain routing + sub-tags for sources
All source creation functions now classify content by domain and
sub-topic instead of hardcoding internet-finance.

Domain routing: keyword matching (2+ hits) routes to ai-alignment,
health, space-development, entertainment. Default: internet-finance.

Sub-tags for internet-finance: futarchy, ownership-coins, defi,
governance, market-analysis, crypto-infra. Added to source frontmatter
tags array for granular filtering.

Applied to: standalone sources, inline SOURCE:/CLAIM:, conversation
archives, research archives.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-26 14:34:33 +00:00
0854375fd0 fix: skip format: conversation in extraction — archive directly instead
Conversation archives produce low-quality claims (26x schema failures,
22x near-duplicates in 24h). Valuable content from conversations now
enters through three other paths:
1. Standalone sources (URLs shared → x-article/x-tweet files)
2. Inline tags (SOURCE:/CLAIM: → curated source files)
3. Transcript review (1-hour JSONL dumps → periodic safety net)

Conversations moved to inbox/archive/telegram/ for provenance without
burning extraction cycles.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-26 12:02:57 +00:00
1019602eec fix: transcript dump uses append-only JSONL, not full rewrite (Ganymede)
Each dump was rewriting the full accumulated history — growing unbounded.
Now: append-only JSONL (one line per message), only new entries since
last dump. One file per chat per day. No dedup needed downstream.

Also verified ARCHIVE_DIR path is correct (staging dir, not worktree).

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-25 13:39:43 +00:00
66bc742979 feat: full transcript archival + SOURCE:/CLAIM: inline tags
Transcript system:
- All messages in all chats captured to chat_transcripts store
- 1-hour dump job writes per-chat JSON to /opt/teleo-eval/transcripts/
- Includes internal reasoning (KB matches, searches, learnings)
- Transcripts accumulate over session (no clear on dump)
- Per-chat directories: transcripts/{chat-slug}/{date-hour}.json

Inline contribution tags:
- SOURCE: creates inbox source file with verbatim user content
- CLAIM: creates draft claim file attributed to contributor
- Both strip tag from displayed response
- Full user message preserved verbatim (Rio decides context, can't alter)

Also: multi-URL processing (up to 5 per message)

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-25 13:35:10 +00:00
0759655688 fix: process all URLs in a message, not just the first
When a user shared two X links in one message (sjdedic + knimkar),
only the first got a standalone source. Now processes up to 5 URLs
per message, each getting its own standalone source file.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-25 13:21:26 +00:00
102d97859c fix: auto-research sends follow-up message with findings
When Opus triggers RESEARCH: tag, the search ran silently and archived
results but never sent a follow-up. User saw "let me look into it" then
nothing. Now: searches, sends concise summary of top 5 results back to
the chat, then archives for pipeline.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-25 13:14:38 +00:00
e4d7ca42ac fix: Gate 2 PR lookup — Forgejo head= filter returns wrong PR
Forgejo API head=teleo:$BRANCH filter is unreliable — returns unrelated
PRs. All 13 queued sources were matching PR #1838 (Leo's research) instead
of their own PRs. Fixed: fetch all open PRs and filter locally by
head.ref match.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-25 11:09:24 +00:00
02c86e9050 fix: split long messages for Telegram 4096 char limit
Bot crashed with "Message is too long" when sending full DP-00002 text
(8K+ chars). Now splits on paragraph boundaries. Also prevents silent
message drops from unhandled BadRequest exceptions.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-24 16:22:53 +00:00
458cd7dfda fix: Opus now knows research results are from a live search it ran
Bot said "I don't have the ability to run live X searches" despite Haiku
finding 10 tweets. Two issues: (1) prompt section header didn't make clear
these were LIVE results, (2) learnings taught deflection ("say drop links
here" instead of acknowledging search capability).

Fixed: section header now says "LIVE X Search Results (you just searched
for X — cite these directly)". Learnings updated to acknowledge search
capability. Stale Robin Hanson learning removed again (re-synced from git).

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-24 16:19:52 +00:00
7232755d11 fix: decision record body cap 2K → 8K — proposals were truncating mid-text
User asked for full DP-00002 text, bot served it but cut off at 2000 chars
with "That's where my copy cuts off." Full proposals are 6K+. Increased
index, sanitize, and prompt caps to 8K for decision records.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-24 16:18:08 +00:00
c2ff4996e3 refine: x-tweet vs x-article source_type, 500ms rate limit (Ganymede)
- Distinguish tweets (source_type: x-tweet, format: social-media) from
  articles (source_type: x-article, format: article) based on content
  length and article marker presence
- 500ms delay between fetch_from_url calls in research path
- Keep standalone sources pure (no Rio analysis — circular dependency)

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-24 16:00:19 +00:00
b3c635290f feat: full content fetch for research + standalone source for shared URLs
Two fixes for article ingestion:

1. Research path: top 5 search results now get full content via
   fetch_from_url before archiving. Articles get full text, not just
   search snippets. Threads get complete text.

2. URL sharing: when a user shares a URL, creates a standalone source
   file (type: source, format: article) separate from the conversation
   archive. Enters extraction pipeline as proper source material,
   attributed to the TG user who shared it.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-24 15:57:58 +00:00
8ff4784fcb fix: dashboard queries Forgejo directly for PR backlog, not just DB
Dashboard showed 1 conflict when Forgejo had 30 open PRs because it
only queried pipeline.db — which misses all agent-created PRs (Rio,
Leo, etc.). Now queries Forgejo API for authoritative open/unmergeable
counts. Falls back to DB if Forgejo unreachable.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-24 15:12:58 +00:00
a19db22b16 bump: chat-level history to 30 exchanges (~6K tokens)
Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-24 15:03:11 +00:00
bb3b033b57 fix: separate history caps — chat-level 10, per-user 5 (Ganymede review)
Group chats with 3 users contributing 2 messages each = 6 exchanges,
exceeding the old shared cap of 5. Chat-level now holds 10 exchanges
(~2K extra tokens, within prompt budget).

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-24 14:54:36 +00:00
60c92d5c19 fix: group chat history shared across users — bot no longer loses context
History was keyed by (chat_id, user_id). In group chats, when Jordan
asked about Solomon buyback and Cory followed up, the bot couldn't see
Jordan's exchange. Now maintains chat-level history (chat_id, 0) that
captures all exchanges with usernames. Group context visible to all
follow-up responses.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-24 14:51:03 +00:00
d33ddd9f3d fix: fixer GC now closes PRs on Forgejo + deletes branches, not just DB
Root cause of 5-day pipeline stall: fixer GC marked PRs as closed in DB
but never synced to Forgejo. Branches stayed alive on remote, blocking
Gate 2 in batch-extract (branch exists → skip forever).

Now: GC fetches PR numbers, posts audit comment, closes on Forgejo,
deletes remote branch, THEN updates DB. Same pattern as _terminate_pr
in evaluate.py.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-24 14:37:50 +00:00
0bedc43c94 fix: silent checkout failure + Gate 2 staleness check (Ganymede review)
Bug 1: 2>/dev/null on critical git commands swallowed checkout failures.
Branches created from stale base (670 commits behind), carrying 56+
noise files. Fix: log all git output, fail hard on errors, add SHA
canary to verify worktree matches origin/main.

Bug 2: Gate 2 had no staleness check. Stale conflict branches blocked
re-extraction forever (0 extractions for 5 days). Fix: 2-hour threshold.
If branch >2h old and PR unmergeable, auto-close PR with audit comment,
delete branch, and re-extract. Also handles orphan branches (no PR).

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-24 14:25:51 +00:00
2ec4c445b1 fix: use x_client.fetch_from_url for X URLs in archive pipeline
_fetch_url_content was doing raw HTTP GET on X URLs which returns
JavaScript, not article content. Now routes X/Twitter URLs through
Ben's API via x_client.fetch_from_url which returns structured
article content (contents[] array with typed blocks).

Article content gets included in the archived source file so the
extraction pipeline has the actual content, not just Rio's response.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-24 14:12:31 +00:00
76f13de681 fix: delete existing branch before re-creating in decision extractor
Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-24 11:43:27 +00:00
d67d36b409 fix: decision extractor uses extract worktree + PR flow
Was writing directly to main worktree where daemon race condition wiped
files. Now: syncs extract worktree to main, creates branch, writes
records, commits, pushes, opens Forgejo PR. Same pattern as batch-extract.

Also checks both main and extract worktrees for existing records.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-24 02:50:12 +00:00
9267351aba fix: 7-day TTL on dated learnings + block availability learnings
Stale learning ("I don't have Robin Hanson data") overrode real KB data.
Ganymede review: dated entries expire after 7 days. Permanent entries
(communication style, identity) are undated and always included.

Prompt guard: "NEVER save a learning about what data you do or don't have"
prevents the bot from writing availability claims that go stale.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-23 18:07:46 +00:00
6c6cd0d14e feat: support fundraise record_type alongside decision_market
LLM now classifies proposals as either decision_market (governance votes)
or fundraise (ICO/launch capital raises). Both handled by same extractor.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-23 18:04:30 +00:00
e1934b30ae fix: API key path + YAML error handling in decision extractor
Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-23 17:59:11 +00:00
a292ab75c2 feat: decision record extractor — proposal sources → decisions/ with full text
Reads event_type: proposal sources from archive, calls Sonnet for
summary/significance/KB-connections, writes decision records with
full verbatim proposal text + structured analysis on top.

224 proposal sources archived, 0 processed. This closes the gap.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-23 17:55:46 +00:00
28be7555b1 fix: top 3 entities get full body in prompt, not just top 1
When two related entities match (advisor hire + research grant), both need
full content so Opus can distinguish them and serve the right one.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-23 17:44:51 +00:00
f77fd229d6 fix: stop word filtering in entity scoring — common words polluted rankings
'the', 'full', 'text', 'proposal' etc. were matching irrelevant entities.
Robin Hanson record ranked #2 behind Drift because Drift matched 'the' and
'proposal' in its name. Now only meaningful tokens (>=3 chars, not stop
words) contribute to entity scoring.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-23 17:44:06 +00:00
089b4609d5 fix: score + rank entities, limit to top 5, full body for decisions
Before: "Robin Hanson MetaDAO proposal" returned 34 entities (39K chars)
with the target record buried at position 13. No relevance scoring.

After: entities scored by query token overlap (name 3x, alias 1x,
bigram 5x), limited to top 5 results. Decision records get full body
(2K chars) instead of 500-char truncation. Top result gets 2K in prompt,
rest get 500.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-23 17:38:10 +00:00
3ed0f20fa1 fix: index parent_entity as alias for decision records (Ganymede review)
MetaDAO queries now surface MetaDAO's decision records because
parent_entity: "[[metadao]]" is stripped and added to the alias set.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-23 17:31:54 +00:00
425e7a1bac fix: index decisions/ as entities so decision records reach the bot prompt
Root cause: decision records have type: decision, but the entity indexer
only accepted type: entity and only scanned entities/. The claim indexer
scanned decisions/ but filtered out non-claim types. Result: decision
records fell through both indexes entirely — invisible to the bot.

Fix: add decisions/ to entity indexer scan paths, accept type: decision
alongside type: entity, include summary/proposer in search aliases.
Remove decisions/ from claim indexer (was silently dropping them anyway).

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-23 17:28:30 +00:00
c7c71ec9d1 epimetheus: fix double research message + add decisions/ to KB retrieval
1. handle_research gets silent=True param. RESEARCH: tag triggers use
   silent mode — archives tweets but posts no follow-up message.
   Prevents "Queued N tweets" after Opus already responded.

2. KB retrieval now searches decisions/ directory alongside domains/,
   core/, foundations/. Decision records (Robin Hanson proposal, etc.)
   are now findable by the bot.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-23 16:59:23 +00:00
c59db5812f epimetheus: fix article content parsing — contents[] array, not text field
Article endpoint returns body in "contents" array of typed blocks
(unstyled, header-two, markdown, list-item, blockquote, etc).
Was looking for article.text which is empty. Now parses all block types
into readable text. Also extracts engagement stats (likes, views).

Fixes: "Claude + Obsidian" article returned title but empty text.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-23 15:30:59 +00:00
bcbe54a0a3 epimetheus: consolidated X API client (x_client.py replaces x_search.py)
Clean, documented interface to twitterapi.io for all agents:
- get_tweet(id) — fetch any tweet by ID, any age
- get_article(id) — fetch X long-form articles
- search_tweets(query) — keyword search for research
- get_user_tweets(username) — user's recent tweets (research sessions)
- fetch_from_url(url) — smart dispatcher: tweet → article → placeholder

Shared by Telegram bot + research sessions. Documented endpoints,
costs, rate limits. Replaces ad-hoc x_search.py.

Pentagon-Agent: Epimetheus <3D35839A-7722-4740-B93D-51157F7D5E70>
2026-03-23 15:26:10 +00:00