diff --git a/contracts/go/seats/meshpipelinerunner/contract.go b/contracts/go/seats/meshpipelinerunner/contract.go index 7c17dd91..cdb26625 100644 --- a/contracts/go/seats/meshpipelinerunner/contract.go +++ b/contracts/go/seats/meshpipelinerunner/contract.go @@ -423,7 +423,7 @@ type Pipeline struct { EndCount int64 `json:"end-count,omitempty"` Ended *time.Time `json:"ended,omitempty"` // the module's build-input fingerprint at the commit - Fp string `json:"fp,omitempty"` + Fingerprint string `json:"fingerprint,omitempty"` // the gathered group, when the pipeline is its Group string `json:"group,omitempty"` Module string `json:"module"` @@ -445,6 +445,8 @@ type Pipeline struct { Tests *TestCounts `json:"tests,omitempty"` // the layout version V int64 `json:"v,omitempty"` + // the version package-published names, for a pipeline the runner started from a publication or from outdated; none for any other (design 47 G 550) + Version string `json:"version,omitempty"` // for a pipeline that did not pass, the steps that held it Why string `json:"why,omitempty"` Widens []Widening `json:"widens,omitempty"` @@ -470,7 +472,7 @@ type PipelineEnded struct { EndCount int64 `json:"end-count,omitempty"` Ended *time.Time `json:"ended,omitempty"` // the module's build-input fingerprint at the commit - Fp string `json:"fp,omitempty"` + Fingerprint string `json:"fingerprint,omitempty"` // the gathered group, when the pipeline is its Group string `json:"group,omitempty"` Module string `json:"module"` @@ -535,7 +537,7 @@ type PipelineStarted struct { // the commit the module's entry was last changed at Commit string `json:"commit"` // the module's build-input fingerprint at the commit - Fp string `json:"fp,omitempty"` + Fingerprint string `json:"fingerprint,omitempty"` // the gathered group, when the pipeline is its Group string `json:"group,omitempty"` Module string `json:"module"` @@ -570,7 +572,7 @@ type StepEvent struct { // the commit the module's entry was last changed at Commit string `json:"commit"` // the module's build-input fingerprint at the commit - Fp string `json:"fp,omitempty"` + Fingerprint string `json:"fingerprint,omitempty"` // the gathered group, when the pipeline is its Group string `json:"group,omitempty"` Module string `json:"module"` @@ -680,7 +682,7 @@ type Wait struct { // the commit the module's entry was last changed at Commit string `json:"commit,omitempty"` // the module's build-input fingerprint at the commit - Fp string `json:"fp,omitempty"` + Fingerprint string `json:"fingerprint,omitempty"` // the gathered group, when the pipeline is its Group string `json:"group,omitempty"` // for its end, how it ended: answered, ran, released, superseded @@ -696,9 +698,10 @@ type Wait struct { Run string `json:"run,omitempty"` Since time.Time `json:"since"` // the source revision of the watched branch; the pipeline is keyed by it (ADR 0666 section 9) - Source int64 `json:"source,omitempty"` - Step string `json:"step"` - V int64 `json:"v"` + Source int64 `json:"source,omitempty"` + // a pipeline step a wait inside a pipeline is in; pipeline is the acting step of design 47 G 203, for a wait of the entries the runner holds for its new version (design 47 G 534) + Step string `json:"step"` + V int64 `json:"v"` // for a wait on a person, who: the operator, a reviewer Who string `json:"who,omitempty"` } @@ -718,6 +721,7 @@ const ( WaitStepComposition = "composition" WaitStepReview = "review" WaitStepApproval = "approval" + WaitStepPipeline = "pipeline" ) // Widening is a part serving a step the change alters, or an acting rule, a grant or a credential it widens, computed by the running runner (ADR 0666 section 23). diff --git a/contracts/go/seats/meshpipelinerunner/contract_test.go b/contracts/go/seats/meshpipelinerunner/contract_test.go index ded5552b..bc6bbde5 100644 --- a/contracts/go/seats/meshpipelinerunner/contract_test.go +++ b/contracts/go/seats/meshpipelinerunner/contract_test.go @@ -17,27 +17,33 @@ func TestFixtures(t *testing.T) { decode func([]byte) (any, error) subjectIs *regexp.Regexp }{ - {name: "a pipeline started with the steps its policy gives", subject: "mesh.seat.mesh-pipeline-runner.event.pipeline-started.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"at\":\"2026-11-10T10:00:00Z\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fp\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"status\":\"required\",\"step\":\"lint\"},{\"status\":\"bypass\",\"step\":\"review\"}],\"v\":1}", wire: "{\"at\":\"2026-11-10T10:00:00Z\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fp\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"status\":\"required\",\"step\":\"lint\"},{\"status\":\"bypass\",\"step\":\"review\"}],\"v\":1}", + {name: "a pipeline started with the steps its policy gives", subject: "mesh.seat.mesh-pipeline-runner.event.pipeline-started.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"at\":\"2026-11-10T10:00:00Z\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"status\":\"required\",\"step\":\"lint\"},{\"status\":\"bypass\",\"step\":\"review\"}],\"v\":1}", wire: "{\"at\":\"2026-11-10T10:00:00Z\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"status\":\"required\",\"step\":\"lint\"},{\"status\":\"bypass\",\"step\":\"review\"}],\"v\":1}", decode: func(b []byte) (any, error) { var v PipelineStartedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-pipeline-runner\\.event\\.pipeline-started\\.[^.*> ]+\\.[^.*> ]+\\.[^.*> ]+$")}, - {name: "a pipeline ended passed, an optional step failed, over budget and widening named", subject: "mesh.seat.mesh-pipeline-runner.event.pipeline-ended.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"ended\":\"2026-11-10T10:20:00Z\",\"fp\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"passed\",\"over-budget\":true,\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"started\":\"2026-11-10T10:00:00Z\",\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},{\"artifact\":\"nats:program\",\"carried-from\":\"main.11.nats\",\"fingerprint\":\"fp-0123\",\"outcome\":\"carried\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"node\":\"g14\",\"outcome\":\"failed\",\"seat\":\"node-build-go\",\"status\":\"optional\",\"step\":\"integration\",\"tests\":{\"integration\":3},\"why\":\"TestTheBusWhole failed\"},{\"outcome\":\"passed\",\"seat\":\"mesh-wants\",\"status\":\"required\",\"step\":\"composition\"},{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},{\"outcome\":\"passed\",\"status\":\"required\",\"step\":\"approval\"}],\"tests\":{\"integration\":3,\"unit\":42},\"v\":1,\"widens\":[{\"name\":\"mesh-build-go:program\",\"said\":\"its test runner\",\"what\":\"serving part\"}]}", wire: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"ended\":\"2026-11-10T10:20:00Z\",\"fp\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"passed\",\"over-budget\":true,\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"started\":\"2026-11-10T10:00:00Z\",\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},{\"artifact\":\"nats:program\",\"carried-from\":\"main.11.nats\",\"fingerprint\":\"fp-0123\",\"outcome\":\"carried\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"node\":\"g14\",\"outcome\":\"failed\",\"seat\":\"node-build-go\",\"status\":\"optional\",\"step\":\"integration\",\"tests\":{\"integration\":3},\"why\":\"TestTheBusWhole failed\"},{\"outcome\":\"passed\",\"seat\":\"mesh-wants\",\"status\":\"required\",\"step\":\"composition\"},{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},{\"outcome\":\"passed\",\"status\":\"required\",\"step\":\"approval\"}],\"tests\":{\"integration\":3,\"unit\":42},\"v\":1,\"widens\":[{\"name\":\"mesh-build-go:program\",\"said\":\"its test runner\",\"what\":\"serving part\"}]}", + {name: "a pipeline ended passed, an optional step failed, over budget and widening named", subject: "mesh.seat.mesh-pipeline-runner.event.pipeline-ended.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"ended\":\"2026-11-10T10:20:00Z\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"passed\",\"over-budget\":true,\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"started\":\"2026-11-10T10:00:00Z\",\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},{\"artifact\":\"nats:program\",\"carried-from\":\"main.11.nats\",\"fingerprint\":\"fp-0123\",\"outcome\":\"carried\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"node\":\"g14\",\"outcome\":\"failed\",\"seat\":\"node-build-go\",\"status\":\"optional\",\"step\":\"integration\",\"tests\":{\"integration\":3},\"why\":\"TestTheBusWhole failed\"},{\"outcome\":\"passed\",\"seat\":\"mesh-wants\",\"status\":\"required\",\"step\":\"composition\"},{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},{\"outcome\":\"passed\",\"status\":\"required\",\"step\":\"approval\"}],\"tests\":{\"integration\":3,\"unit\":42},\"v\":1,\"widens\":[{\"name\":\"mesh-build-go:program\",\"said\":\"its test runner\",\"what\":\"serving part\"}]}", wire: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"ended\":\"2026-11-10T10:20:00Z\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"passed\",\"over-budget\":true,\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"started\":\"2026-11-10T10:00:00Z\",\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},{\"artifact\":\"nats:program\",\"carried-from\":\"main.11.nats\",\"fingerprint\":\"fp-0123\",\"outcome\":\"carried\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"node\":\"g14\",\"outcome\":\"failed\",\"seat\":\"node-build-go\",\"status\":\"optional\",\"step\":\"integration\",\"tests\":{\"integration\":3},\"why\":\"TestTheBusWhole failed\"},{\"outcome\":\"passed\",\"seat\":\"mesh-wants\",\"status\":\"required\",\"step\":\"composition\"},{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},{\"outcome\":\"passed\",\"status\":\"required\",\"step\":\"approval\"}],\"tests\":{\"integration\":3,\"unit\":42},\"v\":1,\"widens\":[{\"name\":\"mesh-build-go:program\",\"said\":\"its test runner\",\"what\":\"serving part\"}]}", decode: func(b []byte) (any, error) { var v PipelineEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-pipeline-runner\\.event\\.pipeline-ended\\.[^.*> ]+\\.[^.*> ]+\\.[^.*> ]+$")}, - {name: "a pipeline ended failed, naming the step that held it, its approval not asked", subject: "mesh.seat.mesh-pipeline-runner.event.pipeline-ended.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"fp\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"failed\",\"over-budget\":true,\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"outcome\":\"failed\",\"status\":\"required\",\"step\":\"unit\"},{\"outcome\":\"not asked\",\"status\":\"required\",\"step\":\"approval\",\"why\":\"unit of nats:program failed\"}],\"v\":1,\"why\":\"unit of nats:program failed\"}", wire: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"fp\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"failed\",\"over-budget\":true,\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"outcome\":\"failed\",\"status\":\"required\",\"step\":\"unit\"},{\"outcome\":\"not asked\",\"status\":\"required\",\"step\":\"approval\",\"why\":\"unit of nats:program failed\"}],\"v\":1,\"why\":\"unit of nats:program failed\"}", + {name: "a pipeline ended failed, naming the step that held it, its approval not asked", subject: "mesh.seat.mesh-pipeline-runner.event.pipeline-ended.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"failed\",\"over-budget\":true,\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"outcome\":\"failed\",\"status\":\"required\",\"step\":\"unit\"},{\"outcome\":\"not asked\",\"status\":\"required\",\"step\":\"approval\",\"why\":\"unit of nats:program failed\"}],\"v\":1,\"why\":\"unit of nats:program failed\"}", wire: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"failed\",\"over-budget\":true,\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"outcome\":\"failed\",\"status\":\"required\",\"step\":\"unit\"},{\"outcome\":\"not asked\",\"status\":\"required\",\"step\":\"approval\",\"why\":\"unit of nats:program failed\"}],\"v\":1,\"why\":\"unit of nats:program failed\"}", decode: func(b []byte) (any, error) { var v PipelineEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-pipeline-runner\\.event\\.pipeline-ended\\.[^.*> ]+\\.[^.*> ]+\\.[^.*> ]+$")}, - {name: "a group's one pipeline ended on a watched branch", subject: "mesh.seat.mesh-pipeline-runner.event.group-ended.main.registry-1966", given: "{\"branch\":\"main\",\"ended\":\"2026-11-10T10:20:00Z\",\"group\":\"registry-1966\",\"outcome\":\"passed\",\"pipelines\":[{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fp\":\"fp-0123\",\"group\":\"registry-1966\",\"module\":\"nats\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"}],\"v\":1}],\"revision\":12,\"source\":3589,\"v\":1}", wire: "{\"branch\":\"main\",\"ended\":\"2026-11-10T10:20:00Z\",\"group\":\"registry-1966\",\"outcome\":\"passed\",\"pipelines\":[{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fp\":\"fp-0123\",\"group\":\"registry-1966\",\"module\":\"nats\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"}],\"v\":1}],\"revision\":12,\"source\":3589,\"v\":1}", + {name: "a group's one pipeline ended on a watched branch", subject: "mesh.seat.mesh-pipeline-runner.event.group-ended.main.registry-1966", given: "{\"branch\":\"main\",\"ended\":\"2026-11-10T10:20:00Z\",\"group\":\"registry-1966\",\"outcome\":\"passed\",\"pipelines\":[{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"group\":\"registry-1966\",\"module\":\"nats\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"}],\"v\":1}],\"revision\":12,\"source\":3589,\"v\":1}", wire: "{\"branch\":\"main\",\"ended\":\"2026-11-10T10:20:00Z\",\"group\":\"registry-1966\",\"outcome\":\"passed\",\"pipelines\":[{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"group\":\"registry-1966\",\"module\":\"nats\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"}],\"v\":1}],\"revision\":12,\"source\":3589,\"v\":1}", decode: func(b []byte) (any, error) { var v GroupEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-pipeline-runner\\.event\\.group-ended\\.[^.*> ]+\\.[^.*> ]+$")}, {name: "a run on request started", subject: "mesh.seat.mesh-pipeline-runner.event.run-started.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"at\":\"2026-11-10T10:00:00Z\",\"by\":\"fix-1965@shanks\",\"members\":[{\"branch\":\"feature/1966-x\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"module\":\"nats\"}],\"run\":\"run-m2kx9a\",\"v\":1}", wire: "{\"at\":\"2026-11-10T10:00:00Z\",\"by\":\"fix-1965@shanks\",\"members\":[{\"branch\":\"feature/1966-x\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"module\":\"nats\"}],\"run\":\"run-m2kx9a\",\"v\":1}", decode: func(b []byte) (any, error) { var v RunStartedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-pipeline-runner\\.event\\.run-started\\.[^.*> ]+\\.[^.*> ]+\\.[^.*> ]+$")}, - {name: "a step started", subject: "mesh.seat.mesh-pipeline-runner.event.step-started.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"at\":\"2026-11-10T10:00:00Z\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fp\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"result\":{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"outcome\":\"running\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},\"revision\":12,\"source\":3589,\"v\":1}", wire: "{\"at\":\"2026-11-10T10:00:00Z\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fp\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"result\":{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"outcome\":\"running\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},\"revision\":12,\"source\":3589,\"v\":1}", + {name: "a step started", subject: "mesh.seat.mesh-pipeline-runner.event.step-started.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"at\":\"2026-11-10T10:00:00Z\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"result\":{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"outcome\":\"running\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},\"revision\":12,\"source\":3589,\"v\":1}", wire: "{\"at\":\"2026-11-10T10:00:00Z\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"result\":{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"outcome\":\"running\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},\"revision\":12,\"source\":3589,\"v\":1}", decode: func(b []byte) (any, error) { var v StepStartedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-pipeline-runner\\.event\\.step-started\\.[^.*> ]+\\.[^.*> ]+\\.[^.*> ]+$")}, - {name: "a rerun step ended passed, with its proved caller", subject: "mesh.seat.mesh-pipeline-runner.event.step-ended.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"at\":\"2026-11-10T10:05:00Z\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fp\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"result\":{\"artifact\":\"nats:program\",\"by\":\"operator@shanks\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"rerun\":true,\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},\"revision\":12,\"source\":3589,\"v\":1}", wire: "{\"at\":\"2026-11-10T10:05:00Z\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fp\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"result\":{\"artifact\":\"nats:program\",\"by\":\"operator@shanks\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"rerun\":true,\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},\"revision\":12,\"source\":3589,\"v\":1}", + {name: "a rerun step ended passed, with its proved caller", subject: "mesh.seat.mesh-pipeline-runner.event.step-ended.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"at\":\"2026-11-10T10:05:00Z\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"result\":{\"artifact\":\"nats:program\",\"by\":\"operator@shanks\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"rerun\":true,\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},\"revision\":12,\"source\":3589,\"v\":1}", wire: "{\"at\":\"2026-11-10T10:05:00Z\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"result\":{\"artifact\":\"nats:program\",\"by\":\"operator@shanks\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"rerun\":true,\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},\"revision\":12,\"source\":3589,\"v\":1}", decode: func(b []byte) (any, error) { var v StepEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-pipeline-runner\\.event\\.step-ended\\.[^.*> ]+\\.[^.*> ]+\\.[^.*> ]+$")}, - {name: "a bypassed step said", subject: "mesh.seat.mesh-pipeline-runner.event.step-ended.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fp\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"result\":{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},\"revision\":12,\"source\":3589,\"v\":1}", wire: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fp\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"result\":{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},\"revision\":12,\"source\":3589,\"v\":1}", + {name: "a bypassed step said", subject: "mesh.seat.mesh-pipeline-runner.event.step-ended.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"result\":{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},\"revision\":12,\"source\":3589,\"v\":1}", wire: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"result\":{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},\"revision\":12,\"source\":3589,\"v\":1}", decode: func(b []byte) (any, error) { var v StepEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-pipeline-runner\\.event\\.step-ended\\.[^.*> ]+\\.[^.*> ]+\\.[^.*> ]+$")}, - {name: "an approval waits on the operator", subject: "mesh.seat.mesh-pipeline-runner.event.wait-held.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fp\":\"fp-0123\",\"module\":\"nats\",\"on\":\"person\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"since\":\"2026-11-10T10:10:00Z\",\"source\":3589,\"step\":\"approval\",\"v\":1,\"who\":\"the operator\"}", wire: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fp\":\"fp-0123\",\"module\":\"nats\",\"on\":\"person\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"since\":\"2026-11-10T10:10:00Z\",\"source\":3589,\"step\":\"approval\",\"v\":1,\"who\":\"the operator\"}", + {name: "an approval waits on the operator", subject: "mesh.seat.mesh-pipeline-runner.event.wait-held.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"on\":\"person\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"since\":\"2026-11-10T10:10:00Z\",\"source\":3589,\"step\":\"approval\",\"v\":1,\"who\":\"the operator\"}", wire: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"on\":\"person\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"since\":\"2026-11-10T10:10:00Z\",\"source\":3589,\"step\":\"approval\",\"v\":1,\"who\":\"the operator\"}", decode: func(b []byte) (any, error) { var v WaitHeldEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-pipeline-runner\\.event\\.wait-held\\.[^.*> ]+\\.[^.*> ]+\\.[^.*> ]+$")}, - {name: "the wait ended answered", subject: "mesh.seat.mesh-pipeline-runner.event.wait-ended.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fp\":\"fp-0123\",\"how\":\"answered\",\"module\":\"nats\",\"on\":\"person\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"since\":\"2026-11-10T10:10:00Z\",\"source\":3589,\"step\":\"approval\",\"v\":1,\"who\":\"the operator\"}", wire: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fp\":\"fp-0123\",\"how\":\"answered\",\"module\":\"nats\",\"on\":\"person\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"since\":\"2026-11-10T10:10:00Z\",\"source\":3589,\"step\":\"approval\",\"v\":1,\"who\":\"the operator\"}", + {name: "the wait ended answered", subject: "mesh.seat.mesh-pipeline-runner.event.wait-ended.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"how\":\"answered\",\"module\":\"nats\",\"on\":\"person\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"since\":\"2026-11-10T10:10:00Z\",\"source\":3589,\"step\":\"approval\",\"v\":1,\"who\":\"the operator\"}", wire: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"how\":\"answered\",\"module\":\"nats\",\"on\":\"person\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"since\":\"2026-11-10T10:10:00Z\",\"source\":3589,\"step\":\"approval\",\"v\":1,\"who\":\"the operator\"}", decode: func(b []byte) (any, error) { var v WaitEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-pipeline-runner\\.event\\.wait-ended\\.[^.*> ]+\\.[^.*> ]+\\.[^.*> ]+$")}, - {name: "a pipeline kept", subject: "", given: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"ended\":\"2026-11-10T10:20:00Z\",\"fp\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"started\":\"2026-11-10T10:00:00Z\",\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},{\"artifact\":\"nats:program\",\"carried-from\":\"main.11.nats\",\"fingerprint\":\"fp-0123\",\"outcome\":\"carried\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"node\":\"g14\",\"outcome\":\"failed\",\"seat\":\"node-build-go\",\"status\":\"optional\",\"step\":\"integration\",\"tests\":{\"integration\":3},\"why\":\"TestTheBusWhole failed\"},{\"outcome\":\"passed\",\"seat\":\"mesh-wants\",\"status\":\"required\",\"step\":\"composition\"},{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},{\"outcome\":\"passed\",\"status\":\"required\",\"step\":\"approval\"}],\"v\":1}", wire: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"ended\":\"2026-11-10T10:20:00Z\",\"fp\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"started\":\"2026-11-10T10:00:00Z\",\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},{\"artifact\":\"nats:program\",\"carried-from\":\"main.11.nats\",\"fingerprint\":\"fp-0123\",\"outcome\":\"carried\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"node\":\"g14\",\"outcome\":\"failed\",\"seat\":\"node-build-go\",\"status\":\"optional\",\"step\":\"integration\",\"tests\":{\"integration\":3},\"why\":\"TestTheBusWhole failed\"},{\"outcome\":\"passed\",\"seat\":\"mesh-wants\",\"status\":\"required\",\"step\":\"composition\"},{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},{\"outcome\":\"passed\",\"status\":\"required\",\"step\":\"approval\"}],\"v\":1}", + {name: "a pipeline kept", subject: "", given: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"ended\":\"2026-11-10T10:20:00Z\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"started\":\"2026-11-10T10:00:00Z\",\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},{\"artifact\":\"nats:program\",\"carried-from\":\"main.11.nats\",\"fingerprint\":\"fp-0123\",\"outcome\":\"carried\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"node\":\"g14\",\"outcome\":\"failed\",\"seat\":\"node-build-go\",\"status\":\"optional\",\"step\":\"integration\",\"tests\":{\"integration\":3},\"why\":\"TestTheBusWhole failed\"},{\"outcome\":\"passed\",\"seat\":\"mesh-wants\",\"status\":\"required\",\"step\":\"composition\"},{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},{\"outcome\":\"passed\",\"status\":\"required\",\"step\":\"approval\"}],\"v\":1}", wire: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"ended\":\"2026-11-10T10:20:00Z\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"started\":\"2026-11-10T10:00:00Z\",\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},{\"artifact\":\"nats:program\",\"carried-from\":\"main.11.nats\",\"fingerprint\":\"fp-0123\",\"outcome\":\"carried\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"node\":\"g14\",\"outcome\":\"failed\",\"seat\":\"node-build-go\",\"status\":\"optional\",\"step\":\"integration\",\"tests\":{\"integration\":3},\"why\":\"TestTheBusWhole failed\"},{\"outcome\":\"passed\",\"seat\":\"mesh-wants\",\"status\":\"required\",\"step\":\"composition\"},{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},{\"outcome\":\"passed\",\"status\":\"required\",\"step\":\"approval\"}],\"v\":1}", + decode: func(b []byte) (any, error) { + var v PipelinesByBranchRevisionModuleValue + err := json.Unmarshal(b, &v) + return v, err + }, subjectIs: nil}, + {name: "a pipeline a publication started, with the version it names (design 47 G 550)", subject: "", given: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"ended\":\"2026-11-10T10:20:00Z\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"started\":\"2026-11-10T10:00:00Z\",\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},{\"artifact\":\"nats:program\",\"carried-from\":\"main.11.nats\",\"fingerprint\":\"fp-0123\",\"outcome\":\"carried\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"node\":\"g14\",\"outcome\":\"failed\",\"seat\":\"node-build-go\",\"status\":\"optional\",\"step\":\"integration\",\"tests\":{\"integration\":3},\"why\":\"TestTheBusWhole failed\"},{\"outcome\":\"passed\",\"seat\":\"mesh-wants\",\"status\":\"required\",\"step\":\"composition\"},{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},{\"outcome\":\"passed\",\"status\":\"required\",\"step\":\"approval\"}],\"v\":1,\"version\":\"0.1.15\"}", wire: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"ended\":\"2026-11-10T10:20:00Z\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"started\":\"2026-11-10T10:00:00Z\",\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},{\"artifact\":\"nats:program\",\"carried-from\":\"main.11.nats\",\"fingerprint\":\"fp-0123\",\"outcome\":\"carried\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"node\":\"g14\",\"outcome\":\"failed\",\"seat\":\"node-build-go\",\"status\":\"optional\",\"step\":\"integration\",\"tests\":{\"integration\":3},\"why\":\"TestTheBusWhole failed\"},{\"outcome\":\"passed\",\"seat\":\"mesh-wants\",\"status\":\"required\",\"step\":\"composition\"},{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},{\"outcome\":\"passed\",\"status\":\"required\",\"step\":\"approval\"}],\"v\":1,\"version\":\"0.1.15\"}", decode: func(b []byte) (any, error) { var v PipelinesByBranchRevisionModuleValue err := json.Unmarshal(b, &v) @@ -53,11 +59,11 @@ func TestFixtures(t *testing.T) { decode: func(b []byte) (any, error) { var v ReviewInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, {name: "review answers its step", subject: "", given: "{\"pipeline\":\"main.12.nats\",\"result\":{\"outcome\":\"passed\",\"status\":\"optional\",\"step\":\"review\"}}", wire: "{\"pipeline\":\"main.12.nats\",\"result\":{\"outcome\":\"passed\",\"status\":\"optional\",\"step\":\"review\"}}", decode: func(b []byte) (any, error) { var v ReviewAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, - {name: "show answers a pipeline with its log and fill", subject: "", given: "{\"fill\":[{\"bytes\":4096,\"cap\":268435456,\"store\":\"pipelines\"}],\"log\":[{\"artifact\":\"nats:program\",\"at\":\"2026-11-10T10:00:00Z\",\"pipeline\":\"main.12.nats\",\"step\":\"lint\",\"what\":\"started\"}],\"outputs\":[\"main.12.nats.lint.nats:program\"],\"pipeline\":{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fp\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"running\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"}],\"v\":1}}", wire: "{\"fill\":[{\"bytes\":4096,\"cap\":268435456,\"store\":\"pipelines\"}],\"log\":[{\"artifact\":\"nats:program\",\"at\":\"2026-11-10T10:00:00Z\",\"pipeline\":\"main.12.nats\",\"step\":\"lint\",\"what\":\"started\"}],\"outputs\":[\"main.12.nats.lint.nats:program\"],\"pipeline\":{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fp\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"running\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"}],\"v\":1}}", + {name: "show answers a pipeline with its log and fill", subject: "", given: "{\"fill\":[{\"bytes\":4096,\"cap\":268435456,\"store\":\"pipelines\"}],\"log\":[{\"artifact\":\"nats:program\",\"at\":\"2026-11-10T10:00:00Z\",\"pipeline\":\"main.12.nats\",\"step\":\"lint\",\"what\":\"started\"}],\"outputs\":[\"main.12.nats.lint.nats:program\"],\"pipeline\":{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"running\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"}],\"v\":1}}", wire: "{\"fill\":[{\"bytes\":4096,\"cap\":268435456,\"store\":\"pipelines\"}],\"log\":[{\"artifact\":\"nats:program\",\"at\":\"2026-11-10T10:00:00Z\",\"pipeline\":\"main.12.nats\",\"step\":\"lint\",\"what\":\"started\"}],\"outputs\":[\"main.12.nats.lint.nats:program\"],\"pipeline\":{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"running\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"}],\"v\":1}}", decode: func(b []byte) (any, error) { var v ShowAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, {name: "accept asks with why", subject: "", given: "{\"artifact\":\"nats:program\",\"pipeline\":\"main.12.nats\",\"step\":\"integration\",\"why\":\"flaky upstream, issue 1966\"}", wire: "{\"artifact\":\"nats:program\",\"pipeline\":\"main.12.nats\",\"step\":\"integration\",\"why\":\"flaky upstream, issue 1966\"}", decode: func(b []byte) (any, error) { var v AcceptInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, - {name: "stands answers a wait on a build node", subject: "", given: "{\"stands\":[{\"artifact\":\"nats:program\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fp\":\"fp-0123\",\"module\":\"nats\",\"on\":\"build node\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"since\":\"2026-11-10T10:00:00Z\",\"source\":3589,\"step\":\"unit\",\"v\":1}]}", wire: "{\"stands\":[{\"artifact\":\"nats:program\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fp\":\"fp-0123\",\"module\":\"nats\",\"on\":\"build node\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"since\":\"2026-11-10T10:00:00Z\",\"source\":3589,\"step\":\"unit\",\"v\":1}]}", + {name: "stands answers a wait on a build node", subject: "", given: "{\"stands\":[{\"artifact\":\"nats:program\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"on\":\"build node\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"since\":\"2026-11-10T10:00:00Z\",\"source\":3589,\"step\":\"unit\",\"v\":1}]}", wire: "{\"stands\":[{\"artifact\":\"nats:program\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"on\":\"build node\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"since\":\"2026-11-10T10:00:00Z\",\"source\":3589,\"step\":\"unit\",\"v\":1}]}", decode: func(b []byte) (any, error) { var v StandsAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, {name: "kept answers by digest", subject: "", given: "{\"fill\":{\"bytes\":300,\"cap\":134217728,\"store\":\"kept\"},\"kept\":[{\"digest\":\"sha256:aa\",\"level\":\"unit\",\"package\":\"git.novox.be/novox/nats\",\"pipeline\":\"main.12.nats\"}]}", wire: "{\"fill\":{\"bytes\":300,\"cap\":134217728,\"store\":\"kept\"},\"kept\":[{\"digest\":\"sha256:aa\",\"level\":\"unit\",\"package\":\"git.novox.be/novox/nats\",\"pipeline\":\"main.12.nats\"}]}", decode: func(b []byte) (any, error) { var v KeptAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, diff --git a/contracts/seats/mesh-pipeline-runner/fixtures/events.json b/contracts/seats/mesh-pipeline-runner/fixtures/events.json index 3eb22465..e630d866 100644 --- a/contracts/seats/mesh-pipeline-runner/fixtures/events.json +++ b/contracts/seats/mesh-pipeline-runner/fixtures/events.json @@ -10,7 +10,6 @@ "revision": 12, "source": 3589, "commit": "0123456789abcdef0123456789abcdef01234567", - "fp": "fp-0123", "v": 1, "steps": [ { @@ -23,7 +22,8 @@ "status": "bypass" } ], - "at": "2026-11-10T10:00:00Z" + "at": "2026-11-10T10:00:00Z", + "fingerprint": "fp-0123" } }, { @@ -38,7 +38,6 @@ "source": 3589, "end-count": 1, "commit": "0123456789abcdef0123456789abcdef01234567", - "fp": "fp-0123", "v": 1, "outcome": "passed", "steps": [ @@ -106,7 +105,8 @@ } ], "started": "2026-11-10T10:00:00Z", - "ended": "2026-11-10T10:20:00Z" + "ended": "2026-11-10T10:20:00Z", + "fingerprint": "fp-0123" } }, { @@ -121,7 +121,6 @@ "source": 3589, "end-count": 1, "commit": "0123456789abcdef0123456789abcdef01234567", - "fp": "fp-0123", "v": 1, "outcome": "failed", "why": "unit of nats:program failed", @@ -140,7 +139,8 @@ "why": "unit of nats:program failed" } ], - "over-budget": true + "over-budget": true, + "fingerprint": "fp-0123" } }, { @@ -162,7 +162,6 @@ "revision": 12, "source": 3589, "commit": "0123456789abcdef0123456789abcdef01234567", - "fp": "fp-0123", "v": 1, "group": "registry-1966", "outcome": "passed", @@ -177,7 +176,8 @@ "node": "ace", "ask": "m2kx9a1b3c4d5e" } - ] + ], + "fingerprint": "fp-0123" } ], "ended": "2026-11-10T10:20:00Z" @@ -212,7 +212,6 @@ "revision": 12, "source": 3589, "commit": "0123456789abcdef0123456789abcdef01234567", - "fp": "fp-0123", "v": 1, "result": { "step": "lint", @@ -222,7 +221,8 @@ "seat": "node-build-go", "ask": "m2kx9a1b3c4d5e" }, - "at": "2026-11-10T10:00:00Z" + "at": "2026-11-10T10:00:00Z", + "fingerprint": "fp-0123" } }, { @@ -236,7 +236,6 @@ "revision": 12, "source": 3589, "commit": "0123456789abcdef0123456789abcdef01234567", - "fp": "fp-0123", "v": 1, "result": { "step": "unit", @@ -252,7 +251,8 @@ "rerun": true, "by": "operator@shanks" }, - "at": "2026-11-10T10:05:00Z" + "at": "2026-11-10T10:05:00Z", + "fingerprint": "fp-0123" } }, { @@ -266,13 +266,13 @@ "revision": 12, "source": 3589, "commit": "0123456789abcdef0123456789abcdef01234567", - "fp": "fp-0123", "v": 1, "result": { "step": "review", "status": "bypass", "outcome": "bypassed" - } + }, + "fingerprint": "fp-0123" } }, { @@ -286,12 +286,12 @@ "revision": 12, "source": 3589, "commit": "0123456789abcdef0123456789abcdef01234567", - "fp": "fp-0123", "v": 1, "step": "approval", "on": "person", "who": "the operator", - "since": "2026-11-10T10:10:00Z" + "since": "2026-11-10T10:10:00Z", + "fingerprint": "fp-0123" } }, { @@ -305,13 +305,13 @@ "revision": 12, "source": 3589, "commit": "0123456789abcdef0123456789abcdef01234567", - "fp": "fp-0123", "v": 1, "step": "approval", "on": "person", "who": "the operator", "since": "2026-11-10T10:10:00Z", - "how": "answered" + "how": "answered", + "fingerprint": "fp-0123" } } ] diff --git a/contracts/seats/mesh-pipeline-runner/fixtures/states.json b/contracts/seats/mesh-pipeline-runner/fixtures/states.json index f5873247..4c3eac27 100644 --- a/contracts/seats/mesh-pipeline-runner/fixtures/states.json +++ b/contracts/seats/mesh-pipeline-runner/fixtures/states.json @@ -10,7 +10,6 @@ "source": 3589, "end-count": 1, "commit": "0123456789abcdef0123456789abcdef01234567", - "fp": "fp-0123", "v": 1, "outcome": "passed", "steps": [ @@ -66,7 +65,79 @@ } ], "started": "2026-11-10T10:00:00Z", - "ended": "2026-11-10T10:20:00Z" + "ended": "2026-11-10T10:20:00Z", + "fingerprint": "fp-0123" + } + }, + { + "name": "a pipeline a publication started, with the version it names (design 47 G 550)", + "of": "state:pipelines/..", + "given": { + "pipeline": "main.12.nats", + "module": "nats", + "branch": "main", + "revision": 12, + "source": 3589, + "end-count": 1, + "commit": "0123456789abcdef0123456789abcdef01234567", + "v": 1, + "outcome": "passed", + "steps": [ + { + "step": "lint", + "artifact": "nats:program", + "status": "required", + "outcome": "passed", + "fingerprint": "fp-0123", + "seat": "node-build-go", + "node": "ace", + "ask": "m2kx9a1b3c4d5e" + }, + { + "step": "unit", + "artifact": "nats:program", + "status": "required", + "outcome": "carried", + "fingerprint": "fp-0123", + "carried-from": "main.11.nats", + "tests": { + "unit": 42 + } + }, + { + "step": "integration", + "artifact": "nats:program", + "status": "optional", + "outcome": "failed", + "why": "TestTheBusWhole failed", + "fingerprint": "fp-0123", + "seat": "node-build-go", + "node": "g14", + "tests": { + "integration": 3 + } + }, + { + "step": "composition", + "status": "required", + "outcome": "passed", + "seat": "mesh-wants" + }, + { + "step": "review", + "status": "bypass", + "outcome": "bypassed" + }, + { + "step": "approval", + "status": "required", + "outcome": "passed" + } + ], + "started": "2026-11-10T10:00:00Z", + "ended": "2026-11-10T10:20:00Z", + "fingerprint": "fp-0123", + "version": "0.1.15" } }, { diff --git a/contracts/seats/mesh-pipeline-runner/fixtures/verbs.json b/contracts/seats/mesh-pipeline-runner/fixtures/verbs.json index ab97a8c2..98e96258 100644 --- a/contracts/seats/mesh-pipeline-runner/fixtures/verbs.json +++ b/contracts/seats/mesh-pipeline-runner/fixtures/verbs.json @@ -56,7 +56,6 @@ "revision": 12, "source": 3589, "commit": "0123456789abcdef0123456789abcdef01234567", - "fp": "fp-0123", "v": 1, "outcome": "running", "steps": [ @@ -70,7 +69,8 @@ "node": "ace", "ask": "m2kx9a1b3c4d5e" } - ] + ], + "fingerprint": "fp-0123" }, "log": [ { @@ -115,12 +115,12 @@ "revision": 12, "source": 3589, "commit": "0123456789abcdef0123456789abcdef01234567", - "fp": "fp-0123", "v": 1, "step": "unit", "artifact": "nats:program", "on": "build node", - "since": "2026-11-10T10:00:00Z" + "since": "2026-11-10T10:00:00Z", + "fingerprint": "fp-0123" } ] } diff --git a/contracts/seats/mesh-pipeline-runner/seat.json b/contracts/seats/mesh-pipeline-runner/seat.json index 29d7b274..d6b36a15 100644 --- a/contracts/seats/mesh-pipeline-runner/seat.json +++ b/contracts/seats/mesh-pipeline-runner/seat.json @@ -991,7 +991,7 @@ "type": "string", "description": "the run on request's id, for a pipeline of a run; such a pipeline delivers nothing" }, - "fp": { + "fingerprint": { "type": "string", "description": "the module's build-input fingerprint at the commit" }, @@ -1044,6 +1044,10 @@ "ended": { "type": "string", "format": "date-time" + }, + "version": { + "type": "string", + "description": "the version package-published names, for a pipeline the runner started from a publication or from outdated; none for any other (design 47 G 550)" } }, "description": "one pipeline as the runner keeps it in its state pipelines, by compare-and-set (design 47 *The runner's kept data*)", @@ -1093,7 +1097,7 @@ "type": "string", "description": "the run on request's id, for a pipeline of a run; such a pipeline delivers nothing" }, - "fp": { + "fingerprint": { "type": "string", "description": "the module's build-input fingerprint at the commit" }, @@ -1187,7 +1191,7 @@ "type": "string", "description": "the run on request's id, for a pipeline of a run; such a pipeline delivers nothing" }, - "fp": { + "fingerprint": { "type": "string", "description": "the module's build-input fingerprint at the commit" }, @@ -1383,7 +1387,7 @@ "type": "string", "description": "the run on request's id, for a pipeline of a run; such a pipeline delivers nothing" }, - "fp": { + "fingerprint": { "type": "string", "description": "the module's build-input fingerprint at the commit" }, @@ -1442,7 +1446,7 @@ "type": "string", "description": "the run on request's id, for a pipeline of a run; such a pipeline delivers nothing" }, - "fp": { + "fingerprint": { "type": "string", "description": "the module's build-input fingerprint at the commit" }, @@ -1457,8 +1461,10 @@ "integration", "composition", "review", - "approval" - ] + "approval", + "pipeline" + ], + "description": "a pipeline step a wait inside a pipeline is in; pipeline is the acting step of design 47 G 203, for a wait of the entries the runner holds for its new version (design 47 G 534)" }, "artifact": { "type": "string" diff --git a/contracts/ts/seats/meshpipelinerunner/index.d.ts b/contracts/ts/seats/meshpipelinerunner/index.d.ts index abcd517c..f270727c 100644 --- a/contracts/ts/seats/meshpipelinerunner/index.d.ts +++ b/contracts/ts/seats/meshpipelinerunner/index.d.ts @@ -186,7 +186,7 @@ export interface Pipeline { "end-count"?: number; "ended"?: string; /** the module's build-input fingerprint at the commit */ - "fp"?: string; + "fingerprint"?: string; /** the gathered group, when the pipeline is its */ "group"?: string; "module": string; @@ -208,6 +208,8 @@ export interface Pipeline { "tests"?: TestCounts; /** the layout version */ "v"?: number; + /** the version package-published names, for a pipeline the runner started from a publication or from outdated; none for any other (design 47 G 550) */ + "version"?: string; /** for a pipeline that did not pass, the steps that held it */ "why"?: string; "widens"?: Widening[]; @@ -223,7 +225,7 @@ export interface PipelineEnded { "end-count"?: number; "ended"?: string; /** the module's build-input fingerprint at the commit */ - "fp"?: string; + "fingerprint"?: string; /** the gathered group, when the pipeline is its */ "group"?: string; "module": string; @@ -260,7 +262,7 @@ export interface PipelineStarted { /** the commit the module's entry was last changed at */ "commit": string; /** the module's build-input fingerprint at the commit */ - "fp"?: string; + "fingerprint"?: string; /** the gathered group, when the pipeline is its */ "group"?: string; "module": string; @@ -295,7 +297,7 @@ export interface StepEvent { /** the commit the module's entry was last changed at */ "commit": string; /** the module's build-input fingerprint at the commit */ - "fp"?: string; + "fingerprint"?: string; /** the gathered group, when the pipeline is its */ "group"?: string; "module": string; @@ -369,7 +371,7 @@ export interface Wait { /** the commit the module's entry was last changed at */ "commit"?: string; /** the module's build-input fingerprint at the commit */ - "fp"?: string; + "fingerprint"?: string; /** the gathered group, when the pipeline is its */ "group"?: string; /** for its end, how it ended: answered, ran, released, superseded */ @@ -386,7 +388,8 @@ export interface Wait { "since": string; /** the source revision of the watched branch; the pipeline is keyed by it (ADR 0666 section 9) */ "source"?: number; - "step": "lint" | "unit" | "integration" | "composition" | "review" | "approval"; + /** a pipeline step a wait inside a pipeline is in; pipeline is the acting step of design 47 G 203, for a wait of the entries the runner holds for its new version (design 47 G 534) */ + "step": "lint" | "unit" | "integration" | "composition" | "review" | "approval" | "pipeline"; "v": number; /** for a wait on a person, who: the operator, a reviewer */ "who"?: string;