diff --git a/CHANGELOG.md b/CHANGELOG.md index 6933981c..9ddf8921 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,20 @@ details, release history over commit history. ## Unreleased +**Decisions on pull requests — the Herald action** +(`pr-decision-surfacing`). A pull request that edits governed code now gets +one advisory comment naming the live decisions whose declared `## Applies +To` scope covers the changed paths — id, title, the matched scope, and a +link — deduplicated, sorted, and updated in place on re-runs. Facts, never +a merge gate (ADR-034/067): the check never fails on findings, and on +forks the comment degrades to the step summary. A thin client over +`rac decisions-for --json` (ADR-063) with no engine change; the action +ships in the CI delivery repo as +`itsthelore/rac-ci/herald/github` beside Watchkeeper, Gatekeeper, and +Registrar, and is documented on the new +[Decisions on PRs](https://itsthelore.github.io/rac-core/decisions-on-pr/) +page. + **The org grounding plane** (ADR-117). One org-standards corpus behind the shared HTTP endpoint grounds every repository's agents — including repositories with no corpus of their own. `rac init --org-endpoint ` diff --git a/docs/decisions-on-pr.md b/docs/decisions-on-pr.md new file mode 100644 index 00000000..12b2c579 --- /dev/null +++ b/docs/decisions-on-pr.md @@ -0,0 +1,101 @@ +# Decisions on Pull Requests + +Lore's core promise — the agent or reviewer stops re-doing what the team +already ruled out — is only felt if someone thinks to ask. The **Herald** +action asks at the one moment it matters most: a pull request editing +governed code gets **one advisory comment** naming the recorded decisions +whose declared [`## Applies To`](cli.md#decisions-for) scope covers the +changed paths — id, title, the scope that matched, and a link — updated in +place on every re-run. + +Facts, never verdicts: the comment reports what governs and recommends +review. It never gates the merge, never fails the check on findings, and the +human PR review stays the trust boundary. + +Herald ships in the CI delivery repo, +[`itsthelore/rac-ci`](https://github.com/itsthelore/rac-ci), beside the +Watchkeeper, Gatekeeper, and Registrar wrappers. + +## 1. Wire it up + +```yaml +name: Lore decisions +on: + pull_request: + +permissions: + contents: read + pull-requests: write + +jobs: + decisions: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 # the diff needs the merge base + + - uses: itsthelore/rac-ci/herald/github@main + with: + path: rac +``` + +That is the whole integration. Prefer a tag over `@main` once one that +includes Herald is published. Inputs: + +- **`path`** — the corpus directory (default `rac`). +- **`max-inline`** — decisions listed in full before the rest collapse into a + details expander (default `5`). +- **`rac-version`** — pin an exact rac-core release from PyPI; empty installs + the latest. + +On forks, where the token is read-only, the comment degrades to the step +summary instead of failing the check. + +## 2. What the comment says + +One bullet per governing decision, deduplicated across paths and sorted by +id: + +> - **[RAC-KTW0M81HX5C6 — ADR-033: Guide Response Budget](…)** (Accepted) — +> applies to `src/rac/mcp/` — changed: `src/rac/mcp/server.py` +> +> …review recommended. + +The matched scope is the engine's answer, not a heuristic: the action shells +to [`rac decisions-for --json`](cli.md#decisions-for) per changed path and +re-derives nothing. Only **live** decisions appear — a superseded or +deprecated decision no longer binds, by the same liveness rule the MCP +`find_decisions` tool uses. When a PR touches nothing governed, no comment is +created; an existing comment is updated even to the empty state, so it never +outlives its diff. + +The body is deterministic — a pure function of the corpus and the changed +paths, no timestamps — so re-runs on an unchanged PR rewrite the same bytes. + +## 3. Getting governed + +The comment only fires where decisions declare scope. Add an `## Applies To` +section to a decision (paths are validated by +[`rac relationships --validate`](relationships.md)): + +```markdown +## Applies To + +- src/payments/ +``` + +Start with the handful of decisions that agents and reviewers actually +violate — the comment's value is precision, and every entry you declare is +also what grounds [`rac decisions-for`](cli.md#decisions-for) and the MCP +path lookup. + +## 4. Boundaries + +- **Advisory only.** No merge status changes here; a gate, if ever wanted, + is a separate later decision after the advisory has proven signal quality — + the same advisory-before-gate sequencing the drift work records. +- **Post-edit, not interception.** The comment appears at review time; it + does not intercept the agent mid-edit. +- **Comment identity is your CI's.** The action posts with the workflow's + own token; Lore holds no credentials and no write path into the corpus. diff --git a/mkdocs.yml b/mkdocs.yml index 22370436..ae86aab2 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -45,6 +45,7 @@ nav: - Context Cost: context-cost.md - Scale & Performance: scale.md - Watchkeeper: watchkeeper.md + - Decisions on PRs: decisions-on-pr.md - Artifacts: artifacts.md - Relationships: relationships.md - Validation: validation.md diff --git a/rac/roadmaps/future/decisions-on-pr.md b/rac/roadmaps/decisions-on-pr.md similarity index 67% rename from rac/roadmaps/future/decisions-on-pr.md rename to rac/roadmaps/decisions-on-pr.md index f4bf7ffa..e8ddac07 100644 --- a/rac/roadmaps/future/decisions-on-pr.md +++ b/rac/roadmaps/decisions-on-pr.md @@ -7,14 +7,38 @@ type: roadmap ## Status -Planned - -Unscheduled — captured as future intent, not yet on a release. The graduation of -the top-ranked net-new adoption lever from `adoption-opportunity-survey` -(Opportunity 1); the implementation contract — the *how* — lives in the -`pr-decision-surfacing` design. This records the *what and why* so the work has -a tracked home; it states positioning already recorded in ADR-036 and ADR-081 -and honours ADR-034/ADR-067, and does not alter them. +Achieved + +Delivered (epic itsthelore/rac-core#351; itsthelore/rac-ci#3 merged) under +the `pr-decision-surfacing` design's contract. The **Herald** capability — +`itsthelore/rac-ci/herald/github` — computes the merge-base diff, runs +`rac decisions-for --json` per changed path (thin client, ADR-063; the +engine owns matching and liveness), and posts one deterministic advisory +comment: id, title, matched `## Applies To` scope, and a head-pinned link +per governing decision, deduplicated, sorted, updated in place by marker on +re-runs, with a fork-safe step-summary fallback. Facts, never a verdict or +merge gate (ADR-034, ADR-067). Its structural contract and behavioral +renderer battery (join, dedup, empty state, noise cap, byte-determinism) +run in rac-ci CI, the behavioral tier against the published engine. The +docs pointer lives here (the Decisions on PRs page); the `v1` tag predates +Herald, so consumers reference `@main` until a tag that includes it is cut. + +The design's three Open Questions closed as delivered: **the action ships +in `rac-ci`** — the CI wrappers' extracted home — beside Watchkeeper, +Gatekeeper, and Registrar, while the corpus record and the docs pointer +stay here; **changed paths are computed action-side** — no engine change +and no dual-engine port, since `decisions-for` is already a covered command +under the ADR-116 dispatcher; **noise is tuned** by the engine's live-only +scoping plus dedupe-by-id, sorted output, an inline cap with a details +expander, no comment when nothing governs, and update-in-place always +(including to the empty state, so a stale comment can never outlive its +diff). The claim check the survey required came back clean. + +This roadmap is the graduation of the top-ranked net-new adoption lever from +`adoption-opportunity-survey` (Opportunity 1); the implementation contract — +the *how* — lives in the `pr-decision-surfacing` design. It states +positioning already recorded in ADR-036 and ADR-081 and honours +ADR-034/ADR-067, and does not alter them. ## Context @@ -120,3 +144,7 @@ a governed decision that is also suspect can be noted. ## Related Requirements - rac-growth-adoption + +## Related Tickets + +- itsthelore/rac-core#351