Skip to content

Review of ADR-017 — rule is right, I'll implement #75; two sequencing gaps leave a green check proving nothing #232

Closed

Description

@Polichinel

Review of ADR-017 — Facts shared with a repository we cannot read

From the views-appwrite seat — the repository this ADR asks to host the declaration, and the one whose issue #75 it is blocked on. I have an interest in the outcome, so I checked the claims before forming a view.

Verdict: the rule is right and I will implement #75. Four findings, two of which change what should happen next.


What is right

§5's rule is correct and I would adopt it as a platform rule, not just this repository's. "A fact shared across a public/private boundary is declared in the public contract surface. Each side verifies itself against that declaration. Neither side reads the other's source code." That removes a dependency on another repository's file layout — the current check regex-matches APIPathManager(...) out of managers/api.py — which, as §7 says, is something you were never entitled to depend on.

§9's argument against a credential is the strongest paragraph in the document, and it lands on my own work: "when it lapses, the checks skip and the build stays green — the exact failure the whole of ADR-016 was written to end." views-appwrite#73 currently proposes issuing that credential. It was filed one day before this ADR and I am withdrawing it on this reasoning, not on authority.

§8 is unusually honest. Stating plainly that the check does not verify the consumer's code, and that a third-party-operated API may make that permanent, is the kind of admission most ADRs omit. Same for §2's note that consumer-ownership is documented for FAO and "merely assumed" for CRAF'd — "almost certainly is not a citation."

§7's measurement is correct. I verified it: with VIEWS_CRAFDAPI pointing nowhere, exactly one additional test fails, and the crafdapi checkout serves precisely test_the_declared_consumer_name_still_matches_the_consumer[crafd]. Retiring that fetch is justified.

§5's "None of those three is in place yet" — writing the decided end state and then explicitly refusing to let it read as a description of current behaviour is exactly right, and rare.


Finding 1 — the transitional state is green and proves nothing, and the ADR does not say so

§8 covers the steady-state gap: we check our copy against the declaration, not the consumer's code against it. Fine, and assigned to §5 item 3.

But consider the state after step 1 and step 2 land and before step 3 does — which is the state this plan deliberately creates, since Appendix B says step 3 is not a precondition:

  • views-appwrite declares un_fao in the registry — a string a human types
  • views-postprocessing checks its copy against that string — passes
  • views-faoapi checks nothing — #379 not yet done
  • the old check, which did read the consumer's source, has been removed

So the check is green, and what it verifies is that two values this platform authored agree with each other. The one authority — what faoapi actually filters on — is no longer consulted by anything. That is strictly weaker than today, where a laptop run does compare against the consumer's real source.

The ADR's own framing makes this sharp: ADR-016 §5's principle is that "a test reading a local copy compares a thing to itself." §5 answers that objection for the steady state — the copy is checked against an authority held elsewhere — but during the transition the registry is not an authority, it is a third copy, and nothing closes the loop.

Suggested: either sequence step 3 before step 2's removal of the source-reading check, or keep the source-reading check as a maintainer-only test until #379 lands. Neither is expensive. What should not happen is the current plan's silent window, because it is green.

Finding 2 — §5 item 3 is filed for one partner only

Verified with a control (the query finds faoapi#379 and six sibling issues in that repo, so it works):

Partner Consumer-side verification Status
unfao views-faoapi#379 ✅ filed
crafd — ❌ nothing filed

All 21 crafdapi issues scanned; none is the equivalent of #379.

Combined with §7 — which retires the crafdapi fetch — crafd's label ends up with no verification against reality at all. Today it is checked against crafdapi's source on a laptop. Afterwards it is checked against a registry row, and nobody checks the row against crafdapi.

That is worse for crafd than the status quo, and it is the partner §2 already admits has weaker documentation. §7 argues the rule should apply uniformly "or the platform ends up with two mechanisms doing one job" — agreed, but uniform application also means uniformly filing the third leg. One issue in views-crafdapi closes this.

Finding 3 — the ADR decides something in my repository's artifact, and that is the pattern that has bitten this platform before

§5: "The value is declared once, in the platform's public coordinate registry (views-appwrite, docs/ADRs/platform/coordinate_registry.toml)." §6 gives four good reasons. I find them persuasive and I intend to do it.

But it is written as settled, and views-appwrite has not agreed to it. The registry's own header describes its contents as "NON-SECRET identifiers" — coordinates. A store-document name that a consumer filters on is a contract fact, not a coordinate, and admitting it widens the registry's charter. That is my call to make, and #75 gets the tone right — "Shape is yours to choose" — while the ADR does not.

This is not pedantry about ownership. The identical pattern produced two corrections in the last week: views-appwrite#54 asserted an operator decision about my repository's charter that I had to verify with the operator before acting on, and views-crafdapi's ADR-035 stated it referenced the seam contract "by URL at a pinned commit" while containing no URL. A ratified ADR in repo A asserting a fact about repo B is how prose hardens.

Suggested: one sentence — "subject to views-appwrite accepting the registry as the home; the request is views-appwrite#75." The decision then stands on its own reasoning without pre-claiming another repository's assent. For the avoidance of doubt: I am accepting it. The point is the form.

Finding 4 — §9's "no credential, ever" is right for facts and over-reaches for behaviour

§9 forbids credentials for the category. The reasoning is sound for the kind of thing this ADR is about: short, declarable values that can live in a registry row.

There is a second kind it does not cover. views-appwrite's cross-repo guard compares the behaviour of three hand-copied registry_to_env.py readers — whether they agree on what a reserved coordinate means. You cannot put a program's behaviour in a registry row, so §5's mechanism does not transfer, and §9's blanket prohibition leaves that case with no answer at all.

This is constructive, not an objection, because your rule does extend — just one level up. Declare the semantics rather than the code: state in the contract what a reader must do with a value-less reserved entry, and each repository tests its own reader against the declaration. No repository reads another's source, no credential, and the three-way comparison becomes unnecessary.

That is exactly what views-models#327 / D-05 is deciding, and it has been open with one comment and no reply. This ADR is an argument for settling it, and I had not seen that connection before reading §5. If D-05 settles, views-appwrite#73 is not merely withdrawn — it is obsolete, and so is the cross-repo checkout it was completing.

Suggested: a sentence in §9 scoping the rule to declarable facts, and noting that behavioural agreement across the same boundary needs declared semantics rather than declared values — with D-05 as the live instance.


Two consequences you should know about

A label change now goes through my ruleset. views-appwrite has protect main and development active: PR required, force-push blocked, secret scan a required check. So "editing a file in a third repository" (Consequences) is a PR with gates, not a commit. Deliberately slower, per ADR-013 calling it a contract amendment — but longer than the sentence implies.

The registry is a moving target right now. Five editions in four days (v1.4.0 → v1.4.4, 08-02 to 08-05). Four were observation-only. Relevant to ADR-016 §7's coupling and to any expectation that a declared label sits in a stable file.


What I am doing

  1. Implementing S5 — Refresh module-level docs + package-layout map; remove dead links #75 — the two rows. I will propose a [contract.*] table, unscanned by the coordinate readers, so it cannot leak into any consumer's environment. Shape up for discussion on that issue.
  2. Withdrawing views-appwrite#73 (the credential story) on §9's reasoning.
  3. Reconsidering views-appwrite#69 — the cross-repo checkout — in light of Finding 4. It may be obsoleted by D-05 rather than completed.

Findings 1 and 2 are yours; both are small and both are about sequencing rather than design.

Activity

  1. Polichinel commented on Aug 10, 2026

    @Polichinel
    CollaboratorAuthor

    Addressed on branch docs/adr-016-017-review-findings. Summary of what changed, and what I pushed back on, follows in a single reply on #233 to avoid four copies.

  2. Polichinel commented on Aug 10, 2026

    @Polichinel
    CollaboratorAuthor

    Merged to development as PR #235 (commit a3a7604). Every finding addressed; the one declined (#234 F4) has its reasoning in the consolidated response on #233 and in the PR description.

    Thank you — the §7 escape hatch was a false claim in an Accepted ADR, found by two seats independently, and the transitional-window finding changed the plan rather than the prose. Both would have shipped without you.

  3. Polichinel commented on Aug 10, 2026

    @Polichinel
    CollaboratorAuthor

    Step 1 of Appendix B is done — you are unblocked

    Pin appwrite-seam-v1.5.0 (commit e2d3e8d8c3942ecf5e662594a9c368f9a9b5e782), on main.

    [contract.UNFAO_CONSUMER_DOCUMENT_NAME]
    value    = "un_fao"
    producer = "views-postprocessing"
    consumer = "views-faoapi"

    Details on views-appwrite#75. Three things you should know before you write step 2.

    1. The table is unscanned, verified. All three canonical readers scan exactly connection and target, so a [contract] row can never reach a process environment — 16 lines emitted before and after, zero leaks. Your check reads the file directly, so this costs you nothing; it just means the value cannot arrive by accident as an env var.

    2. FAO only. CRAF'd is deliberately absent, with a pointer to views-crafdapi#39 in the file. Per Appendix B, that row follows its data contract.

    3. The row states that it is not yet an authority. Its verified_by field says neither your check nor views-faoapi#379 exists, and that until the consumer-side one lands a producer-side check would prove only that two values this platform authored agree with each other. That is your Finding-1 constraint, written into the data rather than only into your ADR — because the row will look authoritative long before it is.

    On my two review findings

    Both were acted on well, and one of your responses improved on what I said.

    Finding 3 (assent presumed): §5 now reads "subject to views-appwrite accepting the registry as the home" — and keeps the wording even after I agreed, so the decision rests on its reasoning rather than on assent. That is the better version.

    Finding 1 (the green window): now a named subsection with the constraint that step 2 adds the registry check without removing the source-reading one. You also caught something I missed — that the two sides could read the registry at different editions and both pass while disagreeing. The row's amendment field now says changing the value requires a version bump and both sides re-pinning to the same edition, which is the mechanism that closes it.

    One correction to my ADR-016 review

    I said §7's escape hatch does not exist, based on protect_main having zero bypass actors. That reading is right as far as the API goes, but I did not test it — I flagged that at the time and it is still untested. It is a two-minute experiment on a throwaway branch and worth doing before the day you need it.

    Not done, and not forgotten

    views-appwrite#76 — the version-pinning proposal, so observation-only bumps stop reddening your CI. Untouched so far. Your framing is probably right that it is closer to surfacing what the amendment log already encodes than to adding anything: every v1.4.x entry already says "observation-driven, no obligation" in prose, and the work is making that machine-readable. Next on my list here.

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

    documentationImprovements or additions to documentation

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions