Self-upgrade installer: SDK-by-version, mesh-controller rename, foundation adopted #26
@@ -72,6 +72,12 @@ func buildFrom(result link.BuildResult) inventory.Build {
|
||||
kept := inventory.Build{
|
||||
ID: result.ID, Repository: result.Repository, Ref: result.Ref,
|
||||
Commit: result.Commit, On: result.On, Failed: result.Failed,
|
||||
// **What the announcement carries, kept rather than discarded** (novox/hq 04-ISSUES/050).
|
||||
// The catalogue turns the manifest into requires/provides edges and `against` into build
|
||||
// edges, and it is not always listening when a build happens — on a fresh mesh it cannot
|
||||
// be, for exactly the modules it needs most. Keeping them is what makes a replay able to
|
||||
// rebuild the graph rather than a list of names.
|
||||
Path: result.Path, Manifest: result.Manifest, Against: result.Against,
|
||||
}
|
||||
for _, made := range result.Made {
|
||||
kept.Made = append(kept.Made, inventory.Artifact{
|
||||
|
||||
@@ -23,6 +23,18 @@ type Build struct {
|
||||
Commit string
|
||||
// On is the machine that did it.
|
||||
On string
|
||||
// Path is where inside the repository the module lives (novox/hq ADR 0069).
|
||||
Path string
|
||||
// Manifest is the declaration the builder resolved, as it announced it.
|
||||
//
|
||||
// **Kept because the catalogue may not have been listening.** The announcement carries this
|
||||
// and the catalogue turns it into the module's requires/provides edges. On a fresh mesh the
|
||||
// modules built before the catalogue exists are exactly the ones it most needs, so the mesh
|
||||
// has to be able to say afterwards what they declared (novox/hq 04-ISSUES/050).
|
||||
Manifest []byte
|
||||
// Against is every artifact this build stood on, as references rather than module names —
|
||||
// what makes a build edge derived rather than declared (ADR 0009).
|
||||
Against []string
|
||||
// Failed is the builder's own words, empty when it worked.
|
||||
Failed string
|
||||
Made []Artifact
|
||||
@@ -49,15 +61,21 @@ func (i *Inventory) RecordBuild(ctx context.Context, b Build) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
against, err := json.Marshal(b.Against)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var module *string
|
||||
if b.Module != "" {
|
||||
module = &b.Module
|
||||
}
|
||||
_, err = i.store.Pool().Exec(ctx,
|
||||
`insert into build (id, repository, ref, module, commit_hash, built_on, failed, made)
|
||||
values ($1, $2, $3, $4, $5, $6, $7, $8)
|
||||
`insert into build (id, repository, ref, module, commit_hash, built_on, failed, made,
|
||||
source_path, manifest, built_against)
|
||||
values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
||||
on conflict (id) do nothing`,
|
||||
b.ID, b.Repository, b.Ref, module, b.Commit, b.On, b.Failed, made)
|
||||
b.ID, b.Repository, b.Ref, module, b.Commit, b.On, b.Failed, made,
|
||||
b.Path, manifestOrNil(b.Manifest), against)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -144,3 +162,15 @@ func (i *Inventory) Held(ctx context.Context) (map[string]string, error) {
|
||||
}
|
||||
return held, rows.Err()
|
||||
}
|
||||
|
||||
// manifestOrNil keeps the difference between "declared nothing" and "predates this being kept".
|
||||
//
|
||||
// A build recorded before the mesh kept manifests has no manifest, and that is not the same as one
|
||||
// whose manifest was empty. A replay can then say which it is holding instead of inventing an
|
||||
// empty declaration for a module that certainly had one.
|
||||
func manifestOrNil(raw []byte) any {
|
||||
if len(raw) == 0 {
|
||||
return nil
|
||||
}
|
||||
return raw
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
-- What a build result carried and the mesh threw away.
|
||||
--
|
||||
-- novox/hq 04-ISSUES/050. The builder announces a build with the resolved manifest, the path
|
||||
-- inside the repository, and every artifact it was built against. The control plane receives all
|
||||
-- of it and kept none of it: `build` held the repository, the ref, the commit and what was made.
|
||||
--
|
||||
-- That was survivable while the catalogue heard the same announcement directly. It stops being
|
||||
-- survivable the moment the catalogue was not there to hear it — which on a fresh mesh is always,
|
||||
-- and always for the same modules. The shared base, the store the catalogue itself runs on, and
|
||||
-- the catalogue: each is necessarily built BEFORE the catalogue exists to hear about it, so the
|
||||
-- graph's foundation is the part the graph never sees.
|
||||
--
|
||||
-- Replaying those builds needs what they said, not a summary of it. Without the manifest there
|
||||
-- are no requires/provides edges; without `against` there are no build edges, which are the ones
|
||||
-- that answer "a base moved, what must be rebuilt". A replay carrying neither would restore the
|
||||
-- module list and leave the question the catalogue exists for still wrong, while looking fixed.
|
||||
--
|
||||
-- Empty and null-free, so every build recorded before this keeps exactly the meaning it had: a
|
||||
-- row with no manifest is one that predates this, and a replay says so rather than inventing an
|
||||
-- empty declaration.
|
||||
--
|
||||
-- `built_against` rather than `built_on`: that column already exists and means the MACHINE that
|
||||
-- did the build, which is a different fact about a different subject.
|
||||
alter table build add column source_path text not null default '';
|
||||
alter table build add column manifest jsonb;
|
||||
alter table build add column built_against jsonb;
|
||||
Reference in New Issue
Block a user