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
1 change: 1 addition & 0 deletions .github/knowledge-model-policy.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
".github/knowledge-model-policy.json",
".github/workflows/knowledge-model-policy.yml",
"tools/check_knowledge_model_policy.py",
"tools/run_knowledge_model_policy.sh",
"docs/knowledge-model-policy.md"
],
"models": {
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/knowledge-model-policy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ jobs:
- name: Evaluate declarations with trusted main code
env:
GITHUB_TOKEN: ${{ github.token }}
run: python tools/check_knowledge_model_policy.py --policy-sha "$(git rev-parse HEAD)"
run: bash tools/run_knowledge_model_policy.sh
67 changes: 58 additions & 9 deletions docs/knowledge-model-policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,14 @@ Unlinked Git identities cannot be inferred by CI. PR number, head, exact scope
require renewed approval. Exceptions cannot excuse malformed/missing attribution;
explicitly unknown settings may be considered by the approval owner.

Changes to the config, checker, metadata workflow or this document need an
independent owner approval of kind `policy-change`, listing exactly the changed
policy-control paths and a specific reason. This is separate from author
eligibility. One comment may contain both kinds in `approvals`. Checks use the
`policy_paths` classifies changes to this mechanism — the policy config, this
checker, the metadata workflow, the runner and this document — and reports them in
each result. Classification is not a gate: a policy-only change does not fail for
lack of a separate approval, and passing it is not a statement about content
quality. Nothing in this mechanism grants an exception: an approval of kind
`policy-change`, including historical comments, cannot excuse protected knowledge
changes or substitute for knowledge author admission. One comment may still carry
both kinds in `approvals`; only the `exception` kind is evaluated. Checks use the
target branch's policy, never the PR's proposed replacement.
Each authorized account's latest comment containing the approval fence replaces
its earlier declarations. Use `decision: "revoke"` to revoke its grants. Comment
Expand All @@ -127,11 +131,56 @@ open PRs is ineligible, even if one PR declares compliant authorship or receives
PR-specific exception. The checker reads all open repository PRs, across target
branches and API pages, and requires a unique head both before evaluation and
before publishing its result. Close the extra PR or use a distinct commit before
retrying. An exception cannot bypass head uniqueness. Each refresh reads the full
open-PR collection once before evaluation and once before publication, with API
pagination in both scans. Results remain pending until the second scan revalidates
head ownership and PR metadata; applicable approvals are reread before publication.
The collection request count scales with its page count, not page count times PRs.
retrying. An exception cannot bypass head uniqueness. A closed peer no longer
shares the head: the remaining open PR is evaluated on its own metadata and
receives its own verdict. The checker reads the full open-PR collection once
before evaluation and once before publication, with API pagination in both scans.
Results are published only from that fresh scan, and only for a target that is
still open against the policy branch with an unchanged head; applicable approvals
are reread before publication. The collection request count scales with its page
count, not page count times PRs.

## Lifecycle and reruns

A merged or closed PR that is no longer part of the sweep receives no new status;
its earlier verdict stays historical. Publication never targets a captured head
for work whose base advanced or whose head changed. One evaluation pass is
followed by a publication pass that re-reads the target. If the head, base, body
or approvals moved, or if head ownership changed because a peer closed, the checker
reassesses once against the current metadata and the current open-PR collection
before writing. A green is published only from a verified premise; when the
open-PR collection cannot be read, an otherwise compliant target is recorded as
`unverified` with a failed status instead of keeping its old success. If the target
itself cannot be re-read, no status is written to the captured head because it may
already be merged; the run reports that the old status could not be invalidated,
which is a real limitation, not a fail-closed result.

When the trusted base advances mid-sweep, the checker returns a retryable result
promptly instead of re-evaluating against its own stale checkout. It exits `2`,
and trusted `tools/run_knowledge_model_policy.sh` refetches `main` and runs the
checker again from the current code and policy. The runner is the single retry
owner with a bounded budget; after exhaustion the workflow run fails. Open PRs
remain fail-closed in every case: stale work is never published as compliant, and
an old green is never retained in place of a valid evaluation.

Each result carries `kind` alongside the status `state`:

| `kind` | Meaning |
| --- | --- |
| `compliant` | Declaration and approvals satisfy the trusted policy |
| `noncompliant` | Genuine rejection: declaration, approval or head eligibility (including a shared head) |
| `evaluator-error` | GitHub API or incomplete evidence; never a rejection |
| `unverified` | Compliance could not be published without unverified lifecycle or ownership metadata |
| `deferred` | Work could not be completed in this run; rerun required |
| `closed` | Target left the sweep; no status was written |
| `publication-failed` | Status write failed; the verdict was not recorded |

The final JSON summary counts each kind, lists the `noncompliant_pull_requests`, and
states the sweep `execution` as `ok`, `failed` or `unfinished`. Exit codes: `0`
the sweep completed (any number of individual rejections are their own red
statuses), `1` an execution error, `2` unfinished work to rerun. A rerun never
overrides a recorded rejection. A rejection belongs to its own PR: one PR's
rejection neither greens nor fails another PR's status.

The workflow handles PR open/reopen/close/commits/body-or-base edits on any target
branch (a PR against another base can share a main PR's head), approval-comment
Expand Down
Loading
Loading