diff --git a/internal/inventory/catalogue.go b/internal/inventory/catalogue.go index 04218f6..342bb0b 100644 --- a/internal/inventory/catalogue.go +++ b/internal/inventory/catalogue.go @@ -78,11 +78,12 @@ func (i *Inventory) RegisterModule(ctx context.Context, m catalogue.Manifest, fr // (novox/hq ADR 0175, to-be 38 WP2.4): a module serving its tools from a container built on the // runtime's image. Refused at registration, by name, for a module that is new to the catalogue // or that was registered in another shape — the mechanism that keeps the old pattern from - // returning by habit. **Not refused for a module already registered in that shape**: the - // catalogue holds some thirty of them the day the runtime arrives, each moves to a bundle in - // its own change (to-be 38 WP4 onward), and a gate that refused every rebuild of every unmoved - // module in the meantime would stop the whole pipeline to make a point the record already makes. - // Before the runtime exists the pattern is accepted as it always was. + // returning by habit. Before the runtime exists the pattern is accepted as it always was. + // + // *Since 2026-10-04 (to-be 38 WP4b's last step):* refused for **every** module. While some + // thirty modules still stood in that shape, one already registered so was rebuilt without + // complaint, so the pipeline kept running while each moved; every module has moved since, and + // the exception would only let one move back. if m.Module != catalogue.RuntimeModule { if why := catalogue.ToolContainerOnTheRuntime(m, from.Against); why != "" { runtime, err := i.hasModule(ctx, catalogue.RuntimeModule) @@ -90,13 +91,7 @@ func (i *Inventory) RegisterModule(ctx context.Context, m catalogue.Manifest, fr return err } if runtime { - already, err := i.registeredInThatShape(ctx, m.Module) - if err != nil { - return err - } - if !already { - return fmt.Errorf("%s is not registered: %s", m.Module, why) - } + return fmt.Errorf("%s is not registered: %s", m.Module, why) } } } @@ -152,26 +147,6 @@ func (i *Inventory) RegisterModule(ctx context.Context, m catalogue.Manifest, fr return nil } -// registeredInThatShape is whether the catalogue already holds this module as a tools container on -// the runtime's image — judged from the manifest it holds and what that module's newest build stood -// on, the same two things the gate judges a new registration by. False for a module the catalogue -// does not hold. -func (i *Inventory) registeredInThatShape(ctx context.Context, name string) (bool, error) { - held, err := i.Catalogue(ctx) - if err != nil { - return false, err - } - stored, has := held[name] - if !has { - return false, nil - } - against, err := i.BuiltAgainst(ctx) - if err != nil { - return false, err - } - return catalogue.ToolContainerOnTheRuntime(stored, against[name]) != "", nil -} - // hasModule is whether the catalogue holds a module of that name. func (i *Inventory) hasModule(ctx context.Context, name string) (bool, error) { var one int diff --git a/internal/inventory/catalogue_test.go b/internal/inventory/catalogue_test.go index dbca7af..39f66cc 100644 --- a/internal/inventory/catalogue_test.go +++ b/internal/inventory/catalogue_test.go @@ -688,9 +688,9 @@ func TestRegisteringWithoutProvenanceKeepsTheSeat(t *testing.T) { // Once the node's tool runtime is in the catalogue, a module serving its tools from a container // built on the runtime's image is refused at registration, naming the record (novox/hq ADR 0175, -// to-be 38 WP2.4) — for a module new to the catalogue or one that had moved away from it; a module -// already standing in that shape is rebuilt as before, so the catalogue's pipeline keeps running -// while each moves (WP3's amendment). Before the runtime, it is accepted as it always was — so a +// to-be 38 WP2.4) — for every module, since every module has moved (WP4b's last step; WP3's +// amendment let one already standing in that shape be rebuilt while each moved). Before the +// runtime, it is accepted as it always was — so a // mesh converts in the order the design says and nothing is refused before there is anything to // move to. func TestAToolContainerIsRefusedOnceTheRuntimeIsRegistered(t *testing.T) { @@ -715,11 +715,11 @@ func TestAToolContainerIsRefusedOnceTheRuntimeIsRegistered(t *testing.T) { t.Fatal(err) } - // **A module already registered in that shape is rebuilt without complaint** (to-be 38 WP2.4 as - // amended by WP3): some thirty of them stand the day the runtime arrives, and each moves in its - // own change. The gate is against the pattern spreading, not against the pipeline running. - if err := inv.RegisterModule(ctx, filter, Source{Repository: "/r", Against: stoodOn}); err != nil { - t.Fatalf("a rebuild of a module that already had the pattern was refused: %v", err) + // **A module already registered in that shape is refused too** (WP4b's last step): every module + // has moved, and a rebuild in the old shape is one moving back. + if err := inv.RegisterModule(ctx, filter, Source{Repository: "/r", Against: stoodOn}); err == nil || + !strings.Contains(err.Error(), "ADR 0175") { + t.Fatalf("a rebuild of a module in the old pattern was registered beside the runtime: %v", err) } // A module new to the catalogue in that shape is refused, naming the record. newcomer := filter