B7-2: record-opened carries a forge-made record's repository, pull request, commit and branch

OpenForgeMade is the fill; no path of the gate opens a forge-made record (design 47 G §151 ends the mark from G's delivery),
so the teller says none until one does.

Builds: design 47 G §170, §522, A-161, A-172
Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
2026-11-12 05:46:45 +01:00
parent 9ee1cbe3f5
commit aa10f070f2
2 changed files with 47 additions and 9 deletions
@@ -483,6 +483,25 @@ func (rs *Records) Read(instance string) (*Record, error) {
// opened now. Each open removes the records past their retention first (the retention needs no timer: records open as
// deliveries do).
func (rs *Records) Open(milestone string, heads map[string]string, forgeMade bool) (r *Record, opened bool, err error) {
return rs.open(milestone, heads, forgeMade, ForgeMerge{})
}
// ForgeMerge is the merge a forge-made record is for: what record-opened says of it (design 47 G A-161).
type ForgeMerge struct {
Repository string
Pull int64
Commit string
Branch string
}
// OpenForgeMade opens the record of a merge made at the forge, marked forge-made, and says record-opened with the merge's
// repository, pull request, commit and branch, so the teller makes no call per message (A-161). No path of the gate opens one
// from G's delivery (§151): the teller says none while nothing calls this.
func (rs *Records) OpenForgeMade(milestone string, heads map[string]string, m ForgeMerge) (r *Record, opened bool, err error) {
return rs.open(milestone, heads, true, m)
}
func (rs *Records) open(milestone string, heads map[string]string, forgeMade bool, m ForgeMerge) (r *Record, opened bool, err error) {
inst, err := RecordInstance(milestone, heads)
if err != nil {
return nil, false, err
@@ -516,7 +535,9 @@ func (rs *Records) Open(milestone string, heads map[string]string, forgeMade boo
rs.keep(r)
// Said once, under the record's id: the watchman times it against 24 hours, ended by record-ended. A say that fails is
// said again by the next write of the record (the id keeps it once).
if serr := rs.say(meshdelivery.SubjectRecordOpened, recordOpened{Record: inst, Milestone: milestone, ForgeMade: forgeMade, At: now.UTC()},
at := now.UTC()
if serr := rs.say(meshdelivery.SubjectRecordOpened, meshdelivery.RecordOpenedEvent{Record: inst, Milestone: milestone, ForgeMade: forgeMade, At: &at,
Repository: m.Repository, Pull: m.Pull, Commit: m.Commit, Branch: m.Branch},
"record-opened."+inst); serr != nil && rs.Logf != nil {
rs.Logf("[mesh-delivery] the record %s is opened and its opening is not said: %v", inst, serr)
}
@@ -524,14 +545,6 @@ func (rs *Records) Open(milestone string, heads map[string]string, forgeMade boo
return r, err == nil && r != nil, err
}
// recordOpened is the body of the seat's event record-opened.
type recordOpened struct {
Record string `json:"record"`
Milestone string `json:"milestone"`
ForgeMade bool `json:"forge-made,omitempty"`
At time.Time `json:"at"`
}
// List is every record kept, opened within the retention and a month more, oldest first.
func (rs *Records) List() ([]*Record, error) {
now := rs.now()
@@ -773,6 +773,31 @@ func TestTheRecordsToolsReadThemAndEndOneByHand(t *testing.T) {
})
}
// A-161: record-opened says what its hearers need to tell a forge-made record: the repository, the pull request, the merge
// commit and the branch; an ordinary record says none of them.
func TestRecordOpenedCarriesAForgeMadeRecordsMerge(t *testing.T) {
var said []meshdelivery.RecordOpenedEvent
rs := &Records{Ledger: newLedgerFake(t), Now: func() time.Time { return time.Date(2026, 11, 12, 5, 0, 0, 0, time.UTC) },
Say: func(subject string, body any, id string) error {
if subject == meshdelivery.SubjectRecordOpened {
said = append(said, body.(meshdelivery.RecordOpenedEvent))
}
return nil
}}
commit := strings.Repeat("3", 40)
if _, _, err := rs.OpenForgeMade("main.5", map[string]string{"novox/app@333333333333": commit},
ForgeMerge{Repository: "novox/app", Pull: 12, Commit: commit, Branch: "main"}); err != nil {
t.Fatal(err)
}
if _, _, err := rs.Open("47/G", map[string]string{"novox/app@111111111111": strings.Repeat("1", 40)}, false); err != nil {
t.Fatal(err)
}
if len(said) != 2 || !said[0].ForgeMade || said[0].Repository != "novox/app" || said[0].Pull != 12 || said[0].Commit != commit ||
said[0].Branch != "main" || said[1].ForgeMade || said[1].Repository != "" || said[1].Pull != 0 || said[1].Commit != "" || said[1].Branch != "" {
t.Fatalf("said %+v", said)
}
}
// W11.20 (design 47 *The delivery record*: a store filling is said before it is full): the gate reads its ledger's fill,
// says filling when a record takes it past 80 % of its cap, refuses the next record as full and holds its merge, and
// says room and hands the merge once the ledger is below 80 % again; the read tool says the fill.