feat(watchkeeper): product knowledge review surface and GitHub Action [roadmap:v0.12.x] - #79
Merged
Merged
Conversation
…quirement [roadmap:v0.12.0] Rewrites the unshipped v0.9.x watchkeeper drafts as a canonical v0.12.x series (v0.12.0 repository review, v0.12.1 intent analysis, v0.12.2 watchkeeper, new v0.12.3 GitHub Action): v0.9.x identities were released as the Explorer series, main carries v0.10.x through v0.10.6, and v0.11.x is allocated to in-flight work. Un-defers rac-product-intent-ci-watchkeeper now that Guide has shipped, links it to the new series, and points the working corpus at v0.12.x. Implements rac/roadmaps/v0.12.x-watchkeeper/.
…[roadmap:v0.12.0] Pins git archive into a temporary directory as the only git-aware seam for watchkeeper comparisons, with directory-to-directory comparison keeping services and golden tests git-free. Implements rac/roadmaps/v0.12.x-watchkeeper/v0.12.0-repository-review.md.
Adds compare.py — RepoState loading and compare_states deriving changed artifacts (matched by corpus-relative path, with requirement-level diffs), validation deltas, relationship deltas, and statistics deltas, all read from the existing Repository model. Extracts the repository_from_corpus seam so a comparison side reuses one corpus walk. Implements rac/roadmaps/v0.12.x-watchkeeper/v0.12.0-repository-review.md.
The only git-aware module in the package: materialized_revision extracts the corpus subpath at a revision via git archive into a temporary directory — read-only, offline, no worktree registration (ADR-042). Unknown revisions and non-git directories raise typed errors the CLI maps to exit 2; a revision without the subpath yields an empty corpus. Implements rac/roadmaps/v0.12.x-watchkeeper/v0.12.0-repository-review.md.
…12.0] rac watchkeeper [directory] --base REF [--head REF] [--json]: base and head each accept a git revision or a plain directory, the working tree is the default head, and the report renders as a human summary or stable JSON (schema_version 1, additive across the series, ADR-007). Exit 0 — comparison is informational until v0.12.2 recommendations. Implements rac/roadmaps/v0.12.x-watchkeeper/v0.12.0-repository-review.md.
…oadmap:v0.12.0] Fixture corpora plant one case per delta — added, modified, removed, newly invalid, and a relationship broken purely by a removal elsewhere. compare and revisions batteries join the CI matrix (ADR-027); golden cases pin human and JSON output via directory-to-directory comparison, so goldens never depend on git state. Implements rac/roadmaps/v0.12.x-watchkeeper/v0.12.0-repository-review.md.
Implements rac/roadmaps/v0.12.x-watchkeeper/v0.12.0-repository-review.md.
…:v0.12.1] analyze_intent screens a repository comparison for clarity regressions: specificity loss, ambiguity, constraint weakening and removal, section removal, unlinked scope, and relationship impact. Token-boundary matching and parsed-section comparison only — no semantic scoring; the finding codes reuse the requirement's policy vocabulary. Implements rac/roadmaps/v0.12.x-watchkeeper/v0.12.1-intent-analysis.md.
…dmap:v0.12.1] The report gains a Findings block (human) and an additive findings array (JSON, ADR-007), each finding carrying its code, severity, path, identifier, detail sentence, and diff-style evidence. Implements rac/roadmaps/v0.12.x-watchkeeper/v0.12.1-intent-analysis.md.
…map:v0.12.1] Positive cases ride the shared watchkeeper fixtures (now planting an acceptance-criteria removal); negative boundary cases — kept numbers, pre-existing terms, token-vs-substring, mandatory rewording, linked new scope — build minimal corpora under tmp_path. The intent battery joins the CI matrix and the goldens pin the findings block. Implements rac/roadmaps/v0.12.x-watchkeeper/v0.12.1-intent-analysis.md.
Implements rac/roadmaps/v0.12.x-watchkeeper/v0.12.1-intent-analysis.md.
…v0.12.2] Newly invalid artifacts, new relationship issues, and the clarity-regression findings map to Core-owned reasons, deduplicated by code; ambiguity, unlinked scope, and relationship impact inform but never recommend alone. JSON gains an additive review block (ADR-007). Implements rac/roadmaps/v0.12.x-watchkeeper/v0.12.2-watchkeeper.md.
…:v0.12.2] --format github writes a Markdown step-summary report to stdout and workflow-command annotations (repository-relative paths, errors for recommendation triggers) to stderr; --no-annotate silences the stream. --fail-on error|warning|none turns the review verdict into CI policy; human output gains the verdict block. Implements rac/roadmaps/v0.12.x-watchkeeper/v0.12.2-watchkeeper.md.
… [roadmap:v0.12.2] The watchkeeper battery covers the recommendation mapping and ordering, the fail-on matrix through the CLI, stdout/stderr separation of the github format, and the json alias; a github golden joins the human and JSON goldens (stdout only — annotations are pinned by the battery). Implements rac/roadmaps/v0.12.x-watchkeeper/v0.12.2-watchkeeper.md.
…2.2] Implements rac/roadmaps/v0.12.x-watchkeeper/v0.12.2-watchkeeper.md.
A logic-free wrapper: pin Python, install RAC (PyPI by default, the action checkout in source mode for dogfooding), resolve the pull request base ref, run one rac watchkeeper --format github invocation with stdout to the step summary, and propagate the exit code unchanged. Implements rac/roadmaps/v0.12.x-watchkeeper/v0.12.3-watchkeeper-action.md.
…v0.12.3] Consumers call .github/workflows/watchkeeper.yml with uses: to get the checkout and base-ref wiring for free; this repository's own PR checks now run the local action in source mode — every pull request here is both reviewed by Watchkeeper and an end-to-end test of action.yml. Implements rac/roadmaps/v0.12.x-watchkeeper/v0.12.3-watchkeeper-action.md.
YAML contract tests assert the action's input surface and defaults, the single forwarded CLI invocation, both install modes, the reusable workflow's pass-through inputs, and the dogfood job's source install — so the wrappers cannot drift from the command contract silently. Implements rac/roadmaps/v0.12.x-watchkeeper/v0.12.3-watchkeeper-action.md.
…:v0.12.3] docs/watchkeeper.md covers the command, the action inputs, the reusable workflow, the exact-tag pinning policy (no moving major tag — setuptools-scm derives versions from git tags), and a worked example. Implements rac/roadmaps/v0.12.x-watchkeeper/v0.12.3-watchkeeper-action.md.
ADR-042 was taken by docs-site hosting (#78, merged to main). Renames the watchkeeper revision-materialization decision to ADR-043 and updates its references in the v0.12.0/v0.12.3 roadmaps and the watchkeeper docs, so 'ADR-043' resolves to this decision and 'ADR-042' stays the docs-site decision. Implements rac/roadmaps/v0.12.x-watchkeeper/v0.12.0-repository-review.md.
tcballard
force-pushed
the
claude/watchkeeper-v0.9-action-tdjbz6
branch
from
June 13, 2026 09:05
1f4c796 to
4dcc8d1
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements the watchkeeper series —
rac/roadmaps/v0.12.x-watchkeeper/(v0.12.0–v0.12.3) — RAC's product knowledge review surface and its delivery as a GitHub Action.Adds:
rac watchkeeper [directory] --base REF [--head REF]: compare two repository states (git revision or directory) and report changed artifacts, validation/relationship/statistics deltas, deterministic intent findings, and a review verdict.--format human|json|github,--json(alias),--fail-on error|warning|none,--no-annotate.action.ymland reusable.github/workflows/watchkeeper.ymlthat run the command on pull requests, plus a dogfood job that runs the action against this repository on every PR.compare,revisions,intent,watchkeeper), four CI test batteries, golden coverage, and docs (docs/watchkeeper.md, CLI reference, README, CHANGELOG).Roadmap / ADR Trace
Roadmap:
rac/roadmaps/v0.12.x-watchkeeper/v0.12.0-repository-review.mdrac/roadmaps/v0.12.x-watchkeeper/v0.12.1-intent-analysis.mdrac/roadmaps/v0.12.x-watchkeeper/v0.12.2-watchkeeper.mdrac/roadmaps/v0.12.x-watchkeeper/v0.12.3-watchkeeper-action.mdRequirement:
rac/requirements/rac-product-intent-ci-watchkeeper.md(un-deferred — Guide shipped through v0.10.6).Relevant ADRs:
rac/decisions/adr-043-watchkeeper-revision-materialization.md(new — git materialization, CLI surface, directory-or-revision inputs; numbered 043 because feat(docs-site): Lore documentation site on GitHub Pages [roadmap:v0.10.7] #78 took 042)rac/decisions/adr-015-explorer-as-consumer.md(watchkeeper is a consumer; all intelligence stays in services)rac/decisions/adr-007-json-contract-stability.md(additiveschema_version: "1"JSON across the series)rac/decisions/adr-027-ci-test-topology.md(one service = one battery)rac/decisions/adr-013-leverage-existing-source-control-systems.md(git, not a bespoke store)Renumbering
This series was drafted as v0.9.x. It is renumbered to v0.12.x because the v0.9.x identities were released as the Explorer series (
rac/roadmaps/archive/v0.9.0–v0.9.3), main already carries the v0.10.x Guide series through v0.10.7, and v0.11.x is the portal/export series (merged in #77). PyPI versions cannot regress. Each artifact records the renumbering in its Assumptions section; a calendar-versioning discussion was raised and explicitly deferred (out of scope here).Scope
Included
newly_invalid/newly_valid); relationship delta (per-side summaries,new_issues/resolved_issues— including references broken purely by a removal elsewhere); statistics delta (per-type and total counts). All derived from the existingRepositorymodel.git archiveinto a temp directory, read-only, corpus-subpath only; a missing subpath yields an empty base corpus.specificity_regression,ambiguity_introduced,constraint_weakened,constraint_removed,acceptance_criteria_removed,success_measures_removed,unlinked_scope,relationship_impact— token-boundary text matching and parsed-section comparison only.--format github(Markdown to stdout, workflow-command annotations to stderr);--fail-onexit policy.action.yml, reusable workflow, PR dogfood job, YAML contract tests, docs.Excluded
watchkeeper:policy block in.rac/config.yaml(named in the requirement). Deferred;--fail-oncovers CI policy. Recorded in the requirement's Future Considerations and the v0.12.3 roadmap.@v1) tag. setuptools-scm derives package versions from git tags; a floating tag would corrupt derivation. Consumers pin exact release tags.Product / Architecture Decisions
rac watchkeeper, notrac review --intent.rac reviewkeeps its current-state semantics; comparison is a new command that grows additively across the series, matching the requirement's interface section.--base/--headaccept a git revision or a directory; revision materialization is isolated in one module (revisions.py). This keeps golden tests git-independent (directory-to-directory) and lets users compare arbitrary snapshots. Recorded as ADR-043.git archive, notgit worktree. No.gitmutation, no worktree registration or locking, safe under concurrent CI runs, and only the corpus subpath is extracted.$GITHUB_STEP_SUMMARY), workflow commands to stderr (parsed live from the step log). One invocation feeds both the summary and inline annotations without interleaving.install-from: sourceexists for this repo's dogfood (external action checkouts lack git metadata for setuptools-scm).User-Facing Contract
CLI
Human Output
Sections: Changed Artifacts, Validation, Relationships, Repository Changes, Findings, Review (verdict with reasons or "Nothing requiring attention").
JSON Output
Stable contract (
schema_version: "1"), additive across the series:{ "schema_version": "1", "base": "main", "head": "rac", "directory": "rac", "changes": [{"change": "modified", "type": "requirement", "id": "…", "title": "…", "path": "…", "base_status": "valid", "head_status": "valid", "diff": {}}], "validation": {"base": {}, "head": {}, "newly_invalid": [], "newly_valid": []}, "relationships": {"base": {}, "head": {}, "new_issues": [], "resolved_issues": []}, "stats": {"total": {}, "by_type": {}}, "findings": [{"code": "specificity_regression", "severity": "warning", "path": "…", "identifier": "…", "detail": "…", "evidence": []}], "review": {"recommended": true, "reasons": [{"code": "…", "reason": "…"}]} }Exit Codes
0: nothing requiring attention under the chosen policy (always with--fail-on none).1: review recommended (--fail-on error), or additionally any warning finding (--fail-on warning).2: usage error, unknown revision, or not inside a git repository when a revision is requested.Verification
Ran (re-run after rebasing onto the current
main)Covered
.gitmutation; temp dir removed on exit.breakfast≠fast), mandatory→mandatory rewording, linked new scope.--fail-onmatrix through the CLI (including warning-only findings); github stdout/stderr separation;--no-annotate; JSON alias.unlinked_scopeannotation; this branch passes its own dogfood gate.Review Path
rac/roadmaps/v0.12.x-watchkeeper/andrac/decisions/adr-043-watchkeeper-revision-materialization.md— the contract and the materialization decision.src/rac/services/compare.py,src/rac/services/revisions.py— comparison model and the single git seam.src/rac/services/intent.py— the deterministic checks.src/rac/services/watchkeeper.py— report assembly and recommendation mapping.src/rac/cli.py,src/rac/output/github.py,src/rac/output/human.py,src/rac/output/json.py— CLI surface and rendering.action.yml,.github/workflows/watchkeeper.yml,.github/workflows/pr-checks.yml— delivery and dogfood.tests/test_compare.py,tests/test_revisions.py,tests/test_intent.py,tests/test_watchkeeper.py, fixtures, goldens.docs/watchkeeper.md,docs/cli.md,mkdocs.yml,CHANGELOG.md.Notes For Reviewer
repository_from_corpusseam insrc/rac/services/repository.pyis an additive extraction fromload_repository; the existing behavior is unchanged, but it is the shared join everything reuses.v0.12.xrelease (the action's default install mode needs a published version carrying the command — the dogfood job sidesteps this viainstall-from: source), and bump the@mainref in.github/workflows/watchkeeper.ymlto that tag.main(linear history, no merge commit) so it lands cleanly via Rebase and merge. This reconciled both feat(export): portal export and web surface [roadmap:v0.11.0] #77 (v0.11.0 portal/export) and feat(docs-site): Lore documentation site on GitHub Pages [roadmap:v0.10.7] #78 (v0.10.7 docs site): additive overlaps resolved inCHANGELOG.md,CLAUDE.md,src/rac/cli.py, and the README doorway;docs/watchkeeper.mdregistered in the mkdocs nav somkdocs build --strictstays green; and this PR's decision renumbered ADR-042 → ADR-043 because feat(docs-site): Lore documentation site on GitHub Pages [roadmap:v0.10.7] #78 landed its own ADR-042 (docs-site hosting).Implementation Process
Implemented with AI assistance under the roadmap contract. Final scope, review, and acceptance decisions were made by the maintainer.