Report malformed sequence items at assigned paths

This commit is contained in:
2026-10-16 19:41:48 +00:00
parent acddce8e2f
commit 0858af1029
3 changed files with 33 additions and 2 deletions

View File

@@ -1,6 +1,6 @@
# Implementation Plan: Sequence Placement and Composition # Implementation Plan: Sequence Placement and Composition
Status: implementation in progress; stages 1–13 completed. Status: implementation complete; all 14 stages completed.
## Purpose and authority ## Purpose and authority
@@ -796,3 +796,20 @@ No environmental limitation affected validation; checks ran on Linux/amd64.
Completion: the repository is clean, the feature and its evidence agree, and no Completion: the repository is clean, the feature and its evidence agree, and no
known in-scope implementation work remains. No product decisions remain open; known in-scope implementation work remains. No product decisions remain open;
private helper names and equivalent mechanics are ordinary implementation work. private helper names and equivalent mechanics are ordinary implementation work.
Completion evidence: final review covered the complete implementation diff from
baseline `2051177` against the settled behavior and public-contract boundaries.
It found one malformed-record diagnostic using a contribution-local rather than
assigned sequence index. The composer now reports the effective assigned item
path, with a regression for a malformed record in the second contribution at
`/records/1`. Review also confirmed registered identity checks remain limited to
strict composition, precedence still replaces complete sequences, both opt-ins
are explicit, and source ownership, physical locations, contexts, and detached
evidence remain intact. Final checks passed with Go `go1.26.9 linux/amd64`:
- `GOTOOLCHAIN=local GOPROXY=off go test ./internal/engine -run 'ComposeDocuments(ReportsAssignedPathForMalformedRegisteredSequenceContribution|ValidatesRegisteredSequenceSingletons|RejectsRegisteredSequence)' -count=1`
- `GOTOOLCHAIN=local GOPROXY=off go test -race ./...`
- `GOTOOLCHAIN=local GOPROXY=off ./scripts/check.sh`
- `git diff --check 2051177`
No environmental limitation affected validation; checks ran on Linux/amd64.

View File

@@ -239,7 +239,7 @@ func validateRegisteredSequences(inputs []*document.Node, claims []compositionCl
start := lengthsByPath[pathKey] start := lengthsByPath[pathKey]
contribution := validatedSequence{items: node.Sequence} contribution := validatedSequence{items: node.Sequence}
for itemIndex, item := range node.Sequence { for itemIndex, item := range node.Sequence {
itemPath := claim.path.Index(itemIndex) itemPath := claim.path.Index(start + itemIndex)
if item == nil || item.Kind != document.Mapping { if item == nil || item.Kind != document.Mapping {
location := (*Location)(nil) location := (*Location)(nil)
if item != nil { if item != nil {

View File

@@ -339,6 +339,20 @@ func TestComposeDocumentsValidatesRegisteredSequenceSingletons(t *testing.T) {
} }
} }
func TestComposeDocumentsReportsAssignedPathForMalformedRegisteredSequenceContribution(t *testing.T) {
_, diagnostics := composeDocumentsWithPolicy(
sequencePolicy{identityFields: map[string]string{"/records": "id"}},
parseCompositionDocument(t, "source-1", "records: [{id: first}]\n"),
parseCompositionDocument(t, "source-2", "records: [{name: malformed}]\n"),
)
if len(diagnostics) != 1 || diagnostics[0].Code != CodeComposeInvalid || diagnostics[0].Path.String() != "/records/1" {
t.Fatalf("diagnostics = %#v, want invalid item at /records/1", diagnostics)
}
if diagnostics[0].Primary == nil || diagnostics[0].Primary.SourceID != "source-2" {
t.Fatalf("malformed item location = %#v, want source-2", diagnostics[0].Primary)
}
}
func TestComposeDocumentsRejectsRegisteredDuplicateIdentities(t *testing.T) { func TestComposeDocumentsRejectsRegisteredDuplicateIdentities(t *testing.T) {
tests := []struct { tests := []struct {
name string name string