Skip to content

feat(reactor-cli): add docs-synthesis example (merged PRs → docs PR) - #131

Open
irl-dan wants to merge 4 commits into
mainfrom
example/docs-synthesis
Open

feat(reactor-cli): add docs-synthesis example (merged PRs → docs PR)#131
irl-dan wants to merge 4 commits into
mainfrom
example/docs-synthesis

Conversation

@irl-dan

@irl-dan irl-dan commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

What

A new cost-tiered Reactor example at packages/reactor-cli/examples/docs-synthesis/, parallel to agent-observatory. It watches a code repo's merged PRs and opens one PR against the public docs site (openprose/docs) to keep it current — the worked example of the Cost and Context Discipline authoring guidance (#126), i.e. the PR→docs shape that guidance was written for.

The pipeline

repo-changes (gateway)     ~free: fold merged-PR deltas (paths + diffstat, no diff)
   └─ change-signal  (cheap classifier: reads ONLY the inline changed-path list)
        ├─ #cli-signal ───────► cli-docs
        ├─ #sdk-signal ───────► sdk-docs
        ├─ #reactor-signal ───► reactor-docs
        ├─ #devtools-signal ──► devtools-docs
        └─ #openprose-signal ─► openprose-docs   each: pending edits (page + why + cited PR)
                                   └─ docs-pr  (one coalesced PR against openprose/docs)

Each of the five public-docs sections subscribes to its own signal facet, so a PR touching only packages/reactor-cli/** moves #cli-signal only — cli-docs renders, the other four memo-skip at zero cost. A test/CI-only PR emits no signal at all. Cost scales with surprise, not with the clock.

How it maps to the discipline

  • Tier; cheap gatekeeper filters surprisechange-signal is a narrow classifier (paths → signals), not a summarizer.
  • Bound each narrow render to its inline input — classifier + accumulators read only the staged PR evidence; ### Invariants forbid running git / reading the repo. They emit pointers, not diffs. Each accumulator carries its section's fixed page list in-contract.
  • Concentrate effectful work in the rare terminal nodedocs-pr is the one render whose job is to act (the Tenet-2 caveat): it may read the specific pages it edits and the cited PRs, still bounded, and fires only when a pending-edit facet moved.
  • Validate the cost-shape — committed replay/ + eval-harness (deterministic selective-wake check + opt-in judge panel).

Section → source mapping

signal facet docs section source it tracks
#cli-signal cli/ packages/reactor-cli/**
#sdk-signal sdk/ packages/reactor/** public API surface
#reactor-signal reactor/ packages/reactor/** harness behavior + concepts
#devtools-signal reactor-devtools/ packages/reactor-devtools/**
#openprose-signal openprose/ skills/open-prose/**, references/*.md

Input

Status / follow-up

  • reactor compile --check passes keyless; all contracts and the connector fixtures parse.
  • Mirrors agent-observatory, which is not registered in the examples.test.ts fake-provider gate (that single-facet seam doesn't fit a multi-node pipeline) — validation is the committed replay/ + eval-harness.
  • The committed replay/ requires a one-time keyed run (compile + serve with DOCS_SYNTH_DRY_RUN=1 so the actuator stays dry). Not included here — a guarded follow-up.

🤖 Generated with Claude Code

irl-dan and others added 4 commits June 7, 2026 15:08
A cost-tiered Reactor example, parallel to agent-observatory, that watches a
code repo's merged PRs and opens one PR against the public docs site to keep it
current. It is the worked example of the Cost and Context Discipline authoring
guidance (the PR→docs shape that guidance was written for):

- repo-changes (gateway): folds merged-PR deltas (changed-path list + diffstat,
  never the full diff).
- change-signal (cheap classifier): maps each PR's inline changed paths to
  per-section doc-impact signals, faceted so an unrelated PR wakes nobody.
- five section accumulators (cli/sdk/reactor/reactor-devtools/openprose): each
  subscribes to its one signal facet and accumulates pending edits (page + why +
  cited PR); memo-skips at zero cost otherwise.
- docs-pr (coalesced actuator): the one effectful node — reads only the pages it
  edits, drafts the .mdx changes, and opens one PR (git + gh). Dry under
  REACTOR_OFFLINE or DOCS_SYNTH_DRY_RUN, which is how the replay is produced.

Ships static PR fixtures (offline demo) and a git-log connectors.cjs.example
(live opt-in). Compile-check passes keyless. The committed replay/ + eval-harness
validation is a follow-up keyed run.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
docs-pr now operates on the docs clone at $DOCS_SYNTH_DOCS_REPO with explicit
git/gh steps (branch docs-synthesis/prs-<cited-PRs>, edit named pages, push, gh
pr create). Generic and runnable; the dry-run guard is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
All five section accumulators exposed a facet literally named `pending-edits`,
so docs-pr's five requires were ambiguous and the *-pending -> docs-pr edges
failed to wire. Rename to cli-pending / sdk-pending / reactor-pending /
devtools-pending / openprose-pending (the same distinct-naming discipline
agent-observatory uses for unambiguous wiring) and point docs-pr at each.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…icit

Point repo-changes at its upstream `inbox.json` (the phantom ingress producer)
and forbid git/filesystem inspection; point change-signal at the upstream
`changes` records and their `files` field. Clarifies the intended data path —
the connector stages PRs into the gateway's ingress, the gateway folds them, the
classifier routes by changed path.

NOTE (live-run finding): in the current CLI/SDK build the staged ingress inbox
does NOT surface as a readable upstream to the gateway render (a render's
readable upstream = its mounted inbound edges; the ingress is an unmounted
producer), so an LLM gateway cannot actually fold connector arrivals. The
canonical agent-observatory example exhibits the same empty result. Filed as
feedback; this wording is the correct intent for when that path is wired.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant