mesh-knowledge: the review is shown every link kind propose accepts and a research effort's status apart from its state (hq issue 492)
mesh/merge-gate pass: builds mesh-knowledge → novox; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
mesh/delivery delivered
mesh/merge-gate pass: builds mesh-knowledge → novox; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
mesh/delivery delivered
The first live review sent research 046 back for a touches link the rules never named and a status proposed that is the record's state, not the effort's. The rules now list LinkKinds, the one list propose holds a link to, each with its meaning.
This commit is contained in:
@@ -96,7 +96,9 @@ as text. `get` serves each, and any other field a record of hq wrote under `fiel
|
||||
3. Revise it by proposing again; every version is kept.
|
||||
4. The knowledge base reviews every version proposed itself. It asks the agent module's judge
|
||||
(`claude-code.claude_code_judge` on this node) one question, in a separate call with no tools, that holds only
|
||||
the record, the records it links and the rules, and answers `approve` or `changes` with findings. The background
|
||||
the record, the records it links and the rules, and answers `approve` or `changes` with findings. The rules it sees
|
||||
name every kind of link `propose` accepts, from the one list `propose` holds a link to, and the record it sees
|
||||
shows its state in the knowledge base apart from a research effort's own status (hq issue 492). The background
|
||||
work asks it at once, before the next step of any drafting, one judgement at a time.
|
||||
- On `changes` the record stays proposed, the findings kept with the version they judged (`get` shows them).
|
||||
Its author revises it by proposing it again, and that version is reviewed again.
|
||||
|
||||
@@ -73,6 +73,18 @@ const (
|
||||
// LinkKinds are the kinds a link may be.
|
||||
var LinkKinds = []string{LinkSupersedes, LinkChanges, LinkExtends, LinkBecame, LinkCites, LinkRestsOn, LinkTouches}
|
||||
|
||||
// LinkMeanings says what each kind of link means, as the knowledge base's own review is told (hq issue 492): the
|
||||
// rules it sees list LinkKinds, which propose holds a link to, so the two cannot drift.
|
||||
var LinkMeanings = map[string]string{
|
||||
LinkSupersedes: "a record it replaces whole",
|
||||
LinkChanges: "a clause of another decision it replaces part of, named as 0276 §4",
|
||||
LinkExtends: "a record of its kind it builds on",
|
||||
LinkBecame: "from a research effort, the decision record or design it became",
|
||||
LinkCites: "any record, issue or design it names",
|
||||
LinkRestsOn: "from a decision, a decision it stands on, which may not be superseded under it",
|
||||
LinkTouches: "from a research effort, a record, issue or design its effort bears on",
|
||||
}
|
||||
|
||||
// What a link may point at besides a record of this knowledge base: an issue in the tracker, a design in hq.
|
||||
const (
|
||||
TargetIssue = "issue"
|
||||
|
||||
@@ -87,6 +87,10 @@ func ReviewQuestion(r *Record, linked []*Record) string {
|
||||
for _, rule := range PerRecordRules {
|
||||
fmt.Fprintf(&b, "- %s\n", rule.Holds)
|
||||
}
|
||||
b.WriteString("\nThe kinds of link a record may have, each going out from the record or one of its clauses:\n")
|
||||
for _, kind := range LinkKinds {
|
||||
fmt.Fprintf(&b, "- `%s`: %s\n", kind, LinkMeanings[kind])
|
||||
}
|
||||
b.WriteString("\nThe record:\n\n")
|
||||
b.WriteString(Render(reviewed(r)))
|
||||
if len(linked) > 0 {
|
||||
@@ -112,9 +116,16 @@ func ReviewQuestion(r *Record, linked []*Record) string {
|
||||
}
|
||||
|
||||
// reviewed is the record as its judgement sees it: what it says, without where its review stands.
|
||||
// Its state in the knowledge base (proposed, while it is reviewed) and a research effort's own status (active,
|
||||
// graduated or abandoned, which it takes once accepted) are shown apart, each named for what it is (hq issue 492).
|
||||
func reviewed(r *Record) *Record {
|
||||
c := r.Clone()
|
||||
c.Reviews, c.Ask, c.Judging, c.Drafting, c.Writers, c.Author = nil, nil, nil, nil, nil, ""
|
||||
c.Extra = addExtra(c.Extra, "state in the knowledge base", c.Status+" (every record under review is; it is not the record's own status)")
|
||||
if c.Kind == KindResearch && c.Effort != "" {
|
||||
c.Extra = addExtra(c.Extra, "research status", c.Effort)
|
||||
}
|
||||
c.Status, c.Effort = "", ""
|
||||
return c
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// hq issue 492: the first live review (research 046) sent a valid proposal back because the rules it was shown
|
||||
// named no link kind propose accepts beyond its words, and the record it was shown carried the record's state
|
||||
// `proposed` where a research effort's status belongs.
|
||||
|
||||
// Every link kind propose accepts is named in the rules the judgement sees: one list, so the two cannot drift.
|
||||
func TestTheReviewIsShownEveryLinkKindProposeAccepts(t *testing.T) {
|
||||
q := ReviewQuestion(&Record{Kind: KindDecision, Number: 300, Title: "x", Status: StatusProposed}, nil)
|
||||
for _, kind := range LinkKinds {
|
||||
if !strings.Contains(q, "- `"+kind+"`: ") {
|
||||
t.Errorf("the review is not shown the link kind %s", kind)
|
||||
}
|
||||
}
|
||||
for _, kind := range LinkKinds {
|
||||
if strings.TrimSpace(LinkMeanings[kind]) == "" {
|
||||
t.Errorf("the link kind %s says nothing of what it means", kind)
|
||||
}
|
||||
}
|
||||
if len(LinkMeanings) != len(LinkKinds) {
|
||||
t.Errorf("%d meanings for %d link kinds", len(LinkMeanings), len(LinkKinds))
|
||||
}
|
||||
}
|
||||
|
||||
// A research effort's own status is shown apart from its state in the knowledge base.
|
||||
func TestTheReviewIsShownAResearchEffortsStatusApartFromItsState(t *testing.T) {
|
||||
w := imported(t, newMemStore())
|
||||
r, err := w.k.ReserveNumber("author@g14", KindResearch, "a vendor-neutral inference layer")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := w.k.Propose("author@g14", ProposeAsk{Kind: KindResearch, Number: r.Number, Title: "A vendor-neutral inference layer",
|
||||
Date: "2026-10-11", Deciders: []string{"jochen"}, Status: StatusActive,
|
||||
Sections: []Section{{Name: "00-overview.md", Text: "What an inference layer the mesh controls would be."}},
|
||||
Links: []LinkAsk{{Kind: LinkTouches, To: "0290"}, {Kind: LinkTouches, To: "issue 365"}}}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
w.reviewAll(t)
|
||||
if len(w.judge.reviews) != 1 {
|
||||
t.Fatalf("%d reviews", len(w.judge.reviews))
|
||||
}
|
||||
q := w.judge.reviews[0]
|
||||
record := q[strings.Index(q, "The record:"):]
|
||||
if !strings.Contains(record, "research status: active") || !strings.Contains(record, "state in the knowledge base: proposed") {
|
||||
t.Fatalf("the record as the review sees it:\n%.600s", record)
|
||||
}
|
||||
for _, never := range []string{"\nstatus: proposed", "\neffort: "} {
|
||||
if strings.Contains(record, never) {
|
||||
t.Errorf("the review is shown %q", strings.TrimSpace(never))
|
||||
}
|
||||
}
|
||||
if !strings.Contains(q, "- `touches`: ") {
|
||||
t.Error("the review is not told what touches is")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user