Repository navigation
ci(accounts): the declared host-interface versions are held to the pinned conformance suite - #1292
Merged
antoinetoussaint-byte merged 2 commits intoNov 3, 2026
Conversation
…nned conformance suite module.codefly.yaml declares what accounts implements and go.mod pins the codefly-dev/authority revision whose shared suite accounts' tests run; nothing held the two together. `module-package verify-host-interfaces` now reads interfaces/<name>/interface.codefly.yaml at the pinned commit (fetched by its full id in the conformance job, which already clones authority) and refuses a declared version above the published one, an interface the pin does not publish, authority libraries pinned at two revisions, or a HOST_INTERFACE.md naming another version. A declared version below the published one is a notice, so the pin can move before the declaration and never the reverse. Running the harness at the pin surfaced an undeclared `instance` key on the hop_admission_key_published audit payload, which the durable emitter drops with a warning; it is declared and held by the admission unit test. session is declared at 0.2.1, the version whose suite accounts passes; delivery and resources move to the revision the other authority libraries pin (empty diff). Tally at authority dea37afac9ad: 94 cases, 294 subtests, 0 failed, 0 skipped. Closes #1291. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ite is red, and a replaced authority library is refused Review findings on #1292: a declared version below the published one was a notice whatever its minor, yet a 0.4.0 declaration under a pin publishing 0.5.0 ran no 0.4.0 suite; only a patch below within the same major.minor is now a notice, every other mismatch fails. ReadAuthorityPin read the require lines alone, so a replace or exclude of an authority library (the shape authority's own services use to point at local directories) left the pin naming nothing that runs; both are refused, read with the strict modfile.Parse, since ParseLax drops those directives. The conformance script resolves the pinned commit in the clone it already has and falls back to the module cache's origin record, and the fetch by full id, only for a pin main does not contain. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1291.
What main already had, verified before changing anything
The issue was written against a tree older than main. Two of its three premises had landed before it was filed:
host-interface-conformance(.github/workflows/ci.yml, job name "Host interface conformance (authority main)") is a required context and arelease-gatesdependency since feat(accounts): the host interfaces are decided by the shared authority core #1257 (27 Oct). It runsscripts/ci/host-interface-conformance-main.sh, which boots the Postgres test store through the Codefly SDK and runsgo test -run '^TestAccountsPassesTheHostInterfaceConformanceSuite$' ./pkg/adapters, with nocontinue-on-error. The last two runs on main (c54a1c8, 2c2aa81) are green.RegisterAdmissionKey,Keys.admission_keyswith purposehop-admission, the per-instance pin and the two-minute lease, over Postgres rows (hop_admission_keys, migrations 55 and 58), and the harness fixture already carriesHopCredential(host_interface_conformance_test.go:362). HOST_INTERFACE.md already states the pin is durable in Postgres and shared across replicas, which is the point the issue asked to be stated.go.modpinnedconformance,authority-coreandauthority-clientatdea37afac9ad, which iscodefly-dev/authoritymain today (0 commits between).deliveryandresourcessat two days behind atf82a98e093ef, with an empty diff between the two revisions for those directories.What was missing is the second done-means item: nothing held "declares
codefly.dev/authority@0.3.5" to "passes the suite of a revision that publishes 0.3.5". This PR adds that gate, and fixes what running the harness surfaced.The declaration gate
module-package verify-host-interfaces(module/tools/modulepackage/host_interfaces.go, unit tests beside it) reads, per service that declaresimplements:inmodule/module.codefly.yaml:go.modpins, from the pseudo-versions of every directgithub.com/codefly-dev/authority/libraries/*/gorequirement: they must be pseudo-versions and must all abbreviate one commit, because the suite, the core it decides with and the client are run together;interfaces/<name>/interface.codefly.yamlat that commit, from a directory the caller provides;HOST_INTERFACE.md.It fails on: a declared version above the published one (a claim no suite proved); a declared version in another major.minor than the published one (a 0.4.0 declaration under a pin publishing 0.5.0 ran no 0.4.0 suite); an interface the pin does not publish; libraries pinned at two revisions, or replaced or excluded in
go.mod(the shape authority's own services use to point at local directories, which would make the require line name nothing that runs); a version that is not semver; a document naming another version than the manifest, or none. A declared patch below the published one, within the same major.minor, is a notice, never a failure: the pin may move to run a newer patch's suite before the declaration follows, and the declaration never moves first. Gate output over the real tree atdea37afac9ad:Where it runs. In
host-interface-conformance, before the suite and before any re-pin: the script already clones authority main (blobless, bare). It resolves the pin's full commit id in that clone (git rev-parse --verify --quiet <pin>^{commit}); only a pin main does not contain falls back to the module cache's origin record (go mod download -json … | Origin.Hash, no network once cached) and is fetched by that id (git fetch --filter=blob:none origin <sha>, which GitHub serves for any reachable commit), and the job is red only when both fail. It then extractsinterfaces/withgit archiveand runs the gate with--revision <sha>so the tree it read is held to thego.modpin. The network-free half (one revision ingo.mod, the document agreeing with the manifest) also runs as amodule/toolstest in the module-package job.Why not offline through Go. The brief preferred an offline check. The authority repo root is nominally a Go module whose zip would carry
interfaces/, but proxy.golang.org does not serve it:@v/<pseudo>.info,@latestand older pseudo-versions all answer 404,@v/listis empty, and sum.golang.org has no entry, so adirectfetch fails "verifying go.mod" too (the nestedlibraries/*/gomodules are served). Pinning by tag is not available either: authority carries two tags, neither on the conformance library or the interfaces. Reading the manifests from git at the pinned commit, inside the one job that already has authority network access, is therefore the real check rather than a copy of it. An offline alternative that belongs to authority is noted under follow-ons.Other changes
module/module.codefly.yaml:codefly.dev/session@0.2.0→0.2.1. accounts already fillsFixturePerson.organization_display_name(the 0.2.1 addition, authority Preserve consumer module agent declarations (#44) #45) and passes the session cases of the 0.2.1 suite at the pin; without the bump the new gate reports an under-declaration on day one. 0.2.1 is additive and consumers require ranges (>=0.2.0 <0.3.0), so no consumer is refused.go.mod:deliveryandresourcesmove fromf82a98e093eftodea37afac9ad, the revision the other three already pin. The diff between the two revisions under those directories is empty; the move makes the pin one commit, which the gate now requires and the CI script's re-pin already assumed.pkg/business/audit_registry.go: the first harness run loggedaudit payload failed registry validation event_type=saas.platform.hop_admission_key_published … no registered field "instance". The durable emitter writes the row and silently drops the whole payload in that case. The field is now declared (required: a credential naming no pod is refused before anything is published), andTestTheHopsRegisteredKeyIsPublishedApartFromTheWorkContextKeysrunsbusiness.ValidatePayloadover the recorded entry so the declaration cannot drift again. The second harness run logs no validation warning.HOST_INTERFACE.md: the opening sentence namedinstallation@0.3.0andsession@0.2.0while the manifest declared 0.4.0 and (now) 0.2.1, and omitted artifact; it now names the five declared versions and is held to the manifest by the gate. Proof gains the gate and the recorded tally below.RELEASE_GATES.md,AGENTS.md, the job comment inci.yml: the gate is documented where the job is; the job'ssetup-gocache now also keys onmodule/tools/go.sum.module/tools/go.mod:golang.org/x/modbecomes a direct dependency (it was already in the graph); core'sresources.LoadModuleFromDirreads the declarations, so the gate parsesimplementsexactly as the CLI does.Conformance tally
Authority
dea37afac9ad(its main on 2026-10-30), frommodule/services/accounts/code:instance)The admission-key case ("only the hop registers an admission key, published apart from the Work Context keys") is among the passes. No new red line, so the gap list (HOST_INTERFACE.md "Not yet") gains nothing.
Classification
Every change is a fix at the owner: the gate lives in
module/toolsbeside the package contract and runs in the job that owns authority access; the audit field is declared in the event catalog that owns payload schemas; the declaration bump and the pin move are manifest facts backed by the suite. No hack, no stopgap, nocontinue-on-error, no loosened case.Reused: the existing job, script and blobless clone; core's module loader;
Masterminds/semverandgolang.org/x/modalready inmodule/tools' graph; thecmd/module-packagesubcommand shape. Deliberately not built: a second clone, a GitHub API call, a download of the authority root module, a hand-written reader ofmodule.codefly.yaml.Verified, and not
scripts/ci/host-interface-conformance-main.shend to end (clone, fetch by id, gate, suite) (exit 0: main identical to the pin, the gate green for the five interfaces, the suite green in 74 s, and no working-tree churn from the re-pin);go test ./...inmodule/tools;node --test scripts/ci/release-gates.test.mjs scripts/ci/ci-performance.test.mjs(125 pass); the admission-key unit tests;node module/tools/naming-gate.mjs check.module-verify.mjsand the Codefly quality phase, which CI runs.Follow-ons, not filed
interfaces/*/interface.codefly.yaml, held by a test in authority). The host-side gate would then be a compile-time comparison with no git access at all. That is authority's change; this PR's gate reads the same fact from the same commit in the meantime, and is not a stopgap for it.🤖 Generated with Claude Code