Files
review-bot/docs/DESIGN-137-doc-map.md
T
claw 60c6bd9f49
PR Ready Gate / clear-labels (pull_request) Successful in 1s
CI / test (pull_request) Successful in 17s
CI / review (anthropic--claude-4.6-sonnet, sonnet, SONNET_REVIEW_TOKEN) (pull_request) Successful in 48s
CI / review (gpt-5, security, ., rodin/security-patterns, SECURITY_REVIEW.md, SECURITY_REVIEW_TOKEN) (pull_request) Successful in 1m52s
CI / review (gpt-5, gpt, GPT_REVIEW_TOKEN) (pull_request) Failing after 2m8s
test(budget): add DesignDocs tests; replace PLAN-137 with clean design doc
- budget/budget_test.go: add TestFit_DesignDocsInSystemPrompt,
  TestFit_DesignDocsTrimmedBeforeFileContext, TestFit_DesignDocsEmptyNoHeading
  to cover the new DesignDocs section through Fit() and buildResult()
- Remove PLAN-137.md (contained raw thinking stream, not suitable as repo doc)
- Add docs/DESIGN-137-doc-map.md with clean architectural decision record
2026-05-14 20:36:22 -07:00

3.3 KiB

Design: doc-map input for path-scoped design doc injection (Issue #137)

Problem

review-bot can inject context via patterns-repo (external VCS repos) and conventions-file (a single file from the reviewed repo). There is no mechanism to inject local repo documentation files scoped to the paths changed in a PR.

First consumer: grgl/gargoyle#778 needs a "doc adherence" reviewer that checks code against the module's governing design doc, without injecting every doc in the tree.

Approach

New: doc-map input

A .review-bot/doc-map.yml config file in the reviewed repo maps source path globs to governing design docs. review-bot reads the map, intersects it with changed PR paths, and injects only the relevant docs into the system prompt.

Config format

mappings:
  - paths:
      - "lib/gargoyle/engine/signal_risk/**"
    docs:
      - docs/domain/contexts/risk/risk-controls.md
  - paths:
      - "lib/gargoyle/trading/**"
    docs:
      - docs/domain/contexts/trading/
  • paths — glob patterns (including **) matched against changed file paths in the PR
  • docs — file paths or directory paths (all .md files under a directory) to inject
  • Docs are deduplicated across mappings

Architecture

Component Description
review/docmap.go YAML parsing, glob matching with ** support, doc loading via VCS
cmd/review-bot/main.go Step 6c: parses config, intersects with changed files, calls LoadMatchingDocs
budget/budget.go New DesignDocs section — injected after Conventions in system prompt
action.yml doc-map and doc-map-max-bytes inputs, wired to DOC_MAP_FILE/DOC_MAP_MAX_BYTES

Doc file loading

  • The doc-map YAML file is read from the local workspace (like system-prompt-file).
  • Doc files listed in the config are fetched via VCS API (same as conventions-file), enabling them to be loaded from any branch without a local checkout.
  • GetAllFilesInPath is tried first; if it returns files, they are treated as a directory listing. If it returns empty, GetFileContent is tried as a fallback (single file).

Glob matching

** is implemented by splitting patterns and paths on /, then matching segment-by-segment. A ** segment consumes zero or more path segments (not just one level like *).

Budget integration

DesignDocs is added to budget.Sections between Conventions and FileContext. Trim order: Patterns → Conventions → DesignDocs → FileContext → Diff. Design docs appear in the system prompt under ## Design Documents.

Context size guard

Default: 100 KB. Configurable via --doc-map-max-bytes / DOC_MAP_MAX_BYTES. Truncation is noted inline with a ⚠️ message.

Error handling

Situation Behavior
--doc-map file not found Fatal error (like --system-prompt-file)
--doc-map file invalid YAML Fatal error with descriptive message
Unknown YAML keys Log warning, continue
Doc file not found in VCS Log warning, skip
Doc directory empty or no .md files Log debug, skip
Total size exceeds limit Truncate with notice, log warning
No changed paths match any mapping No docs injected, review runs normally
paths or docs list empty in a mapping Skip that mapping