Skip to content

refactor(tests): drop the circular half of the sibling declaration - #230

Merged
Polichinel merged 4 commits into
developmentfrom
refactor/simplify-sibling-declaration
Aug 10, 2026
Merged

refactor(tests): drop the circular half of the sibling declaration#230
Polichinel merged 4 commits into
developmentfrom
refactor/simplify-sibling-declaration

Conversation

@Polichinel

Copy link
Copy Markdown
Collaborator

Follows the expert-code-review of PR #229's design. Verdict was SIMPLIFY, not revert — the win and the two bug fixes stand; roughly a quarter of the machinery guarded the machinery.

The finding, measured rather than argued

.public          read in exactly one place — rule G3
.public_checked  read in exactly one place — rule G8
G3's private-branch:  vacuous, no private sibling is checked out

So public existed to be verified by G3, and G3 existed to protect public's verifiability. The field and its guard justified each other and nothing else. Deleting both changes no behaviour.

public_checked was worse than useless: nothing could confirm the check had actually happened, so it manufactured confidence rather than recording a fact. And G8 — its only reader — cried wolf on its first CI run, over a timezone. ADR-014 §3 says prefer a false negative to a false alarm; that rule was the clause's own worked example.

What changed

before after
guard file 552 lines 448
rules 8 6 (G1, G2, G4, G5, G6, G7)
Sibling fields 5 3 (env, ci_checkout, note)

Visibility now lives in a sibling's note, as prose — because nothing here can verify it in any case, and prose is honest about that. What survives without the flag needs no field: a repository CI cannot read simply fails to download, and G5 keeps that failure loud.

Every surviving rule has an incident behind it, not a hypothesis: G6 for the 745 lint findings when a sibling landed outside _siblings/; G7 for views-appwrite's default branch being development rather than main.

Re-proven against the real workflow after the cut. Worth noting: my first G7 mutation passed, and the guard was right — the replacement had hit a comment mentioning ref: main rather than an actual step.

The ADR is rewritten, and the reason matters

You couldn't follow the previous version past §4. That was the design, not the prose: §5–§7 were second-order — rules protecting an argument rather than protecting the code. "G3 exists so that the claim in §5 stays true" is not a sentence anyone should have to parse.

It now:

  • opens with the decision in four sentences;
  • gives each rule the incident behind it in one table;
  • states plainly in §7 that a broken sibling repository can block merging here, with the reasoning — previously asserted rather than argued;
  • records what was removed and why, because the deleted design is more tempting than it looks and this document once argued for it.

On §7, since it was the reviewer's strongest objection

Nygard's point was that this puts two external repositories on the critical path of shipping, and that merging to main here is the release. That is true and now stated rather than buried. Kept blocking rather than reporting, for three reasons written into the ADR: the problem being fixed was that these checks were invisible, and a check that cannot block is invisible again; a red build in that situation is correct; and the maintainer administers this repository and can merge over a failing check when something is genuinely urgent.

Verification

ruff check .        # clean
pytest -q           # 399 passed, 40 xfailed

🤖 Generated with Claude Code

Polichinel and others added 4 commits August 10, 2026 02:12
An expert-code-review of the design found two fields and two rules justifying each other
and nothing else. Measured rather than argued:

  .public          read in exactly one place — rule G3
  .public_checked  read in exactly one place — rule G8
  G3's private-branch  vacuous; no private sibling is checked out

So `public` existed to be verified by G3, and G3 existed to protect `public`'s
verifiability. Deleting both changes no behaviour. `public_checked` was worse than
useless: nothing could confirm the check had happened, so it manufactured confidence
instead of recording a fact — and G8, its only reader, cried wolf on its first CI run
over a timezone, which is ADR-014 §3's own worked example.

Visibility now lives in a sibling's `note`, as prose, because nothing here can verify it
in any case. What survives without the flag needs no field: a repository CI cannot read
fails to download, and G5 keeps that failure loud.

  guard file  552 -> 448 lines
  rules       8 -> 6 (G1, G2, G4, G5, G6, G7)
  Sibling     5 fields -> 3 (env, ci_checkout, note)

Every surviving rule has an incident behind it, not a hypothesis: G6 for the 745 lint
findings when a sibling landed outside `_siblings/`, G7 for views-appwrite's default
branch being `development`. Re-proven against the real workflow after the cut — and the
first G7 mutation was wrong rather than the guard, having hit a comment instead of a step.

