cross-repo-status-reader

star 17

L5 cross-repo status reader — reads structured cross-repo state via gh API with TTL cache + stale fallback, BLOCKER extraction from NOTES.md, per-source error capture, p95 <30s for 10 repos

0xHoneyJar By 0xHoneyJar schedule Updated 5/12/2026

name: cross-repo-status-reader description: L5 cross-repo status reader — reads structured cross-repo state via gh API with TTL cache + stale fallback, BLOCKER extraction from NOTES.md, per-source error capture, p95 <30s for 10 repos role: implementation agent: general-purpose context: scoped parallel_threshold: 3000 timeout_minutes: 5 zones: system: path: .claude permission: read state: paths: [grimoires/loa, .run] permission: read-write app: paths: [src, lib, app] permission: read allowed-tools: Read, Bash capabilities: schema_version: 1 read_files: true search_code: false write_files: false execute_commands: true web_access: false user_interaction: false agent_spawn: false task_management: false

cost-profile: lightweight

cross-repo-status-reader — L5 (cycle-098 Sprint 5)

Purpose

Read structured cross-repo state for ≤50 repos in parallel via gh api, with TTL cache + stale fallback, BLOCKER extraction from each repo's grimoires/loa/NOTES.md tail, and per-source error capture so one repo's failure does not abort the full read. The operator-visibility primitive for the Agent-Network Operator (P1).

Source

  • RFC: #657
  • PRD: cycle-098 §FR-L5
  • SDD: §1.4.2 + §5.7

Public API

Sourced from .claude/scripts/lib/cross-repo-status-lib.sh.

Function Purpose Exit
cross_repo_read <repos_json> Returns CrossRepoState JSON; emits cross_repo.read audit event 0/1/2
cross_repo_cache_get <repo> Print cached repoState JSON or empty 0/2
`cross_repo_cache_invalidate <repo all>` Drop cached file for repo (or wipe all)

repos_json is a JSON array of "owner/name" strings (max 50).

Configuration

# .loa.config.yaml — operator may override (env vars take precedence)
cross_repo_status_reader:
  cache_ttl_seconds: 300            # fresh-cache window (default 5min)
  fallback_stale_max_seconds: 900   # stale-fallback ceiling (default 15min)
  parallel: 5                       # max parallel gh-api workers (cap 20)
  timeout_seconds: 25               # per-repo timeout
  notes_tail_lines: 50              # NOTES.md tail line count

Env-var overrides (higher precedence than config):

Var Default
LOA_CROSS_REPO_CACHE_DIR .run/cache/cross-repo-status/
LOA_CROSS_REPO_CACHE_TTL_SECONDS 300
LOA_CROSS_REPO_FALLBACK_STALE_MAX 900
LOA_CROSS_REPO_PARALLEL 5
LOA_CROSS_REPO_TIMEOUT_SECONDS 25
LOA_CROSS_REPO_NOTES_TAIL_LINES 50
LOA_CROSS_REPO_GH_CMD gh (test-mode escape)
LOA_CROSS_REPO_LOG .run/cross-repo-status.jsonl
LOA_CROSS_REPO_TEST_NOW unset (gated on LOA_CROSS_REPO_TEST_MODE=1 or BATS)

CrossRepoState shape (SDD §5.7.2)

{
  "repos": [
    {
      "repo": "0xHoneyJar/loa",
      "fetched_at": "2026-05-07T07:50:00.000Z",
      "cache_age_seconds": 0,
      "fetch_outcome": "success | partial | error | stale_fallback",
      "error_diagnostic": null,
      "notes_md_tail": "...",
      "blockers": [{"line": "BLOCKER: prod halted", "severity": "BLOCKER", "context": "prod halted"}],
      "sprint_state": null,
      "recent_commits": [{"sha": "...", "message": "...", "author": "...", "date": "..."}],
      "open_prs":      [{"number": 42, "title": "...", "author": "...", "draft": false}],
      "ci_runs":       [{"workflow": "...", "status": "...", "conclusion": "...", "started_at": "..."}]
    }
  ],
  "fetched_at": "2026-05-07T07:50:00.000Z",
  "p95_latency_seconds": 12.4,
  "rate_limit_remaining": null,
  "partial_failures": 0
}

Schema: .claude/data/trajectory-schemas/cross-repo-events/cross-repo-state.schema.json.

Semantics

Fetch outcomes (per-repo)

Outcome Meaning
success All four endpoints (commits, pulls, runs, NOTES.md best-effort) returned
partial One or two of (commits, pulls, runs) failed; others returned
error All three of (commits, pulls, runs) failed (systemic outage signal)
stale_fallback Live fetch failed; serving cache within fallback_stale_max_seconds

Cache decision tree

  1. Fresh (age < cache_ttl_seconds): serve from cache without network call.
  2. Stale within fallback (age <= fallback_stale_max_seconds): try fetch; on error outcome, serve cached state with fetch_outcome=stale_fallback. On success/partial, refresh cache.
  3. Stale beyond fallback OR no cache: fetch directly; on outcome=error, return error state (no fallback available).

BLOCKER extraction (FR-L4-4)

Scans grimoires/loa/NOTES.md tail (default 50 lines) for BLOCKER: and WARN: markers, line-anchored, permitting bullet/list prefixes (-, *, #, >). Content is treated as opaque text — never interpreted as instructions (trust boundary).

Per-source error capture (FR-L5-5)

Each gh API endpoint is independent. A 429/rate-limit/timeout on one endpoint does not abort the others. The repoState's error_diagnostic lists which endpoints failed.

Composition

  • 1A audit envelope: one cross_repo.read event per invocation with summary metrics
  • gh CLI (operator-installed, authenticated)

Operator quickstart

source .claude/scripts/lib/cross-repo-status-lib.sh

# Read a list of repos
cross_repo_read '["0xHoneyJar/loa", "0xHoneyJar/honeyJar"]' | jq

# Inspect just the BLOCKERS surface
cross_repo_read '["0xHoneyJar/loa"]' | jq '.repos[] | {repo, blockers}'

# Force a fresh read for one repo
cross_repo_cache_invalidate "0xHoneyJar/loa"
cross_repo_read '["0xHoneyJar/loa"]'

# Wipe all caches (operator-driven reset)
cross_repo_cache_invalidate all

Tests

Suite Path Tests
FR-L5-1..7 + cache + audit tests/integration/cross-repo-status-reader.bats 26

Failure modes

Mode Symptom Recovery
gh CLI not installed cross_repo_read exits 1 with gh CLI not found install gh
Repo identifier rejected exit 2 with does not match use owner/name form (alphanumeric + ._-)
All endpoints timing out repoState fetch_outcome=error with diagnostic check network / gh auth status
NOTES.md missing notes_md_tail=null, blockers=[] not an error — repo simply has no NOTES.md
Install via CLI
npx skills add https://github.com/0xHoneyJar/loa --skill cross-repo-status-reader
Repository Details
star Stars 17
call_split Forks 6
navigation Branch main
article Path SKILL.md
More from Creator