Skip to content

release: bind parity claims to the distributed plugin and runtime artifacts #729

Open

Description

@cdeust

Problem and evidence

Main and both plugin manifests still declare 4.23.5. Codex runtime.py selects exactly hypermnesia-mcp[postgresql,sqlite]==4.23.5, while Claude launches code from its installed plugin directory. The published v4.23.5 tag resolves to 0037cea.

Downloaded GitHub wheel and MCPB checksums match their published checksums. Each contains 660 mcp_server Python members, all matching the tag; 618 match main and 42 differ. output_streams.py exists in main but is absent in both archives. This is a coherent older release. A main-only fix cannot automatically be attributed to the pinned runtime.

Wheel SHA256 fbe671f68e732f1edad591c299987950f670a1e3fde6dfe5359b2431787e75fc; MCPB SHA256 5397c73cf2126b81b6e61e892c555b22b0e22b26161f5e8e57424365e03b59e8. The inspected GitHub archive does not establish the bytes of any already installed uv/PyPI runtime.

Acceptance evidence

  • Define supported plugin/runtime pairings and diagnose unsupported combinations.
  • Record source revision and installed artifact digests in diagnostics and verification receipts.
  • Test the exact distributed combination in both hosts before attributing published fixes.
  • Keep main-only evidence separately labeled.
  • Reuse checksum and attestation mechanisms to verify installed artifact identity.

Scope and related work

Closed #628 concerns automatic tagging. This concerns artifact identity and delivery of parity fixes.

Raised by the global Hindsight/Cortex audit. The target is a measurable local-first experience with the same supported semantics in Claude and Codex. Acceptance criteria describe a target, not current conformance. Static findings refer to the pinned source; probes identify their boundary.

Primary references

plugins/hypermnesia-mcp-codex/scripts/runtime.py:18; scripts/launcher.py:36; v4.23.5 release

