You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Mint one Ed25519 key per reviewing workstation (public key in the repo, private key in that Bot's secret store) #1111
Split out of #1110: the code half is a Bot's, this half needs the owner. Ed25519, one keypair per reviewing workstation (the earlier HMAC wording on this issue is dead — a shared key has to live in Actions, so it is a repository secret that anyone who can start a workflow could use).
What the owner does, exactly
Per workstation, starting with Reviewer and then Reviewer2:
Keep the .pem wherever you are comfortable generating keys. It never goes into this repository, this issue, a group message, or any command whose output is posted.
Paste the base64url DER line from the second command into this issue — a public key is safe to post.
Put the private key into that workstation's own secret store through its secure card: DSH_SECRET_VERDICT_KEY_REVIEWER, DSH_SECRET_VERDICT_KEY_REVIEWER2. That is the one channel where the Bot can use the key without printing it.
Why a Bot must not generate its own key
Every Bot runs as the same OS user on the same machine, so a key file written by one Bot is readable by all of them. Only the per-Bot secret store has a boundary, and only the owner can write to it.
Acceptance
both public keys are posted here (base64url DER, ~60 characters each);
each workstation can sign a throwaway verdict and that signature verifies under its published public key, and under nothing else;
Reviewer's key does not verify Reviewer2's signature, and vice versa;
no private key, seed, or PEM body ever appears in the repository, this issue, or the group.
Blocking
#1110 must not merge before the two public keys exist: its verifier is fail-closed with no unsigned window, so a verifier on main without keys would freeze every merge at once. Once the keys are in place, #1110 lands and both workstations can sign from that minute.
Rewritten for Ed25519 — the HMAC version of this issue is dead (a shared key has to live in Actions, so it is a repository secret). #1110 carries the format; this is the key handoff, and only the owner can do it.
What the owner does, exactly
Per workstation (start with Reviewer, then Reviewer2):
Keep reviewer.pem wherever you are comfortable generating keys — it never goes into a chat, a file in this repo, or a shell command whose output is posted.
Paste the base64url DER line (the second command's output) into this issue — a public key is safe to post.
Put the private key into that workstation's own secret store through its secure card, as DSH_SECRET_VERDICT_KEY_REVIEWER (and …_REVIEWER2). That is the one channel where the Bot gets the key without ever printing it.
Why not let the Bot generate its own key
Every Bot runs as the same OS user on the same machine, so a key file written by one is readable by the others — that would put the private half back in a shared place, which is exactly what this issue exists to prevent. The per-Bot secret store is the only storage with a per-Bot boundary, and only the owner can write to it.
Acceptance
Both public keys are posted here (base64url DER, ~60 chars).
A signature made by Reviewer's key verifies under nothing but Reviewer's public key; Reviewer2's key fails on it.
Nothing that reaches the repository, this issue, or the group ever contains a private key, a seed, or a PEM body.
Blocking
#1110 must not merge before the first two items exist: there is no unsigned compatibility window, so a verifier on main with no keys would freeze every merge at once. Once the keys are in place, #1110 lands and every workstation can sign from that minute.
changed the title [-]Mint one HMAC key per reviewing workstation (Actions secret + each Bot's secret store)[/-][+]Mint one Ed25519 key per reviewing workstation (public key in the repo, private key in that Bot's secret store)[/+]on Oct 25, 2026
Closed as not planned by the owner's decision (2026-10-25): no signing keys are introduced. The owner was asked for two Ed25519 public keys and said the setup is not worth it — so this issue does not get built, and nobody needs to generate a keypair or paste a secret card.
What replaces it — the three cheap gates we already run, and nothing more: a conclusion must name the current tip (tip moves → old conclusion is void), one conclusion per tip, and Attestation: as a self-report. Together those catch everything we have actually hit: verdicts written against a stale sha, a verdict replayed on a new tip, and mechanical misjudgements.
What stays open, stated plainly so it is not forgotten: any Bot holding the shared Birfy account can still write a fake Verdict: PASS. The three gates do not stop deliberate forgery from inside. Closing that would need a per-workstation account or a per-workstation key; both were declined. This is an accepted residual risk, recorded here, not a solved problem.
Code state: #1137 (signed conclusions) is merged into main and stays, inert. Its switch is the signers list in .github/agent/review-policy.json; that list is null and .github/agent/signers.json does not exist, so behaviour is exactly what it was before the merge. If the call is ever revisited, enabling it is those two config lines plus the keys — no code work. #1110 is merged and is not rolled back.
Activity
Birfy commentedon Oct 25, 2026
Written-by: Triage
Rewritten for Ed25519 — the HMAC version of this issue is dead (a shared key has to live in Actions, so it is a repository secret). #1110 carries the format; this is the key handoff, and only the owner can do it.
What the owner does, exactly
Per workstation (start with
Reviewer, thenReviewer2):reviewer.pemwherever you are comfortable generating keys — it never goes into a chat, a file in this repo, or a shell command whose output is posted.DSH_SECRET_VERDICT_KEY_REVIEWER(and…_REVIEWER2). That is the one channel where the Bot gets the key without ever printing it.Why not let the Bot generate its own key
Every Bot runs as the same OS user on the same machine, so a key file written by one is readable by the others — that would put the private half back in a shared place, which is exactly what this issue exists to prevent. The per-Bot secret store is the only storage with a per-Bot boundary, and only the owner can write to it.
Acceptance
Written-by: Reviewerstill merges: the guard cannot tell which workstation wrote a Verdict #1110 merges.Reviewer's key verifies under nothing butReviewer's public key;Reviewer2's key fails on it.Blocking
#1110 must not merge before the first two items exist: there is no unsigned compatibility window, so a verifier on main with no keys would freeze every merge at once. Once the keys are in place, #1110 lands and every workstation can sign from that minute.
[-]Mint one HMAC key per reviewing workstation (Actions secret + each Bot's secret store)[/-][+]Mint one Ed25519 key per reviewing workstation (public key in the repo, private key in that Bot's secret store)[/+]Count a Verdict only when its reviewing workstation signed it (#1110)
Count a Verdict only when its reviewing workstation signed it (#1110)
Birfy commentedon Oct 25, 2026
Written-by: Triage
Closed as
not plannedby the owner's decision (2026-10-25): no signing keys are introduced. The owner was asked for two Ed25519 public keys and said the setup is not worth it — so this issue does not get built, and nobody needs to generate a keypair or paste a secret card.What replaces it — the three cheap gates we already run, and nothing more: a conclusion must name the current tip (tip moves → old conclusion is void), one conclusion per tip, and
Attestation:as a self-report. Together those catch everything we have actually hit: verdicts written against a stale sha, a verdict replayed on a new tip, and mechanical misjudgements.What stays open, stated plainly so it is not forgotten: any Bot holding the shared
Birfyaccount can still write a fakeVerdict: PASS. The three gates do not stop deliberate forgery from inside. Closing that would need a per-workstation account or a per-workstation key; both were declined. This is an accepted residual risk, recorded here, not a solved problem.Code state:
#1137(signed conclusions) is merged into main and stays, inert. Its switch is thesignerslist in.github/agent/review-policy.json; that list isnulland.github/agent/signers.jsondoes not exist, so behaviour is exactly what it was before the merge. If the call is ever revisited, enabling it is those two config lines plus the keys — no code work.#1110is merged and is not rolled back.docs: signing is shipped and not enabled (#1195)
Count a Verdict only when its reviewing workstation signed it (ThinkF…
docs: say signing is shipped and not enabled (ThinkFlowLab#1195) (Thi…
fix(gate): read a Verdict: word the gate does not know (ThinkFlowLab#…