Skip to the content.

Related-system inventory: make deep study measurable before borrowing

Verdict

The old monitor made source freshness visible but let a study stop after a shallow note. The new spine adds a separate inventory gate: fak study-monitor --inventory-check treats candidate and studied rows as exhaustive by default and fails until each carries a machine-readable map path, matching indexed revision, positive subsystem count, completeness-critic result, and the full required source-class set.

The second spine adds the missing producer: fak study-inventory walks a local checkout at a pinned revision and writes a deterministic map of subsystems, language/file counts, representative paths, skipped dependency/control dirs, and required source-class status rows. This does not claim the study is complete; it creates the denominator a deep pass must finish.

The monitor now reads a registry row’s JSON map_path and refuses unreadable, wrong-schema, wrong-repo, wrong-revision, or mismatched subsystem-count maps, so inventory metadata cannot pass by assertion alone.

The next hardening pass makes the denominator harder to fake: a map file must carry positive totals equal to its subsystem aggregates, a non-empty completeness critic, and one source-class status row for every required class. Local tree classes clear through covered rows with path evidence or checked_absent rows from the full walk. Forge history stays partial or external_required, and process classes stay external_required; they need traceable source_evidence rows. A registry row can no longer clear full forge/process coverage by listing open_closed_issues_prs_discussions, fak_selfquery_witness, candidate_matrix, or issue_tracking without evidence, and forge evidence must cover issues, pull requests, and discussions.

The first live readout is intentionally red: fak-study-inventory-report/1 now reports ok=false with 39 blockers across the current registry. That gives the backlog a concrete denominator instead of an instruction to “study harder.”

The first real map was created for ruvnet/ruflo at pinned revision 4dcff483482cee316f47552a961bcbaadc89f378: docs/research/inventory/ruvnet-ruflo.json, with docs/research/inventory/ruvnet-ruflo.md as the human rendering. It inventories 5,517 files across 18 immediate subsystems. The registry now points at that map but keeps the row red until full forge/API issue and PR read-back, fak self-query witness, candidate matrix, and issue-tracking artifacts exist.

GitHub tracking state

The requested first step was GitHub tracking. Early attempts failed with 401 Bad credentials, but a later gh auth status read-back succeeded for anthony-chaudhary, and exact marker searches found no duplicate issue for related-system-inventory-2026-08-25.

Live tracker:

The root issue also has a child-link comment: https://github.com/anthony-chaudhary/fak/issues/8930#issuecomment-5416600699.

Root issue body

Filed as #8930. The body below is retained because it is the reproducible issue text.

Title: epic: exhaustive related-system inventory and repo indexing for study-repo

Milestone: Generation G0 - Now / Immediate Labels: epic, research, gen/now, priority/P1

<!-- fak-related-system-inventory-key: related-system-inventory-2026-08-25 -->

## Value

- For: maintainers and agents using `study-repo`, `field-borrow`, and `scout-loop` to decide what external systems teach FAK.
- Problem: study passes can stop after a shallow README/code skim, then either file a monolith or file nothing.
- Today: `docs/research/monitored-repositories.json` tracks freshness, but not whether a repo has an exhaustive indexed map.
- Better because: every candidate/studied source has a checkable inventory denominator before any borrow/adopt/dismiss decision.
- Centrality: Enabling - it improves the quality of Core backlog generated from external systems.
- P1: advanced - agents can load a bounded map instead of a transcript.
- P2: advanced - study effort becomes reusable and dedupeable.
- P3: preserved - inventory is evidence, not a commitment to copy or adopt.
- P4: advanced - GitHub issues and dispatch lanes get concrete source-class gaps.

## Core through-line

Add a repo-native inventory contract to `study-monitor` plus a local map generator -> run them over `docs/research/monitored-repositories.json` and a pinned scratch clone -> file child leaves for missing maps, non-tree source classes, and indexing integration -> dispatch workers only after issue IDs exist.

## Gold-plating boundary

Do not build a full Sourcegraph/Glean clone in this issue. The root spine is the failing/passing inventory gate plus issue-ready backlog. Full text indexes, semantic indexes, CodeQL databases, and per-repo study backfills are child leaves.

## Scope / tree

`internal/studymonitor/**`, `cmd/fak/study_monitor.go`, `cmd/fak/study_monitor_test.go`, `cmd/fak/study_inventory.go`, `cmd/fak/study_inventory_test.go`, `docs/research/monitored-repositories.*`, `docs/research/inventory/**`, and the dated research note.

## Acceptance

`fak study-monitor --inventory-check --json` emits `fak-study-inventory-report/1`, defaults candidate/studied rows to exhaustive, exits nonzero on missing maps, and names the exact missing source classes. `fak study-inventory` emits `fak-study-inventory-map/1` from a pinned local checkout and explicitly distinguishes local tree coverage from source classes that require forge/API or study-pass artifacts. The map file itself is now part of the proof: missing source-class status rows, contradictory or empty totals, covered rows without path evidence, invalid class dispositions, empty completeness critics, or bare registry claims for partial/external classes are blockers.

