Use with generated knowledge systems
adrkit and generated knowledge systems solve adjacent problems:
- adrkit records why and governs change. Human-reviewed ADRs carry lifecycle
state, typed relationships, and
affectsmatchers that let CI and agents find the decisions governing a path. - Generated knowledge describes the system as it exists now. Tools such as OpenWiki can synthesize browsable architecture documentation and reconnect factual claims to source evidence as the implementation changes.
Use both layers when you want generated current-state documentation without giving generated content authority over human decisions.
Keep ownership explicit
Section titled “Keep ownership explicit”| Artifact | Owns | Written by |
|---|---|---|
docs/adr/** |
Ratified intent, alternatives, lifecycle, typed relationships, and what a decision affects | People and agents through the repository’s normal pull-request review |
| Source and tests | Current implementation and executable behavior | The product development workflow |
openwiki/INSTRUCTIONS.md |
Human-reviewed instructions that constrain the generated projection | People and agents through a separate pull request |
Other Markdown plus OpenWiki claims and manifest JSON under openwiki/** |
Generated explanations, claims, and current-state architecture projections | OpenWiki through its own update workflow |
OpenWiki-managed blocks in AGENTS.md and CLAUDE.md |
Pointers that help coding agents discover the generated wiki | OpenWiki within its documented marker boundaries |
An OpenWiki page may cite an ADR and explain it. It must not accept, reject, deprecate, supersede, or rewrite that ADR. When implementation and an accepted record disagree, preserve both facts and route the discrepancy to people.
Configure the two workflows separately
Section titled “Configure the two workflows separately”Run the adrkit governing-decisions Action on source pull requests. It resolves the accepted records that govern changed files and comments on the pull request where the change is being reviewed:
name: ADR governing decisions
on: pull_request:
permissions: contents: read pull-requests: write
jobs: governing-decisions: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: mbeacom/adrkit/packages/ci@v0Configure OpenWiki updates independently, using its
current automation guide.
Keep generated documentation under openwiki/**, allow only OpenWiki’s managed
blocks in AGENTS.md and CLAUDE.md, and keep model credentials and update
failures out of the adrkit job. An OpenWiki update may open a documentation pull
request after source changes land; it should not become a prerequisite for
adrkit’s deterministic pull-request context.
Preserve the explicit add-paths allowlist from OpenWiki’s
reference GitHub workflow.
Do not copy its credential persistence unchanged for this boundary. GitHub
permissions apply to a whole job, not one step, so run generation and
publication in separate jobs. The generator receives a read-only token and no
persisted git credential. A fresh publisher job receives the write credential
only after the protected-path guard succeeds.
Save the workflow as .github/workflows/openwiki-update.yml. Before enabling
it, configure:
- repository variable
OPENWIKI_MODEL_ID; - repository secret
OPENAI_API_KEYfor the OpenAI example below, or the provider-specific credential documented by OpenWiki; and - repository secret
OPENWIKI_PR_TOKEN, containing a fine-grained token withcontents:writeandpull-requests:write.
name: OpenWiki update
on: workflow_dispatch: schedule: - cron: '0 8 * * *'
# The ambient token is read-only. OPENWIKI_PR_TOKEN is a fine-grained token with# contents:write and pull-requests:write, stored as a repository secret and# passed only to the final action.permissions: contents: read
concurrency: group: openwiki-update-${{ github.repository }} cancel-in-progress: false
jobs: generate: runs-on: ubuntu-latest steps: - name: Check out without generator write credentials uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 0 persist-credentials: false
- name: Set up Node.js uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: '22'
- name: Build the reviewed OpenWiki source revision shell: bash run: | source_dir="$RUNNER_TEMP/openwiki-source" git init "$source_dir" git -C "$source_dir" remote add origin https://github.com/langchain-ai/openwiki.git git -C "$source_dir" fetch --depth=1 origin c666f4262e4340e5675fa9804bb342b87bf87f1a git -C "$source_dir" checkout --detach FETCH_HEAD corepack enable ( cd "$source_dir" pnpm install --frozen-lockfile pnpm run build )
# This example uses OpenAI. Substitute the provider-specific environment # documented by OpenWiki when you use another provider. - name: Run OpenWiki run: | : "${OPENWIKI_MODEL_ID:?Set repository variable OPENWIKI_MODEL_ID}" : "${OPENAI_API_KEY:?Set repository secret OPENAI_API_KEY}" node "$RUNNER_TEMP/openwiki-source/dist/cli/cli.js" code --update --print env: OPENWIKI_PROVIDER: openai OPENWIKI_MODEL_ID: ${{ vars.OPENWIKI_MODEL_ID }} OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
- name: Remove transient run state run: rm -f -- openwiki/.run.json
# Comparing with GITHUB_SHA catches staged, unstaged, and locally committed # changes. The second check catches new untracked protected files. - name: Protect human-reviewed integration controls shell: bash run: | protected=( docs/adr openwiki/INSTRUCTIONS.md AGENTS.md CLAUDE.md .github/CODEOWNERS .github/workflows/openwiki-update.yml ) if ! git diff --exit-code "$GITHUB_SHA" -- "${protected[@]}"; then echo 'OpenWiki modified tracked protected paths; refusing publication.' >&2 exit 1 fi untracked="$(git ls-files --others -- "${protected[@]}")" if [[ -n "$untracked" ]]; then printf 'OpenWiki created protected paths:\n%s\n' "$untracked" >&2 exit 1 fi
# Archive only generated output. The user-authored brief was already # proven unchanged and is excluded from the handoff. - name: Package generated output shell: bash run: | if [[ ! -d openwiki || -L openwiki ]]; then echo 'OpenWiki output root must be a real directory.' >&2 exit 1 fi invalid=() while IFS= read -r -d '' path; do invalid+=("$path") done < <(find openwiki -mindepth 1 ! -type f ! -type d -print0) while IFS= read -r -d '' path; do case "$path" in openwiki/INSTRUCTIONS.md | openwiki/*.md) ;; openwiki/.claims/*.json | openwiki/.last-update.json | openwiki/.page-manifest.json) ;; *) invalid+=("$path") ;; esac done < <(find openwiki -type f -print0) while IFS= read -r -d '' path; do invalid+=("$path") done < <(find openwiki -type f -perm /111 -print0) if (( ${#invalid[@]} )); then printf 'OpenWiki created unsupported or executable output:\n' >&2 printf ' %q\n' "${invalid[@]}" >&2 exit 1 fi tar \ --exclude='openwiki/INSTRUCTIONS.md' \ --exclude='openwiki/.run.json' \ -czf "$RUNNER_TEMP/openwiki-output.tgz" \ openwiki
- name: Upload generated output uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: openwiki-${{ github.run_id }} path: ${{ runner.temp }}/openwiki-output.tgz if-no-files-found: error
publish: needs: generate runs-on: ubuntu-latest steps: - name: Check out a fresh publishing workspace uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: persist-credentials: false
- name: Download generated output uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: name: openwiki-${{ github.run_id }} path: ${{ runner.temp }}/openwiki-artifact
- name: Replace generated files while preserving the brief shell: bash run: | mkdir -p "$RUNNER_TEMP/openwiki-candidate" tar -xzf "$RUNNER_TEMP/openwiki-artifact/openwiki-output.tgz" \ -C "$RUNNER_TEMP/openwiki-candidate" rsync -a --no-links --delete --exclude '/INSTRUCTIONS.md' \ "$RUNNER_TEMP/openwiki-candidate/openwiki/" openwiki/
- name: Create OpenWiki update pull request uses: peter-evans/create-pull-request@22a9089034f40e5a961c8808d113e2c98fb63676 # v7 with: token: ${{ secrets.OPENWIKI_PR_TOKEN }} add-paths: | openwiki branch: openwiki/update commit-message: 'docs: update OpenWiki' title: 'docs: update OpenWiki' body: | Automated OpenWiki documentation update.
Keep this pull request in draft until a reviewer confirms that ADR lifecycle states, applicability, relationships, and source links agree with the cited decision records. draft: always-true signoff: trueUnlike the upstream reference workflow, this stricter adaptation does not publish partial output: a failed OpenWiki run stops before artifact handoff and PR creation. At minimum, enable GitHub Actions failure notifications and compare the workflow’s last successful run with its expected schedule. A green adrkit check means the decision corpus and governing-decision resolution succeeded—it does not mean the generated wiki is current.
Treat openwiki/update as automation-owned. Do not push reviewer fixup commits
to it; change the source, brief, or workflow on the default branch and rerun the
update instead.
Give OpenWiki a read-only decision brief
Section titled “Give OpenWiki a read-only decision brief”Add guidance like the following to the repository’s
openwiki/INSTRUCTIONS.md:
# Decision records
Treat `docs/adr/**` as read-only normative decision evidence.
- Never create, edit, delete, accept, reject, deprecate, or supersede an ADR.- Preserve each record's id and link to the original file.- Present `accepted` records as ratified decisions. Call one governing for a target only when `adr check` or `adr explain` reports it through a matching `affects` declaration or inbound `@adr` marker; do not reimplement resolution.- Present `draft` and `proposed` records as under review, not as current policy.- Keep `rejected`, `superseded`, and `deprecated` records in decision history.- Preserve `scope`, `affects`, and marker provenance where the consuming contract exposes them. Label `supersedes`, `supersededBy`, `relatesTo`, and `conflictsWith` relationships explicitly.- Label every ADR-derived page as a non-authoritative generated projection and record the source ADR-corpus git revision.- When code differs from an accepted ADR, report the mismatch for human review. Do not revise the ADR or infer a new decision from implementation alone.- Treat machine verification of generated content as documentation provenance, not as human ratification of a decision.This brief lets OpenWiki use the corpus as evidence while preserving the distinctions that make the corpus useful to review and retrieval.
Enforce the write boundary outside the prompt
Section titled “Enforce the write boundary outside the prompt”openwiki/INSTRUCTIONS.md is guidance to the documentation agent, not a
repository permission boundary. Pair it with controls the generated workflow
cannot reinterpret:
- Keep scheduled update commits limited to non-executable Markdown, JSON below
openwiki/.claims/, and OpenWiki’s two root JSON manifests. Fail the run ifopenwiki/INSTRUCTIONS.mdchanges. Establish changes to that brief,AGENTS.md,CLAUDE.md, and the workflow in a separate human-reviewed pull request. - Add
docs/adr/**,openwiki/INSTRUCTIONS.md,AGENTS.md,CLAUDE.md, and the OpenWiki workflow toCODEOWNERS. - Where a distinct reviewer is available, configure branch protection or a ruleset to require that review. CODEOWNERS alone requests review but does not make it mandatory. In a sole-maintainer repository, requiring the sole code owner to approve their own change deadlocks the normal path or leaves an administrator bypass as the routine escape; rely on credential isolation, the base-commit guard, and the committed-path allowlist as the hard automation boundary instead of claiming independent approval.
- Keep OpenWiki’s managed blocks in
AGENTS.mdandCLAUDE.mdlimited to pointers that help agents find the wiki. Review any change outside the documented markers as an ordinary source change. - Open every generated-documentation pull request as a draft. Do not enable automatic merging; a reviewer must first compare ADR lifecycle, applicability, relationship, and source-link claims with the cited records.
For example:
# .github/CODEOWNERS/docs/adr/ @your-architecture-reviewers/openwiki/INSTRUCTIONS.md @your-architecture-reviewers/AGENTS.md @your-architecture-reviewers/CLAUDE.md @your-architecture-reviewers/.github/workflows/openwiki-update.yml @your-architecture-reviewersThese controls keep an instruction-following failure from becoming a decision lifecycle change.
Do not translate unlike lifecycle states
Section titled “Do not translate unlike lifecycle states”OKF v0.2 defines document lifecycle states such as draft, stable, and
deprecated, plus machine- and human-verification events. These describe the
knowledge document. adrkit’s accepted, rejected, and superseded states
describe the outcome and history of a decision.
Do not map:
- adrkit
acceptedto OKFstableas proof that a decision was ratified; - OpenWiki machine
verifiedto adrkitprovenance.ratifiedBy; or - a stale generated Claim to a violated or superseded ADR.
A source change means evidence needs another look. It proves a violation only when an applicable deterministic assertion actually evaluates and fails.
Expected change flow
Section titled “Expected change flow”- A source pull request changes files.
- adrkit reports the accepted decisions governing those files on that pull request.
- People review the source change against those decisions.
- After merge, OpenWiki refreshes the generated description and its source evidence in a separate update.
- If the implementation and decision no longer agree, people either correct the implementation or propose a new ADR that explicitly supersedes the old decision.
Recover from a generated-output breach
Section titled “Recover from a generated-output breach”If a generated-documentation change reaches a protected path or misrepresents an ADR’s lifecycle, applicability, relationship, or source:
- Disable the update workflow before its next scheduled run.
- Open a human-reviewed revert pull request that restores any protected paths
and generated claims to their last reviewed state, and verify
.github/CODEOWNERSwas not weakened. Do not hide the event by rewriting shared history. - Run
adr lintandadr checkagainst the restored corpus and affected source paths. - Review generated-documentation pull requests since the last known-good run for the same boundary crossing.
- Correct the brief or output grammar that admitted the breach, regenerate from the last reviewed source revision, and confirm the branch-protection or ruleset configuration still enforces its intended review policy before re-enabling automation.
The same boundary applies to other generated knowledge systems: consume and project the decision corpus, but leave decision authority in its reviewed git history.