ADR-016 rewritten. The maintainer could not follow the previous version past §4, and the
reason was the design rather than the prose: §5-§7 were second-order, rules protecting an
argument rather than protecting the code. It now opens with the decision in four
sentences, gives each rule the incident behind it, and states plainly in §7 that a broken
sibling can block merging here — with the reasoning, which was previously asserted rather
than argued. What was removed is recorded, because the removed design is more tempting
than it looks and this document once argued for it.

Suite 399 passed / 40 xfailed; ruff clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ADR-017 decides what this repository does about a fact held in a repository it cannot
read. The rule: the fact is declared in the public coordinate registry, each side verifies
itself against it, neither reads the other's source. No credential, for any number of
private APIs. Written for the category, per the maintainer's brief that private consumer
APIs are permanent even if views-faoapi itself goes public.

ADR-016 rescoped to say plainly that it only covers repositories CI can download, with the
private case handed to ADR-017 rather than deferred.

A falsification pass over every section of both documents found seven defects, all fixed:

- the heading said 'four sentences' over a body of three, after the rescope removed one
- ADR-016 still cited a private register ID in a document meant to stand alone
- 'Rejected on §8's arithmetic' pointed at arithmetic the rewrite had removed
- 'sibling' was used seventeen times and never defined
- ADR-017 makes ADR-016's views-crafdapi download pointless — that fetch serves exactly
  one test, and ADR-017 replaces it. Neither document said so; both now do
- §2's ownership claim is evidenced by ADR-013 for the FAO partner only; CRAF'd is not
  mentioned there at all. Now admitted, and folded into the registry work
- ADR-016 rejects 'copy the facts here' while ADR-017 keeps a copy. Reconciled: what is
  forbidden is a copy that is ALSO the thing checked against

The fix for the fourth broke the first by landing between two sentences; caught on re-run.

Suite 399 passed / 40 xfailed; ruff clean. Nothing merged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
New probes, not a re-run of the first pass. Three findings, all fixed:

- ADR-016 is Accepted and asserted the outcome of ADR-017, which is Proposed. It said
  ADR-017 'settles' the private case and that its §7 'replaces' a test. An accepted
  decision cannot depend on an unaccepted one. Softened to conditional throughout, and the
  scope line now states plainly that nothing in ADR-016 depends on the proposal being
  adopted — if it is rejected, the private case returns as an open question.
- §5's rule table runs G1, G2, G4, G5, G6, G7. Two numbers are missing and nothing said
  why. The removed-design section now names G3 and G8 as the removed rules and records
  that survivors keep their original names rather than being renumbered.
- '(see §5.3)' reads as a subsection that does not exist — the ADR's own convention is §N,
  and §4.1a elsewhere refers to a real ADR-013 subsection. Rewritten as prose.

Probes that failed to falsify, recorded because a passed probe is evidence: every factual
claim verified (15 of 33 repositories private; the ADR-013 quote is verbatim; the registry
does carry consumer fields; CI does read it), and the label/name/CONSUMER_DOCUMENT_NAME
terminology is defined on first use and consistent thereafter.

All ten findings from both passes re-checked together; no regressions.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Both ADRs accepted. ADR-017 moves Proposed -> Accepted, and ADR-016's conditional
language about it resolves with it: the scope line no longer hedges on whether the
proposal is adopted, and §8 now says the decision is accepted but not yet implemented,
because it waits on a declaration landing in another repository's registry.

/review-diff over the branch found two, both prose, both this repo's named defect class:

- a docstring in test_ci_sibling_coverage said "eight rules find nothing to complain
  about" after the cut left six. Removed the count rather than correcting it — a number
  nobody checks is a claim with a half-life, which is C-82's whole finding.
- ADR-017 §5 stated in the present tense that this repository checks its copy against the
  registry declaration. It does not: test_product.py still reads the consumer's source and
  will until the declaration exists. Appendix B and ADR-016 §8 both recorded it as pending,
  so the documents were honest taken together, but §5 read alone stated unbuilt work as
  fact. Now says plainly that none of the three steps is in place and that the present
  tense describes the decided end state.

Probes that found nothing, recorded because a passed probe is evidence: no orphaned
reference to the deleted `public`, `public_checked`, G3, G8 or the clock-skew constant
anywhere in tests, docs or workflows; broken_sibling_overrides verified against unset,
empty, whitespace-only, bad-path and valid inputs with the docstring matching each; all
six rules carry a mutant and each mutant fires its own rule.

Suite 399 passed / 40 xfailed; ruff clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@Polichinel
Polichinel merged commit fab6456 into development Aug 10, 2026
4 checks passed
@Polichinel
Polichinel deleted the refactor/simplify-sibling-declaration branch August 10, 2026 01:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant