diff --git a/docs/review/calibration-2026-08.md b/docs/review/calibration-2026-08.md index a3088d1..2c220f7 100644 --- a/docs/review/calibration-2026-08.md +++ b/docs/review/calibration-2026-08.md @@ -222,3 +222,85 @@ collateral damage to be designed around. The gate was not weakened to preserve i The two unrequired CI contexts (`parity-receipt-reproduction`, `standard-candidate-consumption`) remain a separate question, recorded in [`merge-policy.md`](merge-policy.md) §2 and deliberately untouched. + +## Withdrawal — ratified and applied 2026-08-13 + +The requirement ratified above survived one day. It is withdrawn here, in the same +record that promoted it, so the promotion and the demotion are read together. + +**What failed:** criterion 5 of the seven — *a further push retriggers review +against the new head*. Greptile continued to post reviews and stopped emitting the +`Greptile Review` check run. Branch protection matches on the check run, so the +required context could not be satisfied by any action available to a contributor, +and `main` became unmergeable for every change including hotfixes. + +Observed on PR #14 across four heads: + +| Head | Greptile review posted | `Greptile Review` check run | Other checks | Unresolved threads | +| --- | --- | --- | --- | --- | +| `0ee76bc` | yes (COMMENTED) | **0** | 8/8 pass | 0 | +| `c3c17a2` (rebase onto `main`) | yes (COMMENTED) | **0** | 8/8 pass | 0 | +| `3aa4531` (fresh push) | yes (COMMENTED) | **0** | 8/8 pass | 0 | +| `be2e965` (merged head) | — | **0** | 8/8 pass | 0 | + +The same `statusCheck: true` in `.greptile/config.json` kept producing the check on +`workspacejson/standard` across PRs #34, #35 and #36 throughout the same window. The +configuration is not missing; emission on this repository is not dependable. + +**What this says about the calibration.** The seven criteria were the right bar and +were honestly observed — the defect was caught, the revert was clean, the check was +head-associated. What the protocol did not test is *durability*: every criterion was +measured once, in a single sitting, and criterion 5 was verified by one push rather +than by pushes separated in time. A behavioral bar measured once is a measurement, +not a guarantee. Any future promotion should require the signal to survive a stated +interval before it becomes merge-authoritative. + +### Branch protection, before and after + +Both readings taken from the protection API, not from a write response. + +| Setting | Before (2026-08-13T03:53Z) | After | +| --- | --- | --- | +| Required status checks | `build-and-smoke (20)`, `build-and-smoke (22)`, `standard-candidate-consumption`, `SonarCloud Code Analysis`, **`Greptile Review`** | `build-and-smoke (20)`, `build-and-smoke (22)`, `standard-candidate-consumption`, `SonarCloud Code Analysis` | +| `strict` | `true` | `true` — preserved | +| `required_conversation_resolution` | `true` | `true` — preserved | +| `required_approving_review_count` | `0` | `0` — preserved | +| `dismiss_stale_reviews` | `true` | `true` — preserved | +| `enforce_admins` | `false` | `false` — preserved | +| `allow_force_pushes` / `allow_deletions` | `false` / `false` | unchanged | +| Rulesets | `[]` | `[]` | + +App id bindings were preserved on the four surviving contexts, so a same-named check +from another app still cannot satisfy them. + +**Greptile was not uninstalled.** `greptile-apps` (app id `867647`) remains installed +on the org and continues to review. Only its authority over merge eligibility was +withdrawn. + +### How PR #14 actually merged + +It did not merge by satisfying protection. On `be2e965` four of the five required +contexts were green and `Greptile Review` was absent; the merge at +2026-08-13T02:08:20Z used the administrator bypass that `enforce_admins: false` +permits. That is recorded rather than smoothed over: it means the GTM-39 merge +receipt rests on four contexts and conversation resolution, not five, and it is the +reason this withdrawal was necessary rather than optional — a gate satisfiable only +by bypass is not a gate. + +### Deliberately accepted cost + +`main` now has no mechanically enforced reviewer context at all. Nothing asserts +that the head being merged was reviewed by anything; `required_conversation_resolution` +and the written per-finding protocol in [`merge-policy.md`](merge-policy.md) §3 carry +the whole semantic gate. This is a real reduction in enforcement and is accepted +knowingly, because the alternative on offer was not a stronger gate but an +unsatisfiable one — which delivered no review authority either, while also blocking +every merge. + +### Re-admission + +`Greptile Review` may become merge-authoritative again only after **both** are +observed: a substantive review on the current PR head, **and** a mechanically +enforceable current-head signal compatible with branch protection. Absence of either +is reported as absence. Quota, credit-limit and error comments are not review +evidence and do not count toward the first. diff --git a/docs/review/merge-policy.md b/docs/review/merge-policy.md index b56b6d1..9608d00 100644 --- a/docs/review/merge-policy.md +++ b/docs/review/merge-policy.md @@ -56,7 +56,7 @@ Values below were read from the GitHub branch-protection API for `main`. | Setting | Measured value | | --- | --- | -| Required status checks | `build-and-smoke (20)`, `build-and-smoke (22)`, **`Greptile Review`**, `standard-candidate-consumption`, `SonarCloud Code Analysis` | +| Required status checks | `build-and-smoke (20)`, `build-and-smoke (22)`, `standard-candidate-consumption`, `SonarCloud Code Analysis` | | `strict` (branch must be up to date) | `true` | | `required_conversation_resolution` | `true` | | `required_approving_review_count` | `0` | @@ -66,21 +66,21 @@ Values below were read from the GitHub branch-protection API for `main`. | Repository rulesets | none (`[]`) | So a merge into `main` requires: the two `build-and-smoke` contexts, -`Greptile Review`, `standard-candidate-consumption`, and `SonarCloud Code Analysis` -green on an up-to-date head, and **every conversation resolved**. No review approval -is required. +`standard-candidate-consumption`, and `SonarCloud Code Analysis` green on an +up-to-date head, and **every conversation resolved**. No review approval is +required. `Greptile Review` was added to the required contexts on 2026-08-12 after the -calibration in [`calibration-2026-08.md`](calibration-2026-08.md), and is pinned to -app id `867647` — only that app can satisfy the context, so a same-named check from -elsewhere cannot. `Sourcery review` is deliberately **not** required. +calibration in [`calibration-2026-08.md`](calibration-2026-08.md), and **removed on +2026-08-13** because it stopped emitting the check run the requirement depends on — +see §4. `Sourcery review` is deliberately **not** required. -**Read the requirement precisely.** The Greptile context asserts *the current head -was reviewed*, not *the review found nothing* — the check concludes `success` even -on a head carrying a P1 finding. The semantic half of the gate is -`required_conversation_resolution` plus the written per-finding protocol in §3. The -two are only meaningful together, and neither is a substitute for reading the -findings. +**Read what remains precisely.** With no reviewer context required, the semantic +half of the gate is carried entirely by `required_conversation_resolution` plus the +written per-finding protocol in §3. Greptile still posts reviews and its findings +still create threads that must be reconciled to merge; what it no longer does is +assert mechanically that the current head was reviewed. That assertion is now a +human responsibility, and §5 applies with more force, not less. This was observed working end to end on PR #12 at head `76d495d`, **under the three-context protection in force on 2026-08-12**: all three required contexts @@ -158,9 +158,15 @@ The protocol: ## 4. `Greptile Review` as a required check -**Current state: required, as of 2026-08-12.** It was promoted only after all seven -criteria below were observed on this repository, and only into the narrow role it -demonstrably performs — see [`calibration-2026-08.md`](calibration-2026-08.md). +**Current state: NOT required, as of 2026-08-13.** It was required from 2026-08-12 +until 2026-08-13, promoted only after all seven criteria below were observed on this +repository, and only into the narrow role it demonstrably performs — see +[`calibration-2026-08.md`](calibration-2026-08.md). It was demoted because criterion +5 stopped holding; the demotion is recorded under +[Why the requirement was withdrawn](#why-the-requirement-was-withdrawn) below. + +Greptile remains installed and continues to post reviews. What was withdrawn is its +authority over merge eligibility, not its presence. The bar was behavioral, not configurational. Each of the following was observed on this repository — not inherited from `workspacejson/standard`, where the mechanism @@ -172,7 +178,8 @@ was proven: 3. A deliberate, Integrations-specific positive-control defect is **caught** by a custom rule from `.greptile/config.json`. 4. The reverted, non-violating head does **not** repeat that finding. -5. A further push **retriggers** review against the new head. +5. A further push **retriggers** review against the new head. — **This no longer + holds. See [Why the requirement was withdrawn](#why-the-requirement-was-withdrawn).** 6. Actionable findings are reconcilable individually, with thread receipts intact. 7. Merge eligibility then behaves as claimed. @@ -220,6 +227,52 @@ review before merging. PR #6's pre-policy head has **no** Greptile run at all, s cannot satisfy the context until it updates — intended behavior, not collateral damage. +### Why the requirement was withdrawn + +Criterion 5 — *a further push retriggers review against the new head* — held during +calibration on 2026-08-12 and stopped holding immediately afterwards. Greptile kept +posting reviews; it stopped emitting the `Greptile Review` check run that branch +protection matches on. A required context that the installed app does not produce +cannot be satisfied by anything, so `main` became unmergeable. + +Observed on PR #14 across four heads: + +| Head | Greptile review posted | `Greptile Review` check run | Other checks | +| --- | --- | --- | --- | +| `0ee76bc` | yes (COMMENTED) | **0** | 8/8 pass | +| `c3c17a2` (rebase onto main) | yes (COMMENTED) | **0** | 8/8 pass | +| `3aa4531` (fresh push) | yes (COMMENTED) | **0** | 8/8 pass | +| `be2e965` (merged head) | — | **0** | 8/8 pass | + +Zero unresolved threads on every one of them. The documented recovery path — push +again and get a fresh check — was the thing that failed, which is why criterion 5 is +annotated above rather than quietly deleted: it is the criterion whose failure the +requirement could not survive. + +The same `statusCheck: true` in `.greptile/config.json` continued to produce the +check on `workspacejson/standard` throughout, so this was not a missing config +value. The mechanism is real; its emission on this repository is not currently +dependable. + +**Change applied 2026-08-13**, measured before and after against the API: + +``` +before: ["build-and-smoke (20)", "build-and-smoke (22)", + "standard-candidate-consumption", "SonarCloud Code Analysis", + "Greptile Review"] +after: ["build-and-smoke (20)", "build-and-smoke (22)", + "standard-candidate-consumption", "SonarCloud Code Analysis"] +``` + +Greptile was **not** uninstalled (`greptile-apps`, app id `867647`, still installed +on the org). Quota, credit-limit and error comments are **not** review evidence, and +absence of a check is recorded as absence — never as a pass. + +**Re-admission.** `Greptile Review` may become merge-authoritative again only after +**both** are observed: a substantive review on the current PR head, **and** a +mechanically enforceable current-head signal compatible with branch protection. +Meeting one without the other is what produced this deadlock. + ## 5. What a check state does and does not mean * A check that has **not run** is not a pass. Absence of a review is absence of