Skip to content

docs(handoff): étape 3B/PR-A — et le fait que le merge a devancé le handoff - #283

Merged
thierryvm merged 1 commit into
mainfrom
docs/handoff-3b-a
Jul 27, 2026
Merged

docs(handoff): étape 3B/PR-A — et le fait que le merge a devancé le handoff#283
thierryvm merged 1 commit into
mainfrom
docs/handoff-3b-a

Conversation

@thierryvm

@thierryvm thierryvm commented Jul 27, 2026

Copy link
Copy Markdown
Owner

Deux fichiers de documentation qui devaient partir avec #282 et sont arrivés trop tard : la PR a été mergée (d386aae) pendant que j'écrivais le handoff, GitHub a supprimé la branche, et mon push l'a recréée. Ces deux fichiers vivaient donc sur une branche morte, hors de main. Aucun code, aucune migration.

1. Le handoff canonique de la session

docs/handoffs/2026-07-27-1900-etape-3b-pr-a-file-suppression-inerte.md, 9 sections selon le template. Double redondance : ce fichier et le miroir dans le vault Obsidian — slug ankora lu dans 10_Projects/*/_index.md, jamais inféré.

2. Le fait que l'historique Git ne dira pas

Ajouté au rapport de PR à la demande de @Thierry, et c'est le point qui justifie à lui seul cette PR :

La production portait déjà les deux migrations avant le merge. Le comportement de la base a changé au moment du db push, pas au moment du merge.

Concrètement, et indépendamment de main : deletion_self_insert supprimée, deletion_self_update resserrée en pending → cancelled, claim_pending_deletions fermée à anon et authenticated, purge_audit_log_older_than_12_months() passée en SECURITY INVOKER.

Pourquoi c'est sûr, et pourquoi ce n'est pas une supposition : deletion_requests n'est écrit qu'en un seul endroit du code — src/lib/gdpr/deletion.ts, via createServiceRoleClient(), qui contourne la RLS. Aucune insertion client n'existe. La politique retirée accordait une capacité que rien n'utilisait.

Et si #282 n'avait pas été mergée : la migration serait restée. Un revert de PR sur GitHub ne défait pas un db push. Elle est additive et ses politiques sont plus restrictives qu'avant, donc sans danger — mais présente. Revenir en arrière pour de bon demanderait une migration inverse écrite exprès.

3. Mesure avant prescription

@Thierry a refusé qu'une future PR d'hygiène propose un revoke sur la foi de la documentation. touch_updated_at() est une fonction de trigger branchée sur 6 tables (accounts, charges, commitments, users, workspace_settings, workspaces) : la révoquer à l'aveugle pouvait casser chaque écriture de l'application.

Mesuré en trois temps sur la pile locale, en rôle authenticated avec claims JWT :

updated_at remis à 2020-01-01, UPDATE  →  2026-07-27 17:02:40.346726   (avant revoke)
revoke execute … from public, anon, authenticated
updated_at remis à 2020-01-01, UPDATE  →  2026-07-27 17:02:40.368922   (APRÈS revoke)

updated_at bouge toujours. Le privilège EXECUTE d'une fonction de trigger est vérifié à la création du trigger, pas à chaque déclenchement. Le revoke ne casse rien. Grant local restauré après la mesure.

assert_rls_coverage() : aucun appelant dans le dépôt — le « Callable from CI » de 20260417000002:36 décrit une intention jamais réalisée.

Les deux révocations de la future PR grants sont donc prouvées, pas documentées. Cette PR-là part après PR-B, décision @Thierry : ces fonctions sont invoquées par toutes les policies RLS, et ce risque ne doit pas courir en parallèle de l'armement d'une suppression de comptes.

🤖 Generated with Claude Code

Summary by Sourcery

Documenter l’état de la base de données de production et le calendrier de déploiement pour les migrations de la file de suppression, et ajouter le rapport de passation pour PR-3B-A.

Documentation :

  • Étendre le rapport PR-3B-A avec une description explicite de la manière dont les migrations de la file de suppression affectent déjà la production indépendamment de la fusion du code, et pourquoi cela est sans risque.
  • Ajouter un document de passation détaillé pour l’étape 3B / PR-A couvrant l’état de la branche, le statut de déploiement, les décisions prises, les actions de suivi et les garde-fous pour les travaux futurs sur la file de suppression et les révocations de privilèges.
Original summary in English

Summary by Sourcery

Document the production database state and deployment timing for the deletion queue migrations, and add the handoff report for PR-3B-A.

Documentation:

  • Extend the PR-3B-A report with an explicit description of how the deletion queue migrations already affect production independently of the code merge, and why this is safe.
  • Add a detailed handoff document for step 3B / PR-A covering branch state, deployment status, decisions taken, follow-up actions, and guardrails for future work on the deletion queue and privilege revocations.

…handoff

PR #282 a été mergée (d386aae) pendant que j'écrivais le handoff, et GitHub a
supprimé la branche. Mon push l'a recréée : ces deux fichiers étaient donc sur
une branche morte, hors de main. Reportés ici depuis main.

HANDOFF CANONIQUE — double redondance : ce fichier plus le miroir dans le vault
Obsidian (slug `ankora` LU dans 10_Projects/*/_index.md, jamais inféré).

