Skip to content

feat(gallery): politique licence fail-closed — non-remixable par défaut - #25

Merged
openaxcloud merged 1 commit into
mainfrom
feat/remix-license-failclosed
Jul 20, 2026
Merged

feat(gallery): politique licence fail-closed — non-remixable par défaut#25
openaxcloud merged 1 commit into
mainfrom
feat/remix-license-failclosed

Conversation

@openaxcloud

Copy link
Copy Markdown
Owner

Quoi (directive Avi 20/07, point 1)

  • Défaut = ALL_RIGHTS_RESERVED, non-remixable : remixAllowed DEFAULT false (migration 0077) + rétroactif : tout listing sans licenseId repasse non-remixable.
  • Remixable = choix explicite en 3 volets à la curation : licence (id+texte) → sinon 400 REMIX_LICENSE_REQUIRED ; confirmation des droits + acceptation politique PII → sinon 400 REMIX_RIGHTS_CONFIRMATION_REQUIRED.
  • Défense en profondeur au point d'enforcement : remix d'un listing sans licence en base → 403 REMIX_LICENSE_REQUIREDaucun fallback, aucune licence appliquée silencieusement.
  • UI : bouton Remix déjà absent/bloqué avec explication quand non-remixable (existant).
  • 39 tests verts dont 4 négatifs fail-closed neufs ; typecheck 0.

Comportement prod AVANT cette PR (réponse à la question d'Avi)

  • L'absence de licence ne bloquait PAS le remix (défaut remixAllowed=true, mig 0076) ; l'UI affichait « No license specified by the author » et le serveur enregistrait licenseId: null sur le job — aucun fallback de valeur ;
  • AUCUN MIT appliqué automatiquement à des projets utilisateurs : « MIT » n'existe que dans des fixtures de test/e2e, jamais dans un chemin d'écriture produit ni une migration.

⚠️ Pas de merge sans feu vert d'Avi.

🤖 Generated with Claude Code

…ut, licence explicite + confirmations exigées

- Migration 0077 : remixAllowed DEFAULT false + rétroactif (licenseId NULL → false).
- Curation : remixAllowed=true exige licenceId+licenseText (400
  REMIX_LICENSE_REQUIRED) + rightsConfirmed + piiPolicyAccepted (400
  REMIX_RIGHTS_CONFIRMATION_REQUIRED). Aucun choix implicite.
- Défense en profondeur : remix d'un listing sans licence en base → 403
  REMIX_LICENSE_REQUIRED (aucun fallback, jamais de MIT silencieux).
- 39 tests remix+gallery verts (4 négatifs fail-closed neufs), typecheck 0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 20, 2026 16:23
@github-actions

Copy link
Copy Markdown
Contributor

ℹ️ Preview deployment not configured

Name Info
Latest commit ec1a037
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: 4a9fcc1dc2

ℹ️ 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".

-- un listing sans licence explicite n'est JAMAIS remixable.
ALTER TABLE "GalleryListing" ALTER COLUMN "remixAllowed" SET DEFAULT false;
-- Rétroactif : tout listing sans licence déclarée redevient non-remixable.
UPDATE "GalleryListing" SET "remixAllowed" = false WHERE "licenseId" IS NULL;

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 Mark partially licensed legacy rows non-remixable

Before this commit, the admin endpoint allowed licenseId without licenseText and defaulted remixAllowed to true, so existing rows can have a non-null ID but no text/hash. This predicate leaves those rows remixable; the public API consequently exposes remixAllowed: true and the UI enables Remix, but the new enforcement at app.ts:21809 always rejects the request because licenseTextSha256 is missing. Include incomplete license snapshots (at least a null hash/text) in this backfill so the public state matches enforcement.

Useful? React with 👍 / 👎.

Copilot AI 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.

Pull request overview

Cette PR implémente une politique de licence fail-closed pour les remixes de la Gallery : un listing est non-remixable par défaut et ne devient remixable que via une curation explicite (licence + confirmations), avec une vérification “défense en profondeur” côté endpoint de remix.

Changes:

  • Bascule du défaut remixAllowed à false (DB + stores) et rétroaction sur les listings sans licenseId (migration 0077).
  • Durcissement API : validation curator /admin/gallery-listings (licence + confirmations) et enforcement /gallery/:slug/remix (403 si licence absente).
  • Mise à jour/ajout de tests e2e + unit couvrant les cas négatifs fail-closed.

Reviewed changes

Copilot reviewed 7 out of 12 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/e2e/gallery-remix-license.spec.ts Fixture e2e mise à jour pour inclure les confirmations requises quand remixAllowed: true.
services/api/src/tests/test-api-store.ts Défaut remixAllowed aligné sur la politique fail-closed dans le store de test.
services/api/src/tests/gallery-routes.spec.ts Ajustement fixtures + ajout de tests négatifs (curation + enforcement).
services/api/src/prisma-store.ts Défaut remixAllowed aligné sur fail-closed dans le store Prisma.
services/api/src/app.ts Enforcement remix (403 si licence absente) + validation curator pour remixAllowed=true (licence + confirmations).
packages/database/prisma/schema.prisma remixAllowed passe à @default(false) avec doc associée.
packages/database/prisma/migrations/0077_license_fail_closed/migration.sql Migration : default false + rétroactif remixAllowed=false quand licenseId IS NULL.
packages/database/generated/client/schema.prisma Regénération du schéma client (default false + doc).
packages/database/generated/client/package.json Mise à jour du nom de package généré (hash).
packages/database/generated/client/index.js Inline schema Prisma mis à jour (default false).
packages/database/generated/client/index.d.ts Commentaire types générés mis à jour pour refléter fail-closed.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread services/api/src/app.ts

// FAIL-CLOSED en profondeur : même un listing marqué remixable ne se
// remixe pas sans licence explicite enregistrée (aucun fallback).
if (!listing.licenseId || !listing.licenseTextSha256) {
openaxcloud added a commit that referenced this pull request Jul 20, 2026
…EVIEW_PENDING, compteurs/supersession dérivés, resoumission détaillée (#26)

- RÈGLE MAÎTRESSE : CLOSED exige un ReviewReceipt COMPLET (registre + gardes
  validateur + dérivation) ; 22 signés → PROVEN_REVIEW_PENDING (reçu
  RR-20260720-CODEX-01 INCOMPLET, responseHash manquant — jamais un nom saisi
  à la main) ; 8 QUICK remédiés → PROVEN_REVIEW_PENDING.
- COUNTER_RECONCILIATION_20260720.md GÉNÉRÉ (formule + IDs + source par
  métrique, drift-check CI) — 4 questions répondues.
- SUPERSESSION_REGISTRY : couverture 100% des IDs hérités, 164 surfaces et
  122 work items DÉRIVÉS des tables (garde CI).
- REVIEWER_RESUBMISSION_A_20260720.md (+ outputs/) : resoumission POUR REVUE.
- DEC-OWNER-REMIX-DEFAULT-LICENSE → DECIDED (fail-closed ; code = PR #25).
- V3_05_REMIX_AUDIT_20260720.md : audit par exigence — V3-05 NON clos.

Co-authored-by: Avi <avi@snatchbot.me>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@openaxcloud
openaxcloud merged commit 7e001f3 into main Jul 20, 2026
15 of 18 checks passed
@openaxcloud
openaxcloud deleted the feat/remix-license-failclosed branch July 20, 2026 17:25
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