Alt - AI-Augmented RSS Knowledge Platform
September 20, 2026 · View on GitHub
WHAT
Monorepo with 20+ microservices (Go, Python, Rust, TypeScript, Deno). Docker Compose-first orchestration, TDD-first development.
Each service has its own CLAUDE.md with service-specific guidance. See docs/services/MICROSERVICES.md for the full reference.
alt-backend / alt-harvester / alt-notifier / alt-data-hub は 1 ディレクトリ 4 バイナリ —
alt-backend/app という単一 Go モジュール (module alt) から cmd/backend(ユーザ向け API)/
cmd/harvester(7 定期ジョブ)/ cmd/notifier(Web Push 配信、API listener なし)/
cmd/datahub(alt-db の唯一のオーナー、mTLS 専用)の 4 本を切り出し、同じ
alt-backend/Dockerfile.backend を --build-arg BINARY=backend|harvester|notifier|datahub で
4 イメージにビルドする。4 つとも cd alt-backend/app && go test ./... で一括してテストする。
cmd/fix_article_titles は go build ./cmd/... に含まれるが常駐コンテナではない一発実行スクリプト。
根拠と責務分担は docs/ADR/000954.md。
Wiki entry: docs/wiki/HOME.md — crystallized navigation layer over ADR / runbook / plan. Read this first to get the current map of the system.
WHY
- TDD-first: Write failing test → make it pass → refactor. Quality through tests, not hope.
- Compose-first: Docker Compose is the single source of truth. No K8s.
- Clean Architecture:
Handler → Usecase → Port → Gateway → Driverin every service.
HOW
Running services
docker compose -f compose/compose.yaml -p alt up -d # All
docker compose -f compose/compose.yaml -p alt up -d <service> # One
docker compose -f compose/compose.yaml -p alt logs <service> -f
docker compose -f compose/compose.yaml -p alt down
Compose stacks are wired via include:, not Compose profiles — see compose/compose.yaml.
Verifying changes
curl http://localhost/health # Frontend (via nginx)
curl http://localhost:9000/v1/health # Backend
curl http://localhost:9250/health # BFF
curl http://localhost:7700/health # Meilisearch
Antigravity MCP delegation
Use antigravity_run for a separate, bounded investigation or plan. Default to
mode: "plan" and autonomy: "safe"; request accept-edits only when the
task explicitly calls for changes. Continue a thread only with the exact
conversation_id returned by the prior call, and keep the same workspace.
The bridge permits one Antigravity call at a time. Do not ask a delegated turn
to recursively delegate work or launch this MCP server.
Critical Rules
- IMPORTANT: TDD First — Write the failing test BEFORE writing implementation code. RED → GREEN → REFACTOR.
- IMPORTANT: Rate Limiting — 5-second minimum intervals between external API calls.
- IMPORTANT: Rebuild compiled services — Go/Rust/TS changes require
--build. Without it, old binaries keep running silently. - No Secrets in Code — Use
.envand Docker secrets. Never hardcode credentials. - Service-specific rules — Always check
<service>/CLAUDE.mdbefore modifying a service. - Reload canonical context before repair PRs — Before starting a repair / regression-fix PR that touches the Knowledge Trail, Knowledge Home, or any append-first projection path, re-read
docs/plan/knowledge-trail-core-concept.mdand the affected canonical contract via/plan-context-loader. Long-running sessions silently lose the invariants ("context rot") and bug fixes regress to single-axis collapses. Knowledge Loop contracts are historical only ([[000940]]). - Producer wiring PRs require CDC RED first — Any PR that adds or modifies a cross-service event producer (new event type, new payload field, new RPC) must land a Pact CDC RED test before the producer GREEN. "Proto compiled + E2E green" is not enough — the silent-fallback failure mode (ADR-000928) hides DI/wiring gaps that defensive nil-guards swallow.
- No silent fallback for unwired dependencies — Optional dependencies (DI options, feature flags, future hooks) must surface their wiring state with a loud
*_enabled/*_disabledstartup log ANDpanicwhen the unwired branch is taken inside business code. Defensiveif x == nil { return nil }in producer / projector / resolver paths is forbidden — it makes "DI forgot to wire" indistinguishable from "intentionally disabled" (PM-2026-045 / ADR-000928 root cause). Details:.claude/rules/di-wiring.md. - Fail-fast startup config — Missing required config (secrets, upstream URLs, auth tokens) = exit non-zero at startup. Never warn-and-limp. "Disabled" must be an explicit config value with a startup log, never inferred from an unset variable.
- Stream consumers: ACK after durable write + reclaim loop — XACK only after the side effect is durable (not on buffer-in). Every XREADGROUP consumer MUST run an XAUTOCLAIM reclaim loop, or crashed-consumer messages are lost forever and DLQ conditions never fire. Details:
.claude/rules/event-stream-consumer.md.
Planning
Obsidian vault (docs/) — 466+ ADRs, plans, runbooks, reviews. Run /plan-context-loader
before designing; it loads the canonical contracts and searches docs/ADR/ directly.
Immutable Data Model Invariants
- Append-first: State via events, not mutable flags.
knowledge_eventsis INSERT-only. - Reproject-safe: Projectors use event payload only, never latest state queries.
- Versioned artifacts: Summaries/tags use
summary_versions/tag_set_versions. - Why as first-class: Home items and Trail branches must explain why they were surfaced / proposed.
- Disposable projections: Read models (
knowledge_trail_footprints,knowledge_trail_branches,knowledge_home_items,today_digest_view,recall_candidate_view) can be rebuilt from the event log.
Before planning, run /plan-context-loader to load the relevant ADRs first.