Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <url>`
Expand Down
101 changes: 101 additions & 0 deletions docs/decisions-on-pr.md
Original file line number Diff line number Diff line change
@@ -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.
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Loading