## Witness / proof

`go test ./internal/studymonitor ./cmd/fak -run 'StudyMonitor|StudyInventory|InventoryMap|InventoryReport'` passes. A live run against the registry reports 39 blockers rather than silently accepting shallow studies. A pinned Ruflo scratch clone rendered `docs/research/inventory/ruvnet-ruflo.json` plus the Markdown companion.

## Placement

`gen/now`, `priority/P1`, `studymonitor` lane.

Generated follow-on plan

Plan command:

go run ./cmd/fak-dev issue fanout \
  --title "study inventory completeness gate" \
  --leaf studymonitor \
  --spine "go test ./internal/studymonitor ./cmd/fak -run 'StudyMonitor|StudyInventory|InventoryMap|InventoryReport' && go run ./cmd/fak study-monitor --inventory-check --json && go run ./cmd/fak study-inventory --root _scratch/study-inventory/ruflo --repository ruvnet/ruflo --revision 4dcff483482cee316f47552a961bcbaadc89f378 --json --out docs/research/inventory/ruvnet-ruflo.json" \
  --paths internal/studymonitor \
  --areas qa,dogfood,product,integration,docs \
  --max 8 \
  --json

Contract readback:

schema=fak.issue-contract-result.v1
ok=true dispatchable=8 triage_only=0 refused=0 step_budget=25
Key Title Labels Generation Steps
fanout-studymonitor-spine-d6082a942fe2a0c4-qa-edge-sweep qa: adversarial + edge-case sweep for study inventory completeness gate fanout, qa gen/now 3
fanout-studymonitor-spine-d6082a942fe2a0c4-qa-failure-paths qa: failure-path + refusal coverage for study inventory completeness gate fanout, qa gen/now 3
fanout-studymonitor-spine-d6082a942fe2a0c4-qa-determinism qa: determinism + race witness for study inventory completeness gate fanout, qa gen/now 2
fanout-studymonitor-spine-d6082a942fe2a0c4-dogfood-self-run dogfood: run study inventory completeness gate on this repo’s own live work fanout, dogfood gen/now 3
fanout-studymonitor-spine-d6082a942fe2a0c4-dogfood-usage-ledger dogfood: usage ledger so study inventory completeness gate adoption is measured, not claimed fanout, dogfood gen/next 4
fanout-studymonitor-spine-d6082a942fe2a0c4-product-cli-reference product: docs/cli-reference.md entry + usage parity for study inventory completeness gate fanout, product gen/next 2
fanout-studymonitor-spine-d6082a942fe2a0c4-product-lcd-demo product: LCD demo/example for study inventory completeness gate meeting the run-the-demos bar fanout, product gen/next 5
fanout-studymonitor-spine-d6082a942fe2a0c4-product-error-ux product: refusal/error-message quality pass for study inventory completeness gate fanout, product gen/next 3

Live fan-out filing with fak-dev issue fanout --live exited 0 but skipped all eight generated rows because the root issue body already contains their marker keys. That is an anti-duplication behavior, not evidence that the eight rows have independent issue numbers. The concrete repo-scope children were filed manually as #8931-#8937.

Filed scope issues

  1. #8931 completes Ruflo’s non-tree classes: full forge/API issue and PR read-back, fak self-query witness, candidate matrix, and issue-tracking artifacts.
  2. #8932 maps Untrivial-ai/agent-orchestrator at ee2c58a577317d4480a2b2ee5ff77f25e5307af9.
  3. #8933 maps langchain-ai/open-swe at a6c360047186cc5b8afe3a74012a12bfc94ae7c7.
  4. #8934 maps EveryInc/compound-engineering-plugin at 345e2bea42cabea2f32d25a68fd1739e8e92cd03.
  5. #8935 maps obra/superpowers at b36e0829c6d0140e93cfef2ca599b1b07d4a7797.
  6. #8936 backfills or re-issues the already-studied registry rows.
  7. #8937 decides which repo-indexing layers stay native versus optional backend recipes.

Prior-art indexing lessons checked

Agent delegation status

No live FAK dispatch wave was launched in this pass. python3 tools/dispatch_status.py --fast reported READY_TO_GROW, SPAWN_OK, and 0/4 live. A Codex wave dry-run for #8932 was held by MODEL_UNSUPPORTED for gpt-5.6-sol under the current credential class, but a Claude backend dry-run returned ok=true, verdict=WOULD_WAVE, selected docs#8932, lane docs, lease resolve-docs-8932, and tree docs/research/inventory/ plus docs/research/monitored-repositories.json.

Per the super-loop contract, the live worker was not launched without explicit post-plan approval. The staged launch command is recorded on #8932.

Current blockers