diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index e43e61f..f0a91d2 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -150,6 +150,11 @@ Validation: format and run `go test ./examples/go-library/observe`, followed by `go test ./examples/go-library/...`. Existing deterministic collaborators remain the network boundary; no live provider or credential is needed. +Completion: observation workflow encoding now goes through a writer-based +helper shared by the executable and its Go test. The test checks all retained +summary fields, including false and zero presence; the observation and complete +example package tests passed on Go 1.27.0. + ## Stage 4: Remove The Custom Release Hook And Adapt Its Diagnostic Scope: `scripts/check-examples.py`, `releasekit.json`, and diff --git a/examples/go-library/observe/main.go b/examples/go-library/observe/main.go index e6af5f2..af18f24 100644 --- a/examples/go-library/observe/main.go +++ b/examples/go-library/observe/main.go @@ -158,13 +158,16 @@ func run() (summary, error) { } func main() { - value, err := run() - if err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } - if err := json.NewEncoder(os.Stdout).Encode(value); err != nil { + if err := execute(os.Stdout); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } } + +func execute(out io.Writer) error { + value, err := run() + if err != nil { + return err + } + return json.NewEncoder(out).Encode(value) +} diff --git a/examples/go-library/observe/main_test.go b/examples/go-library/observe/main_test.go new file mode 100644 index 0000000..c3a3ed9 --- /dev/null +++ b/examples/go-library/observe/main_test.go @@ -0,0 +1,30 @@ +package main + +import ( + "bytes" + "encoding/json" + "testing" +) + +func TestObserveExample(t *testing.T) { + var output bytes.Buffer + if err := execute(&output); err != nil { + t.Fatal(err) + } + var got struct { + ProposalAttempts *int `json:"proposal_attempts"` + ProposalRetries *int `json:"proposal_transient_retries"` + UsageComplete *bool `json:"proposal_usage_complete"` + AssessmentAttempts *int `json:"assessment_attempts"` + AssessmentRetries *int `json:"assessment_transient_retries"` + Outcome string `json:"assessment_outcome"` + } + if err := json.Unmarshal(output.Bytes(), &got); err != nil { + t.Fatal(err) + } + if got.ProposalAttempts == nil || *got.ProposalAttempts != 2 || got.ProposalRetries == nil || *got.ProposalRetries != 1 || + got.UsageComplete == nil || *got.UsageComplete || got.AssessmentAttempts == nil || *got.AssessmentAttempts != 1 || + got.AssessmentRetries == nil || *got.AssessmentRetries != 0 || got.Outcome != "accepted" { + t.Fatalf("unexpected observation summary: %+v", got) + } +}