Repository navigation
feat(approve): per-doc approval level, AI sign-off where a doc allows it - #13
Merged
Merged
Conversation
A doc may now say who can sign it off: `approval: human` (the default when unset) needs a person, `approval: ai` lets an AI review alone approve it. Customer-facing docs and verbatim-blocks always need a person, and `approval: ai` on them is an error. - km approve <doc>... --by WHO [--at DATE] moves a review doc to accepted and writes approved_by / approved_at in place (no YAML round-trip), then gates it with km validate and restores it if that fails. An AI approver is written ai:<model> and is refused before any write where the level does not allow it; only a review doc can be approved. A doc whose review_by has passed (as after a demotion) is refused unless --review-by sets a new date, since the next demote would undo it; both compare with today, like demote, so a backdated --at gets no way round them. A refused doc is restored byte for byte, and CRLF docs are read like every other km command reads them. - km validate fails an accepted doc whose ai: approver its level does not allow. It is metadata, not authentication, like the rest of the gate. - reviewed_by (list) records pre-reviews, such as a PR bot's model, date and PR. It is not an approval: promote and --replace drop it with the approval, and a cross-repo promote also drops approval, so the target brain decides its own level. - status_rules keys are now read generically as <status>_<requires|recommends|forbids>, so accepted_requires (and any renamed served status) needs no code of its own, and a malformed key fails fast instead of being ignored; a key the brain adds must also name a status the schema knows, while km's own keys stay valid in a brain that renames its statuses. The team template now requires owner and review_by for accepted, which its CONVENTIONS already stated. The rule lives in one place, km.common.approval_problem, shared by approve and validate, and keys on the configured served status, not the literal word "accepted".
Merged
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.
What
A doc can now say who may sign it off.
approvalhumanapproved_by)aiapproved_by: "ai:<model>"audience: customerortype: verbatim-blockapproval: aithere is an errorkm approve <doc>... --by WHO [--at DATE] [--review-by DATE]:reviewdoc to the served status and writesapproved_by/approved_atin place, then gates it withkm validate;review_bythat has passed or can't be parsed, since the nextkm demotewould undo the approval;km validate:ai:approver its level does not allow, keyed on the configured served status;km.common.approval_problem, shared with approve.reviewed_by(list): records pre-reviews, such as a PR bot's model, date and PR. It is not an approval.promoteand--replacedrop it with the approval. A cross-repo promote also dropsapproval, so the target decides its own level.status_rules:<status>_<requires|recommends|forbids>, soaccepted_requiresneeds no code of its own;ownerandreview_byfor accepted docs, which its CONVENTIONS already stated.It is metadata, not authentication, like the rest of the gate.
Verification
ai:withoutapproval: aiis refused before writing;km approvesigns the doc off;approval: aiafterwards failskm validate./simplifyran, then three review passes. The findings are fixed and each has a test:review_byaccepted, including through a backdated--ator a past--review-by;status_rulessilently ignored;review_bypassing.Not changed
km demotekeepsreviewed_by, since the text it describes has not changed.