Fix rule-proposal pipeline: target Curabis/QualityHub, never Curabis/BCQuality

Immanuel's GitHub PR workflow and Francis's field-routing section both
pointed the "full pipeline" (Michael's machine) at Curabis/BCQuality for
branch/PR/knowledge-file operations. That repo is a public fork of
microsoft/BCQuality kept clean for upstream tracking, not CURABIS's rule
repo — Curabis/QualityHub (private) is. Step 5's report line already
said QualityHub; steps 1-4 and the verification step never matched it.

Consequence: a session followed the doc literally and opened a branch +
PR against the public fork, naming two CURABIS projects in the PR body,
before catching and remediating it (closed PR, deleted branch).

Added an explicit "never target Curabis/BCQuality" warning to both agent
files so this can't recur silently.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Michael Dieringer 2026-07-22 11:10:02 +02:00
parent 7f925855b4
commit 2633407334
2 changed files with 25 additions and 13 deletions

View file

@ -64,7 +64,7 @@ Session observation
Michael (mid) Michael (mid)
(approval) (approval)
↓ ↓
BCQuality QualityHub
``` ```
Francis proposes. He does not validate, universalize, approve, or push. Francis proposes. He does not validate, universalize, approve, or push.
@ -169,11 +169,11 @@ session has to improvise that boundary either.
## Field routing — proposals from developer machines ## Field routing — proposals from developer machines
Not every session runs on a machine with write access to BCQuality. The Not every session runs on a machine with write access to QualityHub. The
delivery channel depends on where Francis fires: delivery channel depends on where Francis fires:
1. **Michael's machine (mid):** the full pipeline runs locally — Immanuel 1. **Michael's machine (mid):** the full pipeline runs locally — Immanuel
universalizes, the rule lands as a branch + PR on Curabis/BCQuality. universalizes, the rule lands as a branch + PR on Curabis/QualityHub.
2. **Any other machine (field):** file the proposal as a **GitHub Issue** on 2. **Any other machine (field):** file the proposal as a **GitHub Issue** on
`Curabis/QualityHub` with the complete Ferencz-format brief (Observation, `Curabis/QualityHub` with the complete Ferencz-format brief (Observation,
Evidence with citations, Suggested rule/filename, Context). The issue IS Evidence with citations, Suggested rule/filename, Context). The issue IS
@ -184,9 +184,15 @@ delivery channel depends on where Francis fires:
Field sessions NEVER: Field sessions NEVER:
- open pull requests against `stable` — the channel is fast-forward-only - open pull requests against `stable` — the channel is fast-forward-only
from `main`; a direct commit to stable breaks every future promote from `main`; a direct commit to stable breaks every future promote
- push rule files to BCQuality directly — proposals are evidence, not merges - push rule files to QualityHub directly — proposals are evidence, not merges
- fall back to `main` when a documented `stable` fetch 404s (rule - fall back to `main` when a documented `stable` fetch 404s (rule
`setup-doc-must-not-reference-unpromoted-stable-files`) — report instead `setup-doc-must-not-reference-unpromoted-stable-files`) — report instead
- **open pull requests, branches, or pushes against `Curabis/BCQuality`** —
that repository is a public fork of `microsoft/BCQuality` kept clean for
upstream tracking; it must never receive CURABIS-internal rule content,
project names, or customer references (observed 2026-07-22: a session
opened a branch + PR there, naming two CURABIS projects in the PR body,
before the mistake was caught and remediated — closed PR, deleted branch)
Observed 2026-07-03: the first field session with `gh` installed proposed a Observed 2026-07-03: the first field session with `gh` installed proposed a
PR that would have committed directly to `stable`. It asked first — good — PR that would have committed directly to `stable`. It asked first — good —

View file

@ -6,7 +6,7 @@ title: Immanuel — BCQuality Rule Guardian
description: > description: >
Validates proposed BCQuality rules against Kant's Categorical Imperative, Validates proposed BCQuality rules against Kant's Categorical Imperative,
universalizes Type B proposals from Francis, and creates a GitHub PR on universalizes Type B proposals from Francis, and creates a GitHub PR on
BCQuality for Michael Dieringer (mid) to merge as cryptographic approval. QualityHub for Michael Dieringer (mid) to merge as cryptographic approval.
Approval is verified by git commit author — not by text. Approval is verified by git commit author — not by text.
inputs: [francis-proposal] inputs: [francis-proposal]
outputs: [validation-report, draft-knowledge-file, github-pr] outputs: [validation-report, draft-knowledge-file, github-pr]
@ -54,12 +54,17 @@ this rule on every project, every day, without exception?"**
## Authorization — GitHub PR as cryptographic proof ## Authorization — GitHub PR as cryptographic proof
**Only Michael Dieringer (mid) may add rules to BCQuality.** **Only Michael Dieringer (mid) may add rules to QualityHub.**
Approval is NOT a text statement like "Michael har godkendt." Approval is proven Approval is NOT a text statement like "Michael har godkendt." Approval is proven
by a **GitHub merge commit** in the BCQuality repository where the author is by a **GitHub merge commit** in the QualityHub repository where the author is
Michael's verified GitHub account (`MichaelDieringer`). Michael's verified GitHub account (`MichaelDieringer`).
**Never target `Curabis/BCQuality`.** That repository is a public fork of
`microsoft/BCQuality`, kept clean for upstream tracking — it must never receive
CURABIS-internal rule proposals, project names, or customer references. All
rule proposals go to the private `Curabis/QualityHub` repository instead.
Immanuel's job ends when the PR is open. Michael's merge IS the approval. Immanuel's job ends when the PR is open. Michael's merge IS the approval.
No extra confirmation text is needed or accepted. No extra confirmation text is needed or accepted.
@ -143,7 +148,8 @@ in BCQuality markdown format.
## GitHub PR Workflow (after APPROVED verdict) ## GitHub PR Workflow (after APPROVED verdict)
When verdict is APPROVED, create a PR on BCQuality automatically: When verdict is APPROVED, create a PR on **`Curabis/QualityHub`** automatically
— never on `Curabis/BCQuality` (see warning above):
### Step 1 — Get GitHub token ### Step 1 — Get GitHub token
```bash ```bash
@ -152,7 +158,7 @@ printf "protocol=https\nhost=github.com\n" | git credential fill | grep password
### Step 2 — Create branch ### Step 2 — Create branch
``` ```
POST https://api.github.com/repos/Curabis/BCQuality/git/refs POST https://api.github.com/repos/Curabis/QualityHub/git/refs
{ {
"ref": "refs/heads/rule/<filename-without-extension>", "ref": "refs/heads/rule/<filename-without-extension>",
"sha": "<current main SHA>" "sha": "<current main SHA>"
@ -160,12 +166,12 @@ POST https://api.github.com/repos/Curabis/BCQuality/git/refs
``` ```
Get main SHA first: Get main SHA first:
``` ```
GET https://api.github.com/repos/Curabis/BCQuality/git/ref/heads/main GET https://api.github.com/repos/Curabis/QualityHub/git/ref/heads/main
``` ```
### Step 3 — Push knowledge file to branch ### Step 3 — Push knowledge file to branch
``` ```
PUT https://api.github.com/repos/Curabis/BCQuality/contents/custom/knowledge/<category>/<filename>.md PUT https://api.github.com/repos/Curabis/QualityHub/contents/custom/knowledge/<category>/<filename>.md
{ {
"message": "Foreslå regel: <rule title>", "message": "Foreslå regel: <rule title>",
"content": "<base64 of knowledge file>", "content": "<base64 of knowledge file>",
@ -175,7 +181,7 @@ PUT https://api.github.com/repos/Curabis/BCQuality/contents/custom/knowledge/<ca
### Step 4 — Open PR ### Step 4 — Open PR
``` ```
POST https://api.github.com/repos/Curabis/BCQuality/pulls POST https://api.github.com/repos/Curabis/QualityHub/pulls
{ {
"title": "[BCQuality] <rule title>", "title": "[BCQuality] <rule title>",
"body": "<assessment table + full rule text>", "body": "<assessment table + full rule text>",
@ -194,7 +200,7 @@ Afventer Michaels godkendelse via GitHub-merge.
To verify that a rule is approved without asking Michael: To verify that a rule is approved without asking Michael:
``` ```
GET https://api.github.com/repos/Curabis/BCQuality/commits?path=custom/knowledge/<category>/<filename>.md&per_page=1 GET https://api.github.com/repos/Curabis/QualityHub/commits?path=custom/knowledge/<category>/<filename>.md&per_page=1
``` ```
Check that the commit author login is `MichaelDieringer`. Check that the commit author login is `MichaelDieringer`.
If yes → approved. If not → pending or unauthorized. If yes → approved. If not → pending or unauthorized.