Activity

  1. cdeust commented on Nov 5, 2026

    @cdeust
    OwnerAuthor

    Autopilot : tranche 1 dans #887 (Refs #729, pas Closes).

    Elle couvre en partie les critères 2 et 4 : python -m mcp_server.doctor indique maintenant quel artefact il exécute.

    • Pour une roue installée : sa version et un digest sha256 des membres mcp_server de son RECORD, avec une vérification sur disque de chaque membre.
    • Pour un arbre source : sa révision git et le même digest, étiqueté comme preuve de source.

    Reçu : une roue construite depuis la branche donne le même digest (f8b4ad45…c9fc, 732 membres) que l'arbre dont elle vient.

    Tranches restantes :

    1. Écrire la révision source et le digest d'artefact dans les reçus de vérification (benchmarks, receipts de parité), pas seulement dans le doctor.
    2. Définir les paires plugin/runtime supportées : la version du manifeste plugin doit égaler la version de la roue. Le doctor doit diagnostiquer une paire non supportée, côté Claude comme côté Codex (runtime.py le fait déjà pour Codex au lancement).
    3. Comparer le digest installé au digest publié (checksums et attestations de release, release.yml) pour vérifier l'identité de l'artefact distribué.
    4. Tester la combinaison distribuée exacte dans les deux hôtes avant d'attribuer un correctif publié. Il faut un runner avec Claude et Codex installés, donc pas faisable depuis cet environnement.

    Generated by Claude Code

  2. cdeust commented on Nov 6, 2026

    @cdeust
    OwnerAuthor

    Autopilot : la tranche 1 (#887) est fusionnée. L'issue reste ouverte pour les tranches 2 à 5, listées dans mon commentaire précédent.

    La revue Claude 2/3 a laissé trois notes non bloquantes sur le check Runtime artifact identity. Je les ajoute aux travaux restants :

    • _REINSTALL omet le --python <interpréteur> que passe runtime.py setup.
    • Un arbre sans .git échoue, mais le check lui conseille git -C … status, ce qui ne sert à rien dans ce cas.
    • Une installation dont le RECORD est absent est décrite comme un arbre source au lieu de faire échouer le check.
    • Une note de la revue 1 aussi : tree_members ne respecte pas .gitignore. Un fichier ignoré sous mcp_server/ (par exemple .DS_Store) change donc le digest de l'arbre sans changer celui de la roue.

    Generated by Claude Code

  3. cdeust commented on Nov 6, 2026

    @cdeust
    OwnerAuthor

    Autopilot : tranche 2 dans #904 (Refs #729, pas Closes).

    Elle corrige les quatre notes de revue laissées sur le check Runtime artifact identity livré par #887 :

    • Dans un checkout, le digest couvre les fichiers que git garde dans l'arbre. Un .DS_Store ignoré ne le change plus.
    • Un arbre sans .git est nommé outside git et passe sur son digest, au lieu d'échouer avec un conseil git status inutile.
    • Une roue installée sans RECORD fait échouer le check, au lieu d'être décrite comme un arbre source.
    • Le correctif de réinstallation nomme --python <interpréteur>.

    Reçu : avec un .DS_Store ignoré présent, la roue construite et le checkout donnent le même digest (d8bf266c…7f8e, 735 membres).

    Tranches restantes (inchangées depuis mon commentaire du 2026-11-05) :

    1. Écrire la révision source et le digest d'artefact dans les reçus de vérification.
    2. Définir les paires plugin/runtime supportées, et diagnostiquer une paire non supportée côté Claude comme côté Codex.
    3. Comparer le digest installé aux checksums et attestations de release.
    4. Tester la combinaison distribuée exacte dans les deux hôtes. Il faut un runner avec Claude et Codex.

    Generated by Claude Code

  4. cdeust commented on Nov 6, 2026

    @cdeust
    OwnerAuthor

    Autopilot : tranche 3 dans #916 (Refs #729, pas Closes).

    Elle couvre la tranche restante n° 2 côté Claude : python -m mcp_server.doctor a un check optionnel Plugin/runtime pairing. Lancé avec CLAUDE_PLUGIN_ROOT, il échoue si le processus importe mcp_server hors de ce répertoire, ou si .claude-plugin/plugin.json déclare une autre version que le code exécuté (roue installée, sinon pyproject.toml). Sans CLAUDE_PLUGIN_ROOT, il passe et le dit. Côté Codex, runtime.py vérifie déjà la paire au lancement.

    Reçus : 19 tests, porte de mutation locale à 0 survivant, exécution réelle sur ce checkout (Claude plugin 4.23.5 runs its own mcp_server 4.23.5).

    Tranches restantes :

    1. Écrire la révision source et le digest d'artefact dans les reçus de vérification (benchmarks, reçus de parité).
    2. Comparer le digest installé aux checksums et attestations de release (release.yml).
    3. Tester la combinaison distribuée exacte dans les deux hôtes (runner avec Claude et Codex requis).

    C'est ma 3e tentative sur cette issue. Les deux premières ont été fusionnées (#887, #904), donc pas de hold.


    Generated by Claude Code

  5. cdeust commented on Nov 6, 2026

    @cdeust
    OwnerAuthor

    Autopilot : #916 (tranche 3) est fusionnée avant que les deux correctifs annoncés en réponse à la revue 1 (commentaire) ne partent. Je les ajoute aux tranches restantes :

    • doctor_pairing.py et doctor_artifact.py attrapent (OSError, ValueError) seulement. Sous Python 3.11 et 3.12, une boucle de liens symboliques fait lever RuntimeError à Path.resolve(), ce qui interrompt tout le doctor au lieu de faire échouer ce seul check optionnel. Il faut ajouter RuntimeError dans les deux modules, avec un test de boucle de liens.
    • Un test explicite pour une distribution installée localisée hors du répertoire du plugin, qui doit lire pyproject.toml et non la version de la distribution.

    Generated by Claude Code

  6. cdeust commented on Nov 6, 2026

    @cdeust
    OwnerAuthor

    Autopilot : tranche 4 dans #919 (Refs #729, pas Closes).

    Elle corrige les deux notes de revue de #916 restées en suspens :

    • Le doctor ne s'arrête plus sur une boucle de liens symboliques. Sous Python 3.11 et 3.12, Path.resolve() lève RuntimeError, que doctor_pairing.py et doctor_artifact.py n'attrapaient pas. Chacun des deux checks optionnels échoue maintenant seul et nomme la boucle.
    • Nouveau test : une distribution installée hors du répertoire du plugin ne donne pas sa version, le check lit pyproject.toml.

    Reçus :

    • Les deux tests de boucle échouent sans le correctif et passent avec (64 passed, 1 skipped sur les tests du doctor).
    • CLAUDE_PLUGIN_ROOT=<boucle> python -m mcp_server.doctor va jusqu'au bout.

    Tranches restantes :

    1. Écrire la révision source et le digest d'artefact dans les reçus de vérification (benchmarks, reçus de parité).
    2. Comparer le digest installé aux checksums et attestations de release (release.yml).
    3. Tester la combinaison distribuée exacte dans les deux hôtes (il faut un runner avec Claude et Codex).

    Les trois premières tranches ont été fusionnées (#887, #904, #916), donc pas de hold.


    Generated by Claude Code

  7. cdeust commented on Nov 7, 2026

    @cdeust
    OwnerAuthor

    Autopilot : tranche 5 dans #947 (Refs #729, pas Closes, brouillon).

    Le MANIFEST.json des benchmarks porte maintenant runtime_artifact, c'est-à-dire l'identité d'artefact que calcule cortex doctor : wheel ou arbre source, révision, modifications non commitées, digest des membres mcp_server. Un score est ainsi rattaché au code qui l'a produit, et plus seulement au git_sha du checkout.

    Reçus : pytest tests_py/benchmarks donne 389 passed, dont 3 nouveaux tests ; ruff et le gate craftsmanship passent. Non lancé : reproduce.sh complet.

    Tranches restantes :

    1. Comparer le digest installé aux checksums et attestations de release (release.yml). Cette tranche touche les workflows, un humain doit la faire.
    2. Écrire la même identité dans les reçus de parité.
    3. Tester la combinaison distribuée exacte dans les deux hôtes (il faut un runner avec Claude et Codex).

    Les tranches 1 à 4 sont fusionnées (#887, #904, #916, #919), donc pas de hold.


    Generated by Claude Code

  8. added
    autopilot:holdCI autopilot stood down: a human decision is required
    on Nov 10, 2026
  9. cdeust commented on Nov 10, 2026

    @cdeust
    OwnerAuthor

    CI autopilot : #729 mise en hold. Aucune tranche restante n'est faisable sans décision humaine ni accès.

    Les tranches 1 à 5 sont fusionnées : #887, #904, #916, #919 et #947. Voici l'état des trois tranches listées après #947 :

    1. Comparer le digest installé aux checksums et attestations de release. Il faut éditer release.yml, et le token de l'autopilot n'a pas la permission workflows : un humain doit le faire.
    2. Écrire la même identité dans les reçus de parité. C'est fait : feat(verification): native receipts bind each check to the artifact digest it ran (#730) #948 (cortex-native-receipt/1) lie chaque check au members_digest du doctor, et feat(verification): a native receipt's artifact object is produced from the doctor's identity (#730) #957 produit l'objet artifact du reçu directement depuis l'identité du doctor.
    3. Tester la combinaison distribuée exacte dans les deux hôtes. Il faut un runner où Claude Code et Codex sont installés, et cet environnement n'en a pas.

    À trancher : faire la tranche 1 à la main ou me donner l'accès workflows, et fournir un runner Claude et Codex pour la tranche 3. On peut aussi décider de fermer #729 une fois #957 fusionnée, en suivant le reste dans #730.


    Generated by Claude Code

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

    autopilot:holdCI autopilot stood down: a human decision is requiredenhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions