---
id: ADR-pool.covers-source-anchors
status: Pool
parent: PRD-GZKIT-1.0.0
lane: lite
enabler: null
---

# ADR-pool.covers-source-anchors: Extend @covers anchors to source-level surfaces

## Status

Pool

## Intent

gzkit already runs an anchor-tag-shaped surface system at the **test layer**
(`@covers(REQ-X)` annotations binding tests to OBPI REQs) and the **governance
layer** (ADR-X.Y.Z IDs, OBPI-X.Y.Z-NN IDs, skill names, the manifest at
`.gzkit/manifest.json`). What it does **not** carry is an inline anchor surface
at the **source code layer**: there is no stable token attached to a public
function, class, or module that an agent can grep against to recover the REQ
or product surface a piece of source is responsible for.

The failure mode this leaves open is the one Ben Fellows ("Agentic development
wasn't working for my large codebase. Then I implemented anchor tags",
2026-05-26) describes at scale: agents fall back to fuzzy grep over
`src/gzkit/**` when planning refactors, miss callers, leave orphan code, and
produce confidently-detailed plans that quietly skip the surfaces they should
have read. gzkit's own runtime is approaching the threshold where this
matters — `src/gzkit/` is now several thousand lines across CLI, governance,
validators, advisor, and chore-runner subsystems.

This ADR proposes extending the `@covers` discipline *downward into source
code*, so every public function/class/module surface carries one of:

- `# @covers(REQ-X.Y.Z-NN-MM)` — the same shape as test-layer `@covers`,
  binding the source surface to a specific REQ in an OBPI brief.
- `# @surface <stable-slug>` — a stable product/feature surface label that
  groups related source across files (the Ben-Fellows-style anchor, but
  unified with gzkit's existing slug conventions).

The deterministic queryable system is the existing `.gzkit/manifest.json` plus
a new index (e.g. `data/source_anchors.json`) generated by sync, listing every
declared anchor and the files that reference it. Agents query the index first,
then grep — same "manifest → query → grep" sequence Fellows describes, but
unified with gzkit's existing canonical-surface layout.

## Decision

Pool — not yet decided. Promotion criteria for this item:

1. Operator confirms the failure-mode evidence is real for gzkit specifically
   (not just Fellows's much-larger codebases).
2. The unification story is clear: this MUST replace or absorb some existing
   implicit grep-driven agent planning, not stack a fourth label system on top
   of `@covers` / ADR-ID / skill / REQ tags.
3. There is a foundation rationale for departing from "implicit-via-grep" —
   the stdlib-first / governance-steers-direction posture (AGENTS.md
   § Anti-vibing mantra) suggests this should be a structurally-enforced
   surface, not advisory.

## Alternatives Considered

1. **Status quo — implicit grep-driven planning.** Cheap, no new surface, but
   continues to scale with codebase size against agent grep accuracy. The
   named failure: orphan code, missed callers, plans-that-look-detailed-but-
   skip-files.

2. **Adopt Fellows's manifest+anchor approach verbatim.** Ben reports ~35k
   anchors and ~1300 services in his codebase. gzkit is smaller; verbatim
   adoption would over-fit ceremony surface for the actual scale of the
   problem. The Fellows-density rule ("10–15 similar tags max per group") is
   useful as a *boring-tags* heuristic, not as a literal target.

3. **Lightweight `@surface`-only (no per-function tags).** One anchor per
   module/class, slug-named after the product surface. Faster to author,
   weaker grep accuracy. Pairs naturally with the existing skill/feature
   slug system but loses the REQ→source binding.

4. **Unify with existing `@covers` — extend the same decorator/annotation
   downward.** Reuses the existing schema, validator, and operator mental
   model. REQ-layer binding is the strongest; `@surface` becomes an optional
   second layer for cross-REQ grouping. This is the favored direction if the
   pool item promotes.

5. **Defer to graph-engine promotion (post-1.0 pool item
   `artifact-graph-navigation`).** A real graph engine subsumes anchor tags
   by making the relationships first-class. But Architecture Memo decision
   record 2026-03-29 § 3 says do not build the graph engine before locking
   state doctrine. Anchor tags are a lighter-weight, ship-now alternative
   that the graph engine can later consume as one input.

## Related

- Operator clarification 2026-05-27 (recorded in `agent-insights.jsonl`):
  agent over-fit "5:1 governance-to-output ratio is the product" as
  binding ratio; reframed as steering/accountability metaphor. Anchor-tag
  surface area must justify itself on steering/accountability grounds, not
  volume.
- Ben Fellows, "Agentic development wasn't working for my large codebase.
  Then I implemented anchor tags" (YouTube, 2026-05-26) — external
  proximate trigger.
- `.gzkit/rules/tests.md` — existing `@covers` test-layer discipline.
- `ADR-pool.artifact-graph-navigation` — the post-1.0 graph engine this
  defers to.

## Notes

Pool ADRs are backlog items — they carry no `semver:` or `kind:` frontmatter.
Promotion into the active tree (foundation or feature) is performed via
`gz adr promote`, which rewrites the frontmatter with the chosen taxonomy.