Le fait qu'il ajoute, et que l'historique Git ne dira pas : la production
portait déjà les deux migrations AVANT le merge. Le comportement de la base a
changé au moment du `db push`, pas au moment du merge — `deletion_self_insert`
supprimée, `deletion_self_update` resserrée, claim_pending_deletions fermée à
anon. C'est sûr parce que `deletion_requests` n'est écrit qu'en un seul endroit
du code, via service_role, qui contourne la RLS : aucune insertion client
n'existe. Vérifié, pas supposé.

Et si la PR n'avait pas été mergée, la migration serait restée : un revert de PR
ne défait pas un `db push`.

MESURE AVANT PRESCRIPTION. `touch_updated_at()` est branchée sur 6 tables : la
révoquer à l'aveugle pouvait casser chaque écriture de l'application. Test en
trois temps, rôle authenticated avec claims JWT :

  updated_at remis à 2020-01-01, UPDATE  ->  17:02:40.346726  (avant revoke)
  revoke execute … from public, anon, authenticated
  updated_at remis à 2020-01-01, UPDATE  ->  17:02:40.368922  (APRÈS revoke)

updated_at bouge toujours : le privilège EXECUTE d'une fonction de trigger est
vérifié à la CRÉATION du trigger, pas à chaque déclenchement. Grant local
restauré. `assert_rls_coverage()` : aucun appelant dans le dépôt.

Les deux révocations de la future PR grants sont donc prouvées, pas documentées.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@vercel

vercel Bot commented Jul 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ankora Ready Ready Preview, Comment Jul 27, 2026 5:11pm

@github-actions github-actions Bot added status:review-needed Ready for review type:docs Documentation only labels Jul 27, 2026
@sourcery-ai

sourcery-ai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Guide du relecteur

Cette PR ajoute la documentation manquante pour la PR #282 concernant la fonctionnalité de file d’attente de suppression, en précisant que le comportement de la base de données de production a changé au moment du db push et non au moment du merge. Elle décrit également comment les révocations de privilèges sur les fonctions ont été validées empiriquement. Aucun code applicatif ni schéma n’est modifié, seuls des fichiers de documentation sont mis à jour ou créés.

Diagramme de séquence pour l’impact de db_push vs merge GitHub sur la production

sequenceDiagram
    actor Developer
    participant SupabaseCLI as Supabase_CLI
    participant ProdDB as ankora_prod_db
    participant GitHub as GitHub_main

    Developer->>SupabaseCLI: db push
    SupabaseCLI->>ProdDB: apply 20260727000001_deletion_queue.sql
    SupabaseCLI->>ProdDB: apply 20260727000002_claim_grants_hardening.sql
    ProdDB-->>ProdDB: deletion_self_insert removed
    ProdDB-->>ProdDB: deletion_self_update restricted pending→cancelled
    ProdDB-->>ProdDB: claim_pending_deletions created (EXECUTE closed to anon, authenticated)
    ProdDB-->>ProdDB: purge_audit_log_older_than_12_months SECURITY INVOKER

    Note over ProdDB: Production behavior changes at db push

    Developer->>GitHub: merge PR_282 into main
    GitHub-->>GitHub: update main branch

    Note over GitHub,ProdDB: Git history reflects merge
    Note over ProdDB: Database behavior was already changed by db push
