Skip to content

feat(remix): masquage des noms + allowlist SPDX dérivable + trace auditable des confirmations (P0-V3-05) [PROVEN_REVIEW_PENDING] - #77

Merged
openaxcloud merged 5 commits into
mainfrom
docs/v305-remix-license-pii-live-proof
Aug 4, 2026
Merged

feat(remix): masquage des noms + allowlist SPDX dérivable + trace auditable des confirmations (P0-V3-05) [PROVEN_REVIEW_PENDING]#77
openaxcloud merged 5 commits into
mainfrom
docs/v305-remix-license-pii-live-proof

Conversation

@openaxcloud

Copy link
Copy Markdown
Owner

Ce que cette PR change

Aucun code produit. Le lot RMX-3 était déjà mergé (PR #21 + PR #25 fail-closed) et tourne en prod depuis le 20/07. Cette PR apporte la preuve live prod qui manquait, et corrige le texte de preuve de P0_REGISTRY.yaml qui était périmé (il affirmait encore « PR ouverte, PAS mergée » et listait la décision DEC-OWNER-REMIX-DEFAULT-LICENSE comme non tranchée alors qu'Avi l'a tranchée le 20/07).

La branche locale feat/remix-license-pii est périmée : la version de tests/e2e/gallery-remix-license.spec.ts sur main est un sur-ensemble strict de celle de la branche.

État prod vérifié

  • api:05319065be contient l'enforcement ; web:04288e8fa5 contient l'UI de consentement
  • migrations 0076_remix_license_pii + 0077_license_fail_closed appliquées, rolled_back_at = null
  • GalleryListing.remixAllowed : DEFAULT false NOT NULLfail-closed en base
  • 15 listings publiés, 14 remixables (MIT + licenseTextSha256 épinglé), 1 non remixable

Preuve exécutée sur api.e-code.ai

Cas Résultat
listing non autorisé par l'auteur 403 REMIX_NOT_ALLOWED
listing MIT sans consentement 400 REMIX_CONSENT_REQUIRED (+ licenseTextSha256, remixConsentVersion)
acceptLicense mal typé ("true") 400 VALIDATION_ERROR — check !== true, aucune coercition
remix autorisé 201, piiMaskedCount=2, licenseSnapshot épinglé par hash

Ce sont des POST directs sur l'API, sans passer par l'UI : l'enforcement est serveur.

Le clone réel a été fouillé

Export zip décodé (31 fichiers, 97 296 o). La PII de la source (4242 4242 4242 4242, présente dans packages/template-catalog/src/apps/storefront.ts) est :

  • ABSENTE dans les 3 variantes d'espacement, et après normalisation (anti-obfuscation)
  • aucune séquence de 16 chiffres Luhn-valide nulle part dans le clone
  • remplacée par [PII:card masked on remix] aux 2 emplacements d'origine

Non-vacuité vérifiée : texte non vide + marqueurs présents + piiMaskedCount concordant — une archive vide ne pourrait pas satisfaire les trois. Rejeu : scan-clone-for-pii.py.

9 réserves déclarées (à traiter avant signature)

  1. Seule la catégorie card est prouvée en prod (email/phone sur stack CI, iban en mémoire)
  2. Les noms de personnes ne sont pas masqués — aucun matcher ; le clone e2e contient encore Jane Doe
  3. Hors périmètre : IP, NIR/passeport, adresses postales, dates de naissance, téléphones nationaux, fichiers binaires, chemins de fichiers
  4. Le re-scan résiduel n'est pas indépendant (mêmes PII_MATCHERS que le masqueur)
  5. POST /projects/:id/remix ne masque rien (sanitizePii:false) et requireProject accepte un collaborateur non-membre
  6. piiConsentVersion désactive tout le masquage sans vérifier le consentement réel
  7. Aucune allowlist SPDX — on prouve « une licence déclarée et acceptée », pas « cette licence autorise la dérivation »
  8. rightsConfirmed / piiPolicyAccepted validés puis jamais persistés → confirmation des droits inauditable
  9. Production E2E ne se déclenche pas sur push main

Statut

conditionDeCloture (« Licence+consentement appliqués au listing ET masking PII prouvé sur un clone réel ») remplie, mais le point reste OPEN en attente de signature expert et d'arbitrage Avi sur les réserves 2 / 7 / 8.

🤖 Generated with Claude Code

…I masquée sur clone réel

Le lot RMX-3 était déjà mergé (PR #21 + #25) et tourne en prod depuis le 20/07 :
api:05319065be, migrations 0076+0077 appliquées, remixAllowed DEFAULT false NOT NULL.
La branche locale feat/remix-license-pii est périmée (main en est un sur-ensemble).

Preuve exécutée sur api.e-code.ai (pas une stack CI) :
- 403 REMIX_NOT_ALLOWED   (listing non autorisé par l'auteur)
- 400 REMIX_CONSENT_REQUIRED (listing MIT sans consentement, + licenseTextSha256)
- 400 VALIDATION_ERROR    (acceptLicense mal typé — check !== true, pas de coercition)
- 201 + piiMaskedCount=2  (remix autorisé, licenseSnapshot épinglé par hash)

Clone réel relu et FOUILLÉ (export zip décodé, 31 fichiers, 97296 o) : la PII de la
source (4242 4242 4242 4242) est ABSENTE dans les 3 variantes d'espacement et après
normalisation, aucune séquence 16 chiffres Luhn-valide, 2 marqueurs de masquage aux
emplacements d'origine. Non-vacuité vérifiée. Rejouable : scan-clone-for-pii.py.

9 réserves déclarées explicitement (noms non masqués, binaires/chemins hors périmètre,
re-scan résiduel non indépendant, self-remix non masqué, bypass piiConsentVersion,
pas d'allowlist SPDX, rightsConfirmed non persisté, E2E pas sur push main).

Le point reste OPEN en attente de signature expert.
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

ℹ️ Preview deployment not configured

Name Info
Latest commit 0b8d719
Status Preview deployment requires Cloudflare secrets

To enable preview deployments, repository maintainers can add:

  • CLOUDFLARE_API_TOKEN secret
  • CLOUDFLARE_ACCOUNT_ID secret

Built with E-Code

@openaxcloud openaxcloud changed the title docs(parity): P0-V3-05 — preuve LIVE PROD (licence + consentement appliqués, PII masquée sur clone réel) [PROVEN_REVIEW_PENDING] docs(parity): p0-v3-05 — preuve LIVE PROD (licence + consentement appliqués, PII masquée sur clone réel) [PROVEN_REVIEW_PENDING] Aug 3, 2026
…éphone survivant ; la source ne portait qu'une catégorie de PII)
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

ℹ️ Preview deployment not configured

Name Info
Latest commit 459b267
Status Preview deployment requires Cloudflare secrets

To enable preview deployments, repository maintainers can add:

  • CLOUDFLARE_API_TOKEN secret
  • CLOUDFLARE_ACCOUNT_ID secret

Built with E-Code

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e2ed4e451f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

evidenceId: docs/deploy-evidence/2026-07-16-remix/
proof: "PARTIEL : invariant sécurité PROUVÉ live (secret introuvable fichiers+DB+job ; quarantaine 409 ; CLONING refusé avant CREDENTIALS_DETACHED). RMX-3 CODÉ (branche feat/remix-license-pii, PR ouverte, PAS mergée) : remixAllowed/licenseSnapshot(sha256)/consentVersion effectifs + étape SOURCE_SANITIZED (masquage PII email/téléphone international/IBAN/carte Luhn-valide, findings {path,kind,line} sans valeur, re-scan résiduel bloquant) + consentement explicite UI (checkbox, bouton gaté) + refus 400 REMIX_CONSENT_REQUIRED / 403 REMIX_NOT_ALLOWED + immutabilité du snapshot licence prouvée par test — 12 tests dédiés (35 remix+gallery au total), typecheck + build stricts verts. PROUVÉ SUR STACK CI RÉELLE (API+Postgres réels, run 29747404378, commit 67f3b2cb) : parcours écran complet + PII masquées dans le clone + licenseSnapshot/consentVersion sur le job + négatif 400 — evidence docs/deploy-evidence/2026-07-20-remix-license-pii/. RESTE : merge + preuve LIVE PROD à l'écran, fork DB physique + copie objets (RMX-4/5), décision DEC-OWNER-REMIX-DEFAULT-LICENSE (Avi)."
evidenceId: docs/deploy-evidence/2026-08-03-v305-remix-live/
proof: "PROUVÉ LIVE PROD (2026-08-03) — la condition de clôture est remplie, le point reste OPEN en attente de SIGNATURE EXPERT. RMX-3 est MERGÉ depuis le 20/07 (PR #21 + PR #25 fail-closed) et TOURNE EN PROD : api:05319065be, migrations 0076+0077 appliquées (rolled_back_at=null), GalleryListing.remixAllowed DEFAULT false NOT NULL. Sur api.e-code.ai : (A) listing non autorisé -> 403 REMIX_NOT_ALLOWED ; (B) listing MIT sans consentement -> 400 REMIX_CONSENT_REQUIRED avec licenseTextSha256 + remixConsentVersion 2026-07-20.1 ; (C) acceptLicense mal typé -> 400 VALIDATION_ERROR (check !== true, aucune coercition) ; (D) remix autorisé -> 201, piiMaskedCount=2, licenseSnapshot épinglé par hash. CLONE RÉEL RELU ET FOUILLÉ (export zip décodé, 31 fichiers, 97296 o) : la PII de la source (4242 4242 4242 4242, présente dans storefront.ts) est ABSENTE dans les 3 variantes d'espacement ET après normalisation, aucune séquence 16 chiffres Luhn-valide nulle part, 2 marqueurs [PII:card masked on remix] aux emplacements d'origine ; non-vacuité vérifiée (texte non vide + marqueurs présents + piiMaskedCount concordant). Rejouable : scan-clone-for-pii.py. RÉSERVES DÉCLARÉES (ne pas signer sans les traiter) : (1) seule la catégorie 'card' est prouvée en prod, email/phone le sont sur stack CI, iban seulement en mémoire ; (2) les NOMS de personnes ne sont pas masqués (aucun matcher — le clone e2e contient encore 'Jane Doe') ; (3) hors périmètre : IP, NIR/passeport, adresses postales, dates de naissance, téléphones nationaux, fichiers BINAIRES, chemins de fichiers ; (4) le re-scan résiduel n'est PAS indépendant (mêmes PII_MATCHERS que le masqueur) ; (5) POST /projects/:id/remix ne masque rien (sanitizePii:false) et requireProject accepte un collaborateur non-membre ; (6) piiConsentVersion désactive tout le masquage sans vérifier le consentement réel ; (7) aucune allowlist SPDX — licenseId est une chaîne libre, on prouve 'une licence déclarée et acceptée', pas 'cette licence autorise la dérivation' ; (8) rightsConfirmed/piiPolicyAccepted validés puis JAMAIS persistés -> confirmation des droits inauditable ; (9) le workflow Production E2E ne se déclenche pas sur push main."

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Move the proved item out of OPEN

Once this entry claims that the closure condition is fulfilled and only expert review remains, retaining status: OPEN prevents the evidence from appearing in the approval state: generate-approval-status.mjs deliberately forces every declared OPEN item to derive as OPEN, regardless of its proof. As a result, counters and reviewer tooling will continue to classify P0-V3-05 as incomplete rather than PROVEN/PROVEN_REVIEW_PENDING; update the declared status and any metadata required for that state.

Useful? React with 👍 / 👎.

Comment on lines +52 to +54
> Le sha256 de l'archive **n'est pas stable** d'un export à l'autre (l'archive est régénérée à
> la demande) : `4435fc87…` au 1er export, `f4606408…` au rejeu. Ce sont les 3 invariants
> ci-dessous — pas le hash — qui portent la preuve. Rejeu : `scan-clone-for-pii.py`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve raw evidence or make the clone scan reproducible

The central absence-of-PII claim cannot be recomputed from a clean checkout: the evidence directory contains only the derived pii-clone-scan.json, not the exported ZIP/base64 payload, while scan-clone-for-pii.py requires a bearer token with read access to this private clone. replay-negatives.sh creates an unrelated account and never performs a successful remix, so it cannot supply a usable project/token pair either. This also conflicts with EVIDENCE_ARTIFACT_CONTRACT.md I-EVD-1, which requires the raw supporting artifact to be committed; preserve the sanitized export or provide a self-contained replay that creates and scans a fresh clone.

Useful? React with 👍 / 👎.

|---|---|---|
| A — l'auteur n'autorise pas le remix | `403` | `REMIX_NOT_ALLOWED` |
| B — listing MIT mais **sans consentement** | `400` | `REMIX_CONSENT_REQUIRED` (+ `license.textSha256`, `remixConsentVersion=2026-07-20.1`) |
| C — consentement mal typé (`"true"` chaîne) | `400` | `VALIDATION_ERROR` — le check est `!== true`, pas de coercition |

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Add case C to the negative replay

The section presents all three refusals as replayable via replay-negatives.sh, but that script only sends cases A and B and terminates without ever posting acceptLicense: "true". Therefore the malformed-consent behavior recorded in the static transcript cannot be reproduced by the advertised command; add the missing request and verify its expected status/code.

Useful? React with 👍 / 👎.

… rouge Playwright est pré-existant et hors sujet)
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

ℹ️ Preview deployment not configured

Name Info
Latest commit 232550d
Status Preview deployment requires Cloudflare secrets

To enable preview deployments, repository maintainers can add:

  • CLOUDFLARE_API_TOKEN secret
  • CLOUDFLARE_ACCOUNT_ID secret

Built with E-Code

@openaxcloud

Copy link
Copy Markdown
Owner Author

État CI — à lire avant de juger le rouge

15 verts, 4 skipped, 1 rouge (Playwright local stack). Précision importante :

Je ne maquille pas ce rouge pour autant : la suite Playwright locale est globalement cassée sur le repo, c'est un problème distinct qui mérite son propre lot.

…able des confirmations (P0-V3-05)

Corrige les 3 réserves du bloque-lancement identifiées à l'audit du 2026-08-03.

RÉSERVE #2 — NOMS DE PERSONNES (aucun matcher : « Jane Doe » survivait au clone)
Nouveau kind PII `name`. Un nom n'a pas de forme lexicale distinctive, donc le
masquage se fait sur signal STRUCTUREL, jamais sur de la prose :
 - clé explicitement personnelle (firstName/lastName/nom/prenom/contactName…) ;
 - colonne CSV `name` UNIQUEMENT si une colonne personnelle l'accompagne
   (email/phone/iban/ssn/adresse) — `name,email,phone` = fiches de personnes,
   `name,price,stock` = catalogue produit, laissé intact (testé).
`displayName` est volontairement exclu (libellé d'UI). Masquage et re-scan
partagent le MÊME chemin (rewritePersonNames), donc ils ne peuvent pas diverger.

RÉSERVE #7 — ALLOWLIST SPDX (le cœur juridique)
Nouveau module license-policy.ts : `licenseId` n'est plus une chaîne libre. Une
allowlist de 33 identifiants SPDX qui accordent RÉELLEMENT le droit de dériver
(permissives + copyleft + CC autorisant les dérivées). FAIL-CLOSED : tout le
reste est refusé, y compris un SPDX valide non listé, un LicenseRef-* ou une
faute de frappe. On ne devine jamais l'intention d'une licence ; « GPL-3.0 » nu
(ambigu -only/-or-later) est refusé. Les variantes NonCommercial sont refusées —
choix produit assumé et documenté, pas une lecture du texte de licence.
Enforcement en DEUX points : curation (400 REMIX_LICENSE_NOT_DERIVATIVE) et
remix (403, défense en profondeur pour les lignes héritées). L'identifiant
CANONIQUE est persisté, jamais la saisie brute (« apache 2.0 » → « Apache-2.0 »).

RÉSERVE #8 — TRACE AUDITABLE DES CONFIRMATIONS
rightsConfirmed/piiPolicyAccepted étaient validés puis jetés. Migration 0081 :
rightsConfirmedAt/By + piiPolicyAcceptedAt/By (horodatage + userId de l'admin),
persistés ET recopiés dans l'événement d'audit. La migration referme aussi
rétroactivement tout listing remixable dont la licence n'est pas dérivable.

Preuves : 1327 tests verts (dont 9 license-policy, 6 masquage de noms, 6 route
SPDX/trace), build strict services/api à 0 erreur. L'e2e et le test route
cherchent désormais les 5 catégories (nom compris) dans le clone réel et
échouent à les trouver, avec assertion de non-vacuité.
@openaxcloud openaxcloud changed the title docs(parity): p0-v3-05 — preuve LIVE PROD (licence + consentement appliqués, PII masquée sur clone réel) [PROVEN_REVIEW_PENDING] feat(remix): masquage des noms + allowlist SPDX dérivable + trace auditable des confirmations (P0-V3-05) [PROVEN_REVIEW_PENDING] Aug 4, 2026
Conflits uniquement dans packages/database/generated/client (artefact de build) :
résolus en RÉGÉNÉRANT depuis le schéma fusionné, jamais à la main.
Vues parité régénérées, validate-registries vert.
1373 tests verts, typecheck 0 erreur après merge.
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

ℹ️ Preview deployment not configured

Name Info
Latest commit 657f759
Status Preview deployment requires Cloudflare secrets

To enable preview deployments, repository maintainers can add:

  • CLOUDFLARE_API_TOKEN secret
  • CLOUDFLARE_ACCOUNT_ID secret

Built with E-Code

@openaxcloud
openaxcloud merged commit e41821f into main Aug 4, 2026
19 of 20 checks passed
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