- 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
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 PRdocs— file paths or directory paths (all.mdfiles 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-mapYAML file is read from the local workspace (likesystem-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. GetAllFilesInPathis tried first; if it returns files, they are treated as a directory listing. If it returns empty,GetFileContentis 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 |