Repository navigation
Add the kb-gate verifier, its pinned bundle and workflow - #209
Conversation
The repository-side required check for knowledge PRs. - knowledge_service/gate_verifier: verifies a knowledge change from git objects only (the PR is never checked out or executed). A change that does not touch knowledge/ passes. A knowledge change needs a valid Ed25519 verdict bound to this repository, PR and exact head, inside its issue window; a signed manifest equal to the change as applied (base independent); L1 on the change and on the tree that would land. Rules it retires or purges must not be cited anywhere in that landing tree. For auto: a block table equal to the L1 blocks, all passing, and consistency judgements covering the same owner directories whose page hashes match the landing tree. The context set must not have changed between the judged base and the effective base. For human-approved: the bound reviews are still APPROVED on this head, one of them by a knowledge maintainer (CODEOWNERS of .github/kb-gate/), and the label is present; the approval replaces the auto-merge whitelist (knowledge/tools, skills, scripts, mixed PRs) but not the rest of L1. In both cases: no kb:hold, and the signed hold list is fresh and holds neither the PR nor its scope (repository name, or "general" for knowledge/general/). It fails closed without a public key, a hold-list URL, an attributable merge group, or with upstream fact attestations it cannot re-check. - Two stages under one name: the PR precheck (pull_request_target, verdict comments, dispatch) posts the kb-gate status on the head it verified; the merge_group job verifies every first-parent segment (two-parent merge commits, PR looked up by its head) against its own first parent. - tools/build_kb_gate_bundle.py vendors the verifier and its L1/lifecycle/ops/ signing/verdict siblings into .github/kb-gate/, with a hash-pinned requirements.lock and MANIFEST.sha256; the workflow installs with --require-hashes and runs only from there. The CI --check is a reminder and does not block. - .github/CODEOWNERS makes knowledge maintainers own .github/, knowledge/tools, knowledge/skills and knowledge/.claude; governed pages have no code owner. - test.yml also runs on merge_group (a merge-queue prerequisite). Not in this change: the service does not yet issue human-approved verdicts (polling kb:human-approved and checking the approval); until then only auto verdicts exist. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 182a8c15eb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| for review_id in verdict.get("review_ids") or []: | ||
| review = ctx.github.get(f"/repos/{ctx.repository}/pulls/{number}/reviews/{int(review_id)}") | ||
| login = str((review.get("user") or {}).get("login") or "").lower() | ||
| if review.get("state") != "APPROVED": |
There was a problem hiding this comment.
Reject approvals superseded by a later review
Fetching only each signed review ID does not establish the reviewer's current decision: when a maintainer approves and later submits a new CHANGES_REQUESTED review, GitHub creates another review while the earlier review object can remain APPROVED. The old signed ID therefore still adds that maintainer to approvers, allowing a human-approved verdict—which bypasses L2 and the automatic path whitelist—to pass after its approval was withdrawn. Evaluate the latest effective review state for each bound reviewer (or the PR's aggregate review decision), not only the historical review objects named in the verdict.
Useful? React with 👍 / 👎.
PR 6 of the knowledge-service redesign: the repository-side required check
kb-gate.knowledge_service/gate_verifier.py, vendored into.github/kb-gate/):kb:hold, and a fresh signed hold list that doesn't hold the PR or its scope.pull_request_target/ verdict comments / dispatch): posts thekb-gatestatus on the verified head.merge_groupjobkb-gate: verifies every first-parent segment against its own first parent.tools/build_kb_gate_bundle.pygenerates it;requirements.lockis hash-pinned (verified to install with--require-hasheson 3.12);MANIFEST.sha256is checked before the verifier runs; CI--checkis a non-blocking reminder..github/CODEOWNERS: maintainers own.github/,knowledge/{tools,skills,.claude}; governed pages have no code owner on purpose.test.ymlgainsmerge_group.Effect once merged: every PR gets a
kb-gatestatus. Code PRs pass. Knowledge PRs fail closed until the owner commits.github/kb-gate.pub, setsholds_urlin.github/kb-gate/config.json, and adds a second maintainer to CODEOWNERS. The check is not required until the ruleset is configured.Not in this PR: the service does not yet issue human-approved verdicts.
Commit hook approved; full suite, SPEC freshness and doc linters pass locally.
🤖 Generated with Claude Code