Skip to content

EPIC: the guards this arc built do not guard what they claim — fifteen verified defects, and the reason they survived three reviews #241

Closed

Description

@Polichinel

Rewritten 2026-08-12 after an expert review of the standing decisions. The first draft was nine stories of widening guards. This one is mostly deletion, and it is scoped so that PR #240 can merge after three issues, not nine.

The problem, in one paragraph

This repository has 9,200 lines of tests against 2,998 lines of package, and 3,182 of those test lines guard the repository's claims about itself rather than the product. A post-merge review of #239 found fifteen defects, all reproduced. They are not fifteen unrelated slips. Every one sits on a check that tries to verify a fact this repository does not own — another repo's source layout, another repo's edition semantics, every markdown dialect a person might write. Those checks cannot be proven against reality, so they get proven against the author's imagination, and then they fail inspection. That is the loop this epic exists to break.

The root decision

A check here may rest on a fact we own, on a fact another repository has declared in the public registry, or on an outcome we can observe. It may never rest on another repository's implementation.

Where a needed fact is none of those three, the check is not built here. It is requested as a declaration, requested as a consumer obligation, or registered as an accepted gap with a named owner and trigger.

ADR-003 already says this. It was applied rigorously to the product and not at all across the repository boundary. Landing it as an ADR-017 clause is what makes this a roadmap instead of a queue.

The evidence it is right: the consumer source-read broke twice in 24 hours — views-faoapi on 2026-08-11, views-crafdapi on 2026-08-12 — both times because the other repository refactored a literal into a named constant. Their code got better and our test went red. The regex was measuring their code quality and reporting it as our failure.

What ships, and when

This is an MVP with one maintainer. The test for every item below is: does this make the thing smaller, or does it add a second product to maintain?

Gate 1 — blocks PR #240. Three issues, almost entirely deletion.

net
#242 The no-copy guard prints the coordinate value it exists to hide, into public CI logs, on the one event it fires for ~5 lines changed
#245 Delete arrived. It is computed over every row of every table we depend on — 8 of 25 belong to other repositories — so any coordinate issued for any repo blocks a release here. This is the thing that literally stops shipping. net deletion
#248 Delete both consumer source-reads. Broken twice in 24 hours; one is red on development right now. Not replaced — the category is wrong. Register the gap with an owner and a trigger. net deletion

After these three, #240 merges. Nothing below blocks the release.

Gate 2 — cheap, same week, each makes the code smaller or truer

#243 Replace the assignment parser with a pair matcher, and adopt a corpus-derived stopping rule. This deletes regex complexity; it does not add any. (#244 merged in.)
#246 Two proofs that cannot fail: a tautology, and the untested function an entire module was extracted to create.
#247 The cheap legibility fixes only — rows() refusing a scalar row, commit.gpgsign and a timeout on the scratch repo. No platform-module extraction.
#249 Eight stale claims this arc left behind, plus a þing mis-citation that concealed a whole mechanism for weeks.

Gate 3 — the two paragraphs that stop the next round

#250 The ADR-017 clause above, plus a short ADR-014 §2 amendment: a guard provable only against imagined inputs is on the wrong side of a boundary. Two paragraphs, not an essay.

Deliberately NOT built — deferred with named triggers

Each of these was recommended by the expert review. Each is defensible. Each is also a second thing to maintain, and none of them is needed to ship.

