Skip to content

11.4: step 4 does not reach schema-derived code, and step 3 does not name the tree it lives in #94

Description

@euskadi31

Section 11.4 step 4 says "régénère le code émis", and step 3 lists what a
synchronization writes: spec/, rules.lock, spec/PROVENANCE.md and the
prose contracts. Neither reaches a second kind of generated code that at least
two engines carry: the code a schema compiler emits from rules.proto,
conformance.proto and testee.proto.

That code is not emitted by the engine's own generator. It is emitted by
protoc plus a language plugin, from a copy of the schemas laid out in the
package-shaped tree protoc requires. 2026.08.38 moved the Protobuf package
from libbusinessid.* to entid.*, so both the tree and the emitted symbols
had to move — and section 11.4 gives a synchronization no reason to touch
either.

Measured on entid-org/entid-swift, release v2026.08.38

Ran the engine's own synchronization on v2026.08.38, then reproduced the tree
it produces before any hand step, in a worktree: the new spec/, the new
proto/entid/**, the new rules.lock, the emitted rule code regenerated by
step 4 — and the committed *.pb.swift still the ones generated from
libbusinessid.ir.v1, under their old file names.

./Tools/verify-lock.sh   -> 11 checks ok, exit 0
swift test               -> 261 tests in 32 suites passed
make conformance         -> rules 2026.08.38: 676 cases, 676 matched, 0 differed

The section 12.6 entry point is green on a tree whose wire code was generated
from a schema the release replaced. It is green for a sound reason: a package
rename does not change the wire format, and nothing outside the emitted file
names the package. Regenerating turned out to be byte-for-byte the old file with
the names substituted — which is exactly why nothing failed.

The only job that notices is a separate Protobuf job that runs protoc and
compares. That job does not run on a synchronization pull request: it is opened
with the repository's own GITHUB_TOKEN, which starts no pull_request
workflow — the same cut section 11.4 already documents for the required check.
So the drift merges on green.

Why the engine cannot simply do it

Section 11.4's own argument applies twice over. Regeneration needs the engine's
toolchain, which is why the release does not push; a schema compiler is a
third toolchain, which the synchronization runner does not have either. This
engine's runner has SwiftPM but no protoc and no protoc-gen-swift, and
installing them on every nightly run to notice a change that happens once a year
is not obviously the right trade.

What is missing from the text

  1. Step 3 does not name the engine-side schema tree. An engine that keeps a
    copy of the schemas for its compiler has to move it when the package moves,
    and nothing says so. This engine had a literal path in its digest check; on
    this release it compared the new schema against a copy that was no longer the
    one its compiler reads, and refused the release at the end of a
    synchronization that had passed every digest and every attestation. The fix
    here was to derive the path from the package the attested schema declares,
    but that reading is invented, not specified.

  2. Step 4 does not say how far "le code émis" reaches. If it includes
    schema-derived code, section 11.4 needs to say what an engine does when its
    synchronization runner cannot produce it — go red, or install the compiler.
    If it does not, the specification should say that this code is outside the
    automated path and name what is supposed to catch it, because a pull request
    opened by GITHUB_TOKEN cannot rely on a second workflow.

A suggestion for 1: state that the schemas an engine vendors are located by the
package they declare, so a package rename relocates them by construction. It
costs one sentence and it removes the literal path from four engines.

A suggestion for 2: make step 4 name schema-derived code explicitly, and require
the synchronization to fail rather than to skip it — a red pull request on the
release that renames a package is precisely the sorting section 11.4 describes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    next-releaseHandled together at the next legitimate release

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions