Skip to content

fix: refuse declarations when source ownership is unknown - #54

Closed
albertovincenzi wants to merge 3 commits into
fix/reject-queue-feedbackfrom
fix/fail-closed-source-inventory
Closed

fix: refuse declarations when source ownership is unknown#54
albertovincenzi wants to merge 3 commits into
fix/reject-queue-feedbackfrom
fix/fail-closed-source-inventory

Conversation

@albertovincenzi

Copy link
Copy Markdown
Collaborator

Problema

Il controllo di ownership delle code fisiche introdotto dalla PR #32 consultava anche lo store, ma la lettura era best effort. Se la scansione falliva, veniva troncata dal broker o conteneva un documento non leggibile da questa versione di Gate, la dichiarazione proseguiva come se la coda fosse libera.

Su una replica non ancora riconciliata questo può avviare un secondo consumer group sulla stessa sorgente: entrambi ricevono ogni messaggio e l'egress viene duplicato.

Fix

La dichiarazione ora fallisce con 502 quando Gate non può dimostrare che l'inventario remoto sia completo:

  • errore di trasporto durante la lettura;
  • pagina clamped/troncata;
  • documento corrotto o scritto da una versione più nuova e quindi non decodificabile.

Un conflitto verificato continua invece a rispondere 409. Restore e reconcile non cambiano comportamento: il fail closed riguarda soltanto una nuova mutazione richiesta dal caller.

Verifica per Alice

Il test live usa una seconda replica con registry vuoto e copre entrambi i casi:

  1. il broker rifiuta soltanto getPrefix;
  2. lo store risponde ma contiene un documento futuro non leggibile.

In entrambi i casi la seconda dichiarazione riceve 502, nessun runtime viene avviato e la risposta nomina l'impossibilità di provare l'ownership esclusiva.

Controlli locali:

  • cargo test --workspace
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo fmt --all -- --check

Dipendenze e trade-off

Questa PR è stacked su #32, perché protegge il controllo esteso a tutte le sorgenti fisiche. È consigliato integrare anche #28 prima di questa: #28 pagina l'intero store; senza #28, oltre il limite di una pagina Gate rifiuta in sicurezza nuove dichiarazioni invece di rischiare un doppio owner.

Questa PR chiude gli errori e gli inventari incompleti, ma non pretende di chiudere la finestra tra due scansioni simultanee su repliche diverse. Quella richiede un protocollo di lock con rinnovo e fencing, non un semplice TTL.

albertovincenzi and others added 3 commits September 5, 2026 01:20
…oes not name

`Stored::complete` is a fact about the whole NAMESPACE, not about this graph.
Refusing every declare on it means one row this build cannot read stops the
control plane for every application in the deployment — and `doc.rs` makes that
row a design goal, not an accident: `deny_unknown_fields` is there so a newer
build's document is unreadable by an older one. A rolling deploy or a rollback
therefore turns every declare and every sync into a 502 for tenants that share
nothing but a broker. Without the paging fix it is worse: past a thousand
stored graphs the inventory is permanently clamped and no declare ever succeeds
again.

The refusal only ever had teeth for a source Gate does not name. An owned
ingress and an interior queue are derived from `{app}.{graph}.{node}`, so no
other graph key can mint the same name and no unreadable document can be
claiming one. A user-declared ingress is free-form, and there the question is
real and still fails closed — the existing regression covers exactly that
shape.

Claude-Session: https://claude.ai/code/session_012K8u7BEJyd6nDNMCQAgH3z
@alice-viola

Copy link
Copy Markdown
Contributor

Landed on master via #67 (merge commit 944ee9b) as part of the 62-PR integration — this PR's head commit 51b3558 is an ancestor of master. GitHub could not mark it merged automatically because its base is fix/reject-queue-feedback, not master. Closing as landed.

@alice-viola alice-viola closed this Sep 7, 2026
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.

2 participants