W4.15: a commit the forge does not have is the seat git's kind not-found, never a 404 in the error's words (milestone 47/G)

askGit wraps the kind not-found as index.ErrNotFound; order.go's notFound reads only that. Needs feat/47-G-seats'
seat git at 3b355a35 at the join.

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ

Builds: design 47 G §310, §317
This commit is contained in:
2026-11-11 14:36:10 +01:00
parent 91791fdabd
commit 86d13a41a3
5 changed files with 23 additions and 8 deletions
@@ -31,7 +31,7 @@ func gitVerb(verb string) string { return "seat:" + git.Seat + "." + verb }
type toolCaller func(key string, body any) (json.RawMessage, error)
// askGit asks one verb of the seat git and decodes its answer into out; an answer whose error is set is the failure it
// names, with its kind.
// names, with its kind; the kind not-found is index.ErrNotFound, so a caller never reads it from the words.
func askGit(call toolCaller, verb string, in, out any) error {
raw, err := call(gitVerb(verb), in)
if err != nil {
@@ -44,6 +44,9 @@ func askGit(call toolCaller, verb string, in, out any) error {
if err := json.Unmarshal(raw, &failed); err != nil {
return fmt.Errorf("the answer of %s is not its seat's answer: %w", gitVerb(verb), err)
}
if failed.Error != "" && failed.ErrorKind == git.ErrorKindNotFound {
return fmt.Errorf("%s (%s): %s: %w", gitVerb(verb), failed.ErrorKind, failed.Error, index.ErrNotFound)
}
if failed.Error != "" {
return fmt.Errorf("%s (%s): %s", gitVerb(verb), failed.ErrorKind, failed.Error)
}
@@ -27,6 +27,16 @@ func TestNamedViaAsksTheTreesToolWithThePathsAndTakesTheirObjects(t *testing.T)
if asked.Repository != "novox/mesh-sdk" || asked.Commit != "s" || asked.Paths == nil {
t.Errorf("asked %v, want the repository, commit and paths", asked)
}
// The seat's kind not-found is index.ErrNotFound whatever its words; a failed answer whose words carry a 404 is not.
for answer, gone := range map[string]bool{
`{"error":"the forge holds no commit bbbb","error-kind":"not-found"}`: true,
`{"error":"Gitea API /compare/aaa: 404 Not Found","error-kind":"failed"}`: false,
} {
contains := func(string, any) (json.RawMessage, error) { return json.RawMessage(answer), nil }
if _, err := containsVia(contains)(context.Background(), "novox/a", "aaaa", "bbbb"); err == nil || errors.Is(err, index.ErrNotFound) != gone {
t.Errorf("contains answering %s: %v, want not-found %v", answer, err, gone)
}
}
// An answer that carries the seat's error is the failure it names, never an empty answer.
failed := func(string, any) (json.RawMessage, error) {
return json.RawMessage(`{"error":"the forge did not answer","error-kind":"failed"}`), nil
@@ -291,7 +291,7 @@ func TestAnUnchangedModuleWritesNothing(t *testing.T) { // 1239 (unchanged value
said: "is not known to be older",
then: func(ix *Indexer) error {
ix.Contains = func(context.Context, string, string, string) (bool, error) {
return false, errors.New("gitea_contains: the forge answered: 404 Not Found")
return false, fmt.Errorf("seat:git.contains (not-found): the forge holds no commit bbbb: %w", ErrNotFound) // the kind, no status in its words
}
later := mergedMsg(repo, map[string]string{"modules/a": "treeA2", "modules/b": "treeB", "modules/c": "treeC"})
later.Merge = next
@@ -53,11 +53,13 @@ func newMergeWrite(f forgemsg.Forge) *mergeWrite {
return &mergeWrite{repository: f.Repository, merge: f.Merge}
}
// notFound says the forge answered that a commit it was asked about does not exist: the seat git's contains answers it as
// an error of kind failed whose words carry the forge's status ": 404 " (cmd/mesh-delivery-indexer named.go). A bare "404"
// is not enough: the error's words carry both shas, and a 502 naming a sha with 404 in it would read as not older and
// write a late message backwards. The thorough form, a typed not-found in the seat's error kinds, is noted on issue 1126.
func notFound(err error) bool { return err != nil && strings.Contains(err.Error(), ": 404 ") }
// ErrNotFound is the forge saying that what it was asked about (here a commit) does not exist: the seat git's error kind
// not-found, which the indexer's call of the seat wraps (cmd/mesh-delivery-indexer named.go). Only the kind says it,
// never the error's words: a 502 whose words carry "404" inside a sha is a failure.
var ErrNotFound = errors.New("the forge does not have it")
// notFound says the forge answered that a commit it was asked about does not exist.
func notFound(err error) bool { return errors.Is(err, ErrNotFound) }
// older says commit is older than later: the forge says commit is in later and the two differ. A commit the forge does not
// have is not known to be older (false, said); a forge that cannot say otherwise is an error. Without a forge to ask
@@ -131,7 +131,7 @@ func TestARegisteredModuleIsIndexedFromItsRepository(t *testing.T) { // the gran
{name: "a source head of a diverged history is read again", moved: true,
contains: func(context.Context, string, string, string) (bool, error) { return false, nil }},
{name: "a record whose commit the forge no longer has is read again", moved: true, contains: func(context.Context, string, string, string) (bool, error) {
return false, errors.New("gitea_contains: 404 Not Found")
return false, fmt.Errorf("seat:git.contains (not-found): the forge holds no commit: %w", ErrNotFound) // the kind, no status in its words
}},
{name: "a forge that cannot say the order reads nothing", contains: func(context.Context, string, string, string) (bool, error) {
return false, errors.New("timeout")