feat(docs-sync): gh-aw hub, agent knowledge base and release notes (IP-2864, IP-2863, IP-2866) - #18
Open
DemidovVladimir wants to merge 3 commits into
Open
feat(docs-sync): gh-aw hub, agent knowledge base and release notes (IP-2864, IP-2863, IP-2866)#18DemidovVladimir wants to merge 3 commits into
DemidovVladimir wants to merge 3 commits into
Conversation
…P-2864, IP-2863, IP-2866) The docs-repo half of the docs-sync pipeline from the IP-2745 spike. Inert until the credentials in IP-2861 exist and this lands on the default branch. DOCS-4 (IP-2864) — .github/workflows/docs-sync.md + compiled docs-sync.lock.yml Triggered by repository_dispatch (docs-sync) from desci-infra on release. Pinned to gh-aw v0.85.4, outside the 0.68.4-0.71.3 billing bug. The agent job is contents:read; every write happens in the separate sanitized safe-outputs job. Verified in the generated lock. A deterministic relevance gate runs in pre_activation, before the agent job exists, so a release touching no documented surface costs zero AI credits. It uses one compare API call, not a clone. skip-if-match cannot do this - it evaluates GitHub search queries, not changed paths. stop-after +14d bakes the DOCS-7 pilot expiry to an absolute timestamp. DOCS-3 (IP-2863) — .github/prompts/docs-sync.md Page-to-source map, house style, guardrails and the PR body contract. Points the agent at hand-authored sources and away from graphql/autogen and prisma/generated, which are build artefacts. DOCS-6 (IP-2866) — release-notes/ + SUMMARY.md Consumer-facing per-version notes, complementing the thematic api-reference/changelog.md. Seeded from release 1.0.14, whose isSuccess removal is verifiable in PR #652 of desci-infra. DOCS-2 (IP-2862) is materialized here as close-older-pull-requests: true. A rolling sync PR is not achievable - create-pull-request calls pulls.create unconditionally and can never update an existing PR. Rationale and the alternatives are recorded in desci-infra/docs/docs-sync-write-strategy.md. Security review of new restricted secrets, per gh-aw safe update mode: ANTHROPIC_API_KEY - engine key, same org key the other repos already use. DOCS_SYNC_APP_KEY - private key of a GitHub App holding contents:read on desci-infra and nothing else. Neither grants write on any source repo. The compiled lock excludes both from the agent container and redacts them in logs. Verified: gh aw compile, gh aw validate --strict, gh aw lint all clean. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Drops the hand-written 1.0.14 entry. The entry-format template in release-notes/README.md is the whole specification; a worked example was a marginal gain and it was the only content in this PR asserting facts to external integrators on a public site. The first real entry now comes from a pilot run, which also exercises the pipeline properly. Removes the same assumption from the agent knowledge base, which told the agent to imitate examples that no longer exist. Note the 1.0.14 breaking change this entry described is real and still undocumented: 43 references to the removed isSuccess field remain across 9 reference pages. Tracked separately - it needs the reference pages corrected, not a release-notes entry. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…e, close IP-2864 AC gaps - Re-pin v0.85.4 -> v0.86.2 and record the pin + its reason in the workflow header (IP-2864 AC). v0.86.2 carries the Claude-harness retry fix (github/gh-aw#51793) whose trigger scenario is exactly this workflow's engine + strict bash allow-list, plus enforced secret redaction in step summaries and patch artifacts (#50777/#50778). Verified behaviour-neutral for the DOCS-2 write strategy: safe-output schemas and the close_older_pull_requests handler are unchanged between the two versions. - Release notes now travel hub-side, not in the dispatch payload: a pre-agent step mints a token from the read-only source App (Releases API is covered by contents: read - no permission change) and writes the body to ./source/RELEASE_NOTES.md. The payload lands in a public repo's workflow run, and source release bodies now carry real content naming private infrastructure (desci-infra 2.0.0, 2026-08-12). Contract change lands in desci-infra#675 in the same breath. - Add the claude-code-action fallback note (IP-2864 AC), flag it as unvalidated for repository_dispatch. - Relevance gate: add docs/service-auth.md (mapped for authentication and roles pages, previously unreachable); document that the gate is a deliberate triggering subset of the map, with the ride-along rows named in the knowledge base. - Knowledge base: account for the previously unmapped pages (technical-deep-dive/onchain-lab.md, module-registry/**, data/README.md, and the orphan api-reference/IPNFT-api.md) in the out-of-scope list. - stop-after refreshed at compile: expiry is now 2026-08-28 10:16:52. If this PR has not merged by then, run `gh aw compile --refresh-stop-time` again before merging or the pilot arrives expired. Recompiled with gh-aw v0.86.2; `gh aw validate --strict` and `gh aw lint` both clean; agent job verified still contents: read only, bots allow-list and max-ai-credits unchanged in the regenerated lock. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
The docs-repo half of the docs-sync pipeline from the
IP-2745 spike. Implements DOCS-4
(IP-2864), DOCS-3
(IP-2863) and DOCS-6
(IP-2866).
The spoke half lives in moleculeprotocol/desci-infra#675.
What lands
.github/workflows/docs-sync.md+.lock.yml.github/prompts/docs-sync.mdrelease-notes/**+SUMMARY.md.github/aw/actions-lock.json,.gitattributesgh aw compile. Pins every action to a SHA.This is inert on merge. Nothing runs until the credentials in
IP-2861 exist. Until then a dispatch is accepted with
204and does nothing.gh-aw pin: v0.86.2
Pinned and documented in the workflow header (with the reason — an IP-2864 acceptance criterion).
History: v0.85.4 was chosen 2026-08-07 to stay clear of the 0.68.4–0.71.3 billing bug; bumped to
v0.86.2 on 2026-08-14 for the Claude-harness retry fix
(github/gh-aw#51793 — at v0.85.4 a
permission_deniedon a compound bash command could burn the whole retry budget, and this workflow's
engine: claude+ strict bash allow-list is exactly that scenario) and for enforced secretredaction in step summaries and patch artifacts (#50777/#50778). The bump is behaviour-neutral for
the write strategy: safe-output schemas and the
close_older_pull_requestshandler are unchangedbetween the two versions.
How it works
desci-infrafires arepository_dispatch(docs-sync) on each production release. The hub then:pre_activation, before the agent job exists. One compare API call, noclone. A release touching no documented surface stops here at zero AI credits — which is most
releases. The gate is a deliberate triggering subset of the knowledge-base map; ride-along
surfaces (deprecated IPNFT lambdas, secondary
lib/stacks) update only when a triggering pathchanged in the same release.
desci-infraout at the released SHA into./source../source/RELEASE_NOTES.mdwith the same read-only App(
pre-agent-steps, on the runner, outside the agent container). The dispatch payload no longercarries the notes: it lands in a public repo's workflow run, and source release bodies now carry
real content naming private infrastructure (desci-infra 2.0.0, 2026-08-12). The Releases API is
covered by
contents: read, so the App's permission set is unchanged.Security review
Required by
gh aw compile's safe-update mode, which flagged two new restricted secrets.New secrets
ANTHROPIC_API_KEY— the engine key. The same org keydesci-infra,desci-ecosystemandLabsalready use forclaude-review.ymlandclaude-release-notes.yml. gh-aw's Claude enginerequires an API key as an Actions secret; provider OAuth is unsupported.
DOCS_SYNC_APP_KEY(+ variableDOCS_SYNC_APP_CLIENT_ID) — private key of a GitHub App holdingcontents: readondesci-infraand nothing else. It mints a ~1h token scoped per run to asingle repo. It cannot write anywhere, and it is not installed on this repo.
Neither grants write access to any source repository. The only cross-repo write credential in
the whole design is the dispatch credential, and it lives in
desci-infraand points at thisrepo — which is the property the hub-and-spoke shape exists to preserve.
Verified in the generated
.lock.ymlafter the v0.86.2 recompile, not assumed:agentjob haspermissions: {contents: read}. Every write happens in the separatesafe_outputs/conclusionjobs. gh-aw's strict mode rejects a write permission on the agent jobat compile time.
--exclude-env) and registered for logredaction. The release-body fetch runs on the runner, outside the container — its token never
enters the agent's environment.
defaultsallow-list.actions/checkout@3d3c42e…v7.0.1,actions/create-github-app-token@bcd2ba4…v3.2.0,gh-aw-actions/setup@6aab9e5…v0.86.2).Prompt-injection posture. The release body originates in a pull-request description and is
untrusted. The knowledge base instructs the agent to treat
./source/RELEASE_NOTES.mdas data tosummarise, never as instructions, and to report anything that looks like directions addressed to it.
Structurally the agent is read-only and cannot push — it can only emit a PR through the sanitised
safe-output job.
DOCS-2: the write strategy, and why it isn't a rolling PR
IP-2745 wanted the agent to append to one long-lived sync PR. Verified against the shipped handler
source at v0.85.4 (and re-checked at v0.86.2):
create-pull-requesthas onepulls.createcall and zeropulls.update/pulls.listcalls,and no
branch:key. It can never update an existing PR.push-to-pull-request-branchcannot bootstrap a PR, and underrepository_dispatchits defaulttarget: "triggering"hard-fails. A rolling PR is technically constructible viatarget: "*"(the agent supplies the PR number itself) — the decision record explains why werejected that shape: more prompt surface, PR-list access for the agent, and a wider push blast
radius than "create a fresh draft".
update-pull-requestcannot create.So: new PR per run +
close-older-pull-requests: true, which delivers the property actuallywanted — at most one open docs PR at a time — with no force-push or lost-review-history hazards.
Quick-succession dispatches serialize under the compiled workflow's concurrency group, so two runs
never race. Full rationale in
desci-infra/docs/docs-sync-write-strategy.md.The trade-off, stated plainly: an unreviewed docs PR is closed, not merged, when the next
release lands. The relevance gate keeps the real rate well below the release rate, and closed
branches are not deleted, so nothing is unrecoverable.
Pilot expiry is built in
stop-after: +14dis baked to an absolute 2026-08-28 10:16:52 UTC (refreshed at the v0.86.2recompile), after which the trigger auto-disables. A plain recompile preserves the baked time —
it can only be extended deliberately, via
gh aw compile --refresh-stop-time.arrives already expired.
Release notes (DOCS-6)
New
release-notes/section, one page per API area, newest-first. It complementsapi-reference/changelog.mdrather than duplicating it: this section answers "what shipped in1.0.14", that page answers "how do I migrate off
ipnftUid". Cross-linked both ways.The section ships unseeded, on purpose (commit aecc762): the entry-format template in
release-notes/README.mdis the whole specification, and a hand-written worked example was the onlycontent in this PR asserting facts to external integrators. The first real entry comes from a pilot
run, which also exercises the pipeline properly. (Linear note: IP-2866's "seeded with real past
releases" AC should be amended to record this deviation.)
Known debt tracked separately: 43 stale
isSuccessreferences across 9 reference pages from the1.0.14 error-contract cutover.
Verification
gh aw compile(v0.86.2),gh aw validate --strictandgh aw lintall exit clean, and arecompile produces zero drift against the committed lock. All
SUMMARY.mdand inter-page linksresolve.
Not verifiable until DOCS-1 lands: an end-to-end run.
gh aw trialcannot help — it requiresworkflow_dispatch, which this workflow does not have — so the first real exercise is the runbook'smanual dispatch test.
Two things to know before merging
repository_dispatchonly triggers workflows on the default branch. This must be onmainbefore any dispatch does anything; it cannot be tested from this branch.
bots:allow-list must match the App slug exactly.repository_dispatchis not a gh-aw"safe event", so the pre-activation membership check runs against
github.actor. Ifmolecule-docs-sync[bot]does not match the App created in DOCS-1, every run is rejectedsilently. Confirm the literal actor string from the first run's
pre_activationlog.🤖 Generated with Claude Code