Loading

Modifications au niveau des fichiers

Changement Détails Fichiers
Préciser dans le rapport de PR que la production exécute déjà les deux migrations et que le comportement a changé lors du db push, et non lors du merge, en incluant pourquoi c’est sûr et ce qui se passerait si la PR était revert.
  • Ajouter une nouvelle section décrivant que les deux migrations liées au RGPD ont été poussées en production avant que le code de la fonctionnalité ne soit mergé dans main.
  • Documenter les effets concrets des migrations sur les politiques, fonctions et RLS liées à deletion_requests et claim_pending_deletions.
  • Expliquer pourquoi la suppression de la politique d’insertion orientée client est sûre compte tenu des chemins d’écriture réels, et ce qui reste vrai même si la PR-A n’était pas mergée.
docs/prs/PR-3B-A-report.md
Documenter que les futures révocations de privilèges sur les fonctions utilitaires de base de données ont d’abord été validées expérimentalement et n’ont aucun impact à l’exécution sur l’application.
  • Ajouter une section décrivant comment la révocation du privilège EXECUTE sur touch_updated_at() a été testée et s’est avérée ne pas affecter le comportement des triggers.
  • Consigner que assert_rls_coverage() n’a aucun appelant et qu’il est donc sûr de révoquer ce privilège pour les rôles anon et authenticated.
  • Préciser que les futures révocations devront explicitement inclure public afin d’éviter de répéter une précédente suppression incomplète de droits.
docs/prs/PR-3B-A-report.md
Ajouter un document de passation canonique pour la session de PR-A sur la file d’attente de suppression, capturant l’état git, le statut des migrations, les décisions, les arguments de sécurité et les garde-fous.
  • Créer un nouveau fichier de passation en suivant le modèle cc-handoff, résumant l’état de la branche, le statut de la CI et le plan pour PR-A et PR-B.
  • Détailler que les deux migrations sont déjà appliquées en production et en local, pourquoi elles sont sûres même si la PR n’est pas mergée, et que revert la PR n’annule pas le db push.
  • Consigner les décisions de la session, les décisions en attente pour le tech lead, les garde-fous et anti‑patterns pour les travaux futurs, ainsi que des annexes avec mesures et extraits SQL pour l’analyse des privilèges et le comportement RLS.
docs/handoffs/2026-07-27-1900-etape-3b-pr-a-file-suppression-inerte.md

Conseils et commandes

Interagir avec Sourcery

  • Déclencher une nouvelle revue : Commentez @sourcery-ai review sur la pull request.
  • Poursuivre les discussions : Répondez directement aux commentaires de revue de Sourcery.
  • Générer une issue GitHub à partir d’un commentaire de revue : Demandez à Sourcery de créer une issue à partir d’un commentaire de revue en y répondant. Vous pouvez également répondre à un commentaire de revue avec @sourcery-ai issue pour créer une issue à partir de celui-ci.
  • Générer un titre de pull request : Écrivez @sourcery-ai n’importe où dans le titre de la pull request pour générer un titre à tout moment. Vous pouvez aussi commenter @sourcery-ai title sur la pull request pour (re)générer le titre à tout moment.
  • Générer un résumé de pull request : Écrivez @sourcery-ai summary n’importe où dans le corps de la pull request pour générer un résumé de PR à tout moment exactement à l’endroit souhaité. Vous pouvez également commenter @sourcery-ai summary sur la pull request pour (re)générer le résumé à tout moment.
  • Générer un guide du relecteur : Commentez @sourcery-ai guide sur la pull request pour (re)générer le guide du relecteur à tout moment.
  • Résoudre tous les commentaires Sourcery : Commentez @sourcery-ai resolve sur la pull request pour résoudre tous les commentaires Sourcery. Utile si vous avez déjà traité tous les commentaires et ne souhaitez plus les voir.
  • Ignorer toutes les revues Sourcery : Commentez @sourcery-ai dismiss sur la pull request pour ignorer toutes les revues Sourcery existantes. Particulièrement utile si vous souhaitez repartir de zéro avec une nouvelle revue – n’oubliez pas de commenter @sourcery-ai review pour déclencher une nouvelle revue !