Deferred Why not now Trigger to revisit
Read-only findability preflight — query the store after upload, assert the document is findable by the declared name It is the right long-term answer to invisible delivery and it needs a read credential wired into the launcher — an operator action, not a code change. Delivery works today. A delivery is reported empty, or APPWRITE_READ_API_KEY is provisioned for the launcher. Registered as C-94.
Adopt [edition].obliges_consumers Deleting arrived already fixes the shipping problem. Adopting the flag is an addition, and it would move a safety property onto upstream's labelling discipline. The drift check fires again on something we do not care about.
Extract a platform/ declarations module (C-88) One script hardcodes one string that conftest declares. One duplicated string is cheaper than a new package for a solo maintainer. WET before DRY, and the abstraction is not yet known. A third consumer needs one of these declarations. C-88 stays open with its existing trigger.
GitHub push protection / secret scanning These coordinates need a custom pattern, which historically requires paid Advanced Security. Money is the operator's decision, not mine. The cost is known, or GHAS becomes available on this org.
Splitting test_env_declaration.py (1,145 lines) Real debt, correctly diagnosed, and moving 1,145 lines while fixing bugs in them is how a fourth review finds a sixteenth defect. The file grows again after this epic, or a second contributor arrives.
A write-path integration test Forbidden by the seam contract until a non-production Appwrite project exists — an operator assignment from þing-01 D2 that is still open. The test project is created.

Desired end state

  • PR Sync development → main: the sibling-CI arc, three ADRs, and a drift check that matches on the right thing #240 merged; FAO has the eight days of work.
  • No guard in this repository reads another repository's source. Ever again.
  • The drift check fires on exactly one condition: a row we name moved between the pin and their main.
  • The no-copy scan's stopping rule is written down, mechanical, and derived from this repo's own documents rather than from imagination.
  • Every proof in the arc fails under mutation of the thing it names.
  • The guard surface is smaller than when this epic started.

Out of scope, permanently for this epic

  • Any change to delivered bytes. CONTRACT_VERSION stays 1.5; tests/fixtures/ stays byte-identical. Any story that would touch either is wrong and must stop.
  • De-inheritance (C-40 / Cluster G).
  • main branch protection and required status checks (C-81, C-86) — operator-owned, and deliberately sequenced after this epic. The epic is what makes requiring the check cheap, by shrinking what CI needs from siblings.
  • Editing views-faoapi or views-crafdapi. This epic may file issues there; it does not touch them.

Acceptance criteria

  • Gate 1 complete; PR Sync development → main: the sibling-CI arc, three ADRs, and a drift check that matches on the right thing #240 green and merged.
  • ruff check . clean; suite green; no test skipped that was not skipped before.
  • CONTRACT_VERSION == "1.5"; git diff origin/main..HEAD -- tests/fixtures/ empty.
  • wc -l tests/*.py is lower than at the start of this epic. If it is higher, the epic did the opposite of its purpose and needs re-reading.
  • Every deferral above is in the register with an owner and a trigger (ADR-014 §4).
  • C-89 … C-96 each resolved or amended with a measured residual.
  • A review pass by something other than the author finds nothing above suggestion severity.

Provenance

Every claim here was reproduced locally against views-appwrite@origin/main (registry v1.6.0) and views-faoapi@origin/development. Where the review that raised an item overstated it, the issue says so.

Activity

  1. added
    epicA large capability spanning multiple stories
    planningInvestigation/spike/decision work
    on Aug 12, 2026
  2. Polichinel commented on Aug 12, 2026

    @Polichinel
    CollaboratorAuthor

    Stories and tracking issue are filed.

    # Story Registers
    #242 S1 — the no-copy scan must not print what it forbids C-89
    #243 S2 — replace assignment-parsing with pair-matching C-57, C-89
    #244 S3 — the ban-set is a declaration, not a length accident C-57
    #245 S4 — the drift check, using upstream's obligation flag C-90, C-86
    #246 S5 — two proofs that prove nothing C-90
    #247 S6 — seam_registry must fail legibly C-91
    #248 S7 — the FAO consumer-filter gap C-92, C-87
    #249 S8 — the claims this arc left behind C-82
    #250 S9 — ADR-014 §2 on mutant lists C-93

    Implementation order and completion criteria: #251.

    PR #240 (development → main) is blocked on this epic.

  3. Polichinel commented on Aug 12, 2026

    @Polichinel
    CollaboratorAuthor

    Complete. All nine stories closed, PR #240 released, post-mortem in reports/post_mortems/2026-08-12_the_guards_that_did_not_guard.md.

    Closing summary in #251.

  4. added a commit that references this issue on Aug 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    epicA large capability spanning multiple storiesplanningInvestigation/spike/decision work

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions