For Agents

Reverse-chronological session log. Newest entries at top, grouped by date (## YYYY-MM-DD). Each bullet: one piece of work, short summary, wikilinks to docs touched. Updated by obsidian-documenter on every project doc write. Read by historian at bootstrap.

2026-06-09

  • Two verified Phase 2 findings documented (current state, NOT decisions). (1) No Anthropic embeddings API (verified via claude-api skill) — Messages API is generation-only, so the article-vectorization step CANNOT use a Claude OAuth token; embeddings must come from OpenAI text-embedding-3-small (dim≤1024) or Voyage voyage-3-lite (Anthropic’s recommended partner). A Claude token can only serve a GENERATION step (e.g. entity salience). (2) “Who is the article about” has no data pipeline — verified in code: gkg.rs parses persons/orgs but ingest.rs:171 matches_priority uses them only for a boolean then discards; PreparedArticle (ingest.rs:26) has no entity fields; articles (0001_fastpath.sql) has no entity columns; no article_mentions table anywhere (grep=0) despite spec §6 defining it; the drafted Phase 2 plan writes Qdrant entity_ids: [] (lines 1637/1698) and builds a keyword index on that empty field (line 1055) → entity-filtered retrieval (Elon-tweet use case) is non-functional. Also recorded HIGH-severity drafted-plan bugs to fix on execution: unbounded retry storm (no attempt_count/terminal stop, status IN ('detected','failed')), rows stranded in enriching on error/crash (no sweeper/lease reclaim), news.enriched emitted on confirm-searchable fail (only warn!, violates spec §8), bitemporal clock split (Qdrant payload knowledge_ts = Utc::now() line 1635 vs Postgres transaction_timestamp() line 1664); + cost_cap_usd_cents never enforced, fake semaphore (sequential loop, no spawn), enrich_pool not capped at 5, no total timeout on the embed HTTP call, subject_token duplicated (DRY) — dionysus-phase2-findings, dionysus
  • Post-build security/correctness/DRY audit (after Phase 1 was committed + pushed) — a 3-lens adversarial pass found + fixed REAL issues, pushed to wowjeeez/dionysus @ 21332bd, 37 tests still green, live-smoke re-validated (articles=1749 relayed=1749). Fixes: HIGH prod bug — relay drained only one batch_size (100) per cycle while each poll ingests ~1200-1750 articles → unbounded outbox backlog (1204→100); now drains-to-empty per cycle (1749→1749). Security: GDELT is http-only (its data server has a broken/mismatched TLS cert — an audit agent’s “upgrade to https” would have broken ingest, caught by manual curl); validate_gkg_url host-allowlist (data.gdeltproject.org) + redirect::Policy::limited(0) (MitM/SSRF); 512 MiB decompression cap in unzip_single (OOM-DoS); NATS subject-injection slug (subject_token(), raw source_common_name had ./*/>). Gaps: MissedTickBehavior::Skip (no poll-storm), detect_latency on error cycles (outcome= attr), gdelt_file_ts from filename, prepare skips non-https junk URLs, startup warns on empty priority_terms. DRY: extracted dev-only dionysus-testsupport crate (fresh_pool/priority_off/start_nats, PG_IMAGE_TAG pinned once) — Cargo dev-dep cycle is fine, not in release binary. Recorded 5 deferred Phase-2 hardening items (stream-unzip+field caps, deny.toml/cargo-audit CI, relay-tx-held-across-publish, checkpoint pre-check, RFC-4122 article_id bits) — dionysus-phase1-ingest-skeleton, dionysus, dionysus-architecture-decisions
  • Phase 1 (Ingest Skeleton) COMPLETE — built, reviewed, committed (final commit 23c31c9). All-Rust walking skeleton: GDELT 2.0 poll → GKG 2.1 parse → bitemporal-Postgres fast-path persist + transactional outbox in one tx → single-leader relay → news.detected on NATS JetStream → OTel traces+metrics. 37 tests pass; live-smoke-verified (1204 ingested, 100 relayed). Created the build report capturing 8 durable reusable learnings the review caught (Supabase pgcrypto-denied, testcontainers PG11 default, sqlx Migrator self-locks, URL percent-encoding equivalence, verified GKG 2.1 column indices, async-nats double-await, OTel dual-provider, bitemporal single knowledge-clock) — dionysus-phase1-ingest-skeleton
  • Flipped overview + decision record from “design phase, no code” to Phase 1 complete (status/current); added a Phase 1 success banner + a Phase 2+ backlog (slow path, enrichment SCD-2, signals, entity resolution, as_of API, CC-NEWS backfill, reconcile sweeper, deploy wiring, + small follow-ups); corrected the design-time sqlx advisory-lock assumption inline — dionysus, dionysus-architecture-decisions

2026-06-08

  • Updated overview + decision record to spec v2 (post 6-lens adversarial review): bitemporal-from-day-1, phase-gated managed-first infra (~765/mo self-host), host tailscaled (dropped the unaudited embedded crate), filtered validation corpus, transactional outbox, per-event Nats-Msg-Id; added a “What changed in v2” diff, a Bitemporal/backtest-safety section, and a “Durable gotchas (reference)” section (GDELT scale/raw-entities/format+license, Empire kind: job 15-min limit + zero backup/DR, cost shape, crate pins) — dionysus, dionysus-architecture-decisions
  • Initialized dionysus project folder + overview note — dionysus
  • Documented the nine architecture decisions and their rationale (platform-first, GDELT-spine hybrid, Postgres+Qdrant, NATS JetStream, all-Rust, Tailscale-native, SigNoz/OTel, self-hosted sized VM, 2015→now backfill), the @deploy contract, and the reused empire gotchas — dionysus-architecture-decisions