Personnaliser votre expérience

Accédez à votre tableau de bord pour :

  • Activer ou désactiver des fonctionnalités de revue telles que le résumé de pull request généré par Sourcery, le guide du relecteur et d’autres.
  • Changer la langue de la revue.
  • Ajouter, supprimer ou modifier des instructions de revue personnalisées.
  • Ajuster d’autres paramètres de revue.

Obtenir de l’aide

Original review guide in English

Reviewer's Guide

This PR adds missing documentation for PR #282 about the deletion queue feature, clarifying that production database behavior changed at the time of the db push rather than the merge, and records how function privilege revocations were empirically validated; no application code or schema is modified, only documentation files are updated and created.

Sequence diagram for db_push vs GitHub merge impact on production

sequenceDiagram
    actor Developer
    participant SupabaseCLI as Supabase_CLI
    participant ProdDB as ankora_prod_db
    participant GitHub as GitHub_main

    Developer->>SupabaseCLI: db push
    SupabaseCLI->>ProdDB: apply 20260727000001_deletion_queue.sql
    SupabaseCLI->>ProdDB: apply 20260727000002_claim_grants_hardening.sql
    ProdDB-->>ProdDB: deletion_self_insert removed
    ProdDB-->>ProdDB: deletion_self_update restricted pending→cancelled
    ProdDB-->>ProdDB: claim_pending_deletions created (EXECUTE closed to anon, authenticated)
    ProdDB-->>ProdDB: purge_audit_log_older_than_12_months SECURITY INVOKER

    Note over ProdDB: Production behavior changes at db push

    Developer->>GitHub: merge PR_282 into main
    GitHub-->>GitHub: update main branch

    Note over GitHub,ProdDB: Git history reflects merge
    Note over ProdDB: Database behavior was already changed by db push
Loading

File-Level Changes

Change Details Files
Clarify in the PR report that production already runs the two migrations and that behavior changed on db push, not on merge, including why this is safe and what would happen if the PR were reverted.
  • Add a new section describing that the two GDPR-related migrations were pushed to production before the feature code was merged to main.
  • Document the concrete effects of the migrations on policies, functions, and RLS related to deletion_requests and claim_pending_deletions.
  • Explain why removing the client-facing insertion policy is safe given the actual write paths, and what remains true even if PR-A were not merged.
docs/prs/PR-3B-A-report.md
Document that future privilege revocations on database helper functions were experimentally validated first and have no runtime impact on the application.
  • Add a section describing how EXECUTE privilege revocation on touch_updated_at() was tested and shown not to affect trigger behavior.
  • Record that assert_rls_coverage() has no callers and is therefore safe to revoke for anon and authenticated roles.
  • Clarify that future revokes must explicitly include public to avoid repeating a previous incomplete grant removal.
docs/prs/PR-3B-A-report.md
Add a canonical handoff document for the deletion queue PR-A session, capturing git state, migration status, decisions, safety arguments, and anti-footguns.
  • Create a new handoff file following the cc-handoff template, summarizing branch state, CI status, and the plan for PR-A and PR-B.
  • Detail that the two migrations are already applied in production and local, why they are safe even if the PR is not merged, and that reverting the PR does not undo db push.
  • Record session decisions, pending decisions for the tech lead, guardrails and anti-patterns for future work, and annexes with measurements and SQL snippets for privilege analysis and RLS behavior.
docs/handoffs/2026-07-27-1900-etape-3b-pr-a-file-suppression-inerte.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Salut - j'ai passé en revue tes modifications et elles sont super !


Sourcery est gratuit pour l’open source - si tu apprécies nos revues, pense à les partager ✨
Aide-moi à être plus utile ! Clique sur 👍 ou 👎 sur chaque commentaire et j’utiliserai tes retours pour améliorer tes revues.
Original comment in English

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@thierryvm
thierryvm merged commit 207c064 into main Jul 27, 2026
11 checks passed
@thierryvm
thierryvm deleted the docs/handoff-3b-a branch July 27, 2026 17:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status:review-needed Ready for review type:docs Documentation only

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant