Exemplo
github.com/google/go-cmp v0.6.0: cmp.FilterPath
Amostra verificada para golang github.com/google/go-cmp v0.6.0: cmp.FilterPath. O contrato rodou em go 1.26 · linux debian/x64 · docker e passou.
sha256:bd719df6dcb1055c7007000069885170a4b6989caf09c22fc348018c8dd38849
Esta rede oferece uma coisa: uma amostra que compila. Ela a executou em um sandbox e guardou o recibo assinado. Não classifica nem garante nada — se o mesmo código compila onde você está, ela não mediu.
Quantas chaves de assinatura distintas enviaram um recibo de contrato aprovado. Uma é só o autor; mais de uma significa que outra pessoa também o compilou. Uma chave é gerada por conta própria e não tem identidade registrada por trás, então conta chaves, não pessoas.
MIT-0
Evidência de execução
O ambiente declarado e as execuções assinadas ficam separados, para você ver exatamente o que esta amostra executou e onde.
- Base da evidência
- Contrato assinado aprovado
- Recibos de verificação
- 1
- Chaves de assinatura que o compilaram
- 1
Ambiente declarado
linux 24 · ubuntu · glibc 2.39 x64 go
Ambientes das execuções de verificação
| Ambiente | Contrato | Etapas | Execução |
|---|---|---|---|
| go 1.26 · linux debian/x64 · docker ed25519:c1973797be207ac4 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · golang@1golang:1.26@sha256:e30143be198a… |
2026-09-15 |
Caso
HOW- Objetivo
- verify github.com/google/go-cmp/cmp.FilterPath in pkg:golang/github.com/google/go-cmp@v0.6.0
- Pacotes
- Símbolos
-
- github.com/google/go-cmp/cmp.FilterPath
- Criado
- 2026-09-15T21:02:46Z
Contrato
- cmp.FilterPath scopes string transformers to specific struct fields, preventing ambiguous option panics
- unfiltered cmp.Ignore panics while cmp.FilterPath combined with cmp.Ignore selectively ignores target struct fields
- cmp.FilterPath enables path-based filtering on nested slice element fields
- overlapping cmp.FilterPath predicates targeting the same path panic with ambiguous applicable options
- cmp.FilterPath panics at construction time when passed a nil filter function
- cmp.FilterPath returns nil when passed a nil option
Arquivos
- NOTES.md
- PROMPT.md
- csx.json
- filterpath.go
- go.mod
- go.sum
- spec.json
- test/contract.go
Código-fonte
# google/go-cmp: Path Filtering and Option Scoping with cmp.FilterPath
## Known Solutions Search
A search for `github.com/google/go-cmp/cmp.FilterPath` in `pkg:golang/github.com/google/go-cmp@v0.6.0` returned `NO_SAFE_MATCH`. This sample establishes a clean-room verified contract for `cmp.FilterPath` in `pkg:golang/github.com/google/go-cmp@v0.6.0`.
## Pinned Release
`github.com/google/go-cmp v0.6.0` declared in `go.mod` and locked in `go.sum`.
## Failure Modes
1. Passing multiple transformers or comparers matching the same type across different struct fields causes runtime panics during tree comparison: `panic: ambiguous set of applicable options at {type}`.
2. Passing an unfiltered `cmp.Ignore()` directly to `cmp.Diff` or `cmp.Equal` triggers a runtime panic: `panic: cannot handle unfiltered Ignore`.
3. Overlapping `FilterPath` predicates that both match the same node path trigger an ambiguity panic at comparison time.
4. Calling `cmp.FilterPath(nil, opt)` panics at option construction time with `panic: invalid path filter function`.
## Observed Behaviour
1. `cmp.FilterPath(f, opt)` scopes an option `opt` so it only evaluates when predicate `f(p cmp.Path)` returns true for the current traversal position.
2. Inspecting `p.Last()` allows checking node properties such as `cmp.StructField` name and type, restricting transformation rules to specific struct attributes.
3. Combining `cmp.FilterPath` with `cmp.Ignore()` enables selective ignoring of specific struct fields (e.g. tokens, metadata) without requiring `cmpopts.IgnoreFields`.
4. Passing a `nil` option to `cmp.FilterPath` returns `nil`.
Clean-room public code sample — generation instructions
Write a brand-new, minimal, self-contained code sample in this clean-room directory.
Do not copy, paraphrase, or reference any existing project source. Work only from this spec.
A csx.json manifest scaffold already exists. Do not recreate it from memory. Preserve its case.goal, packages and symbols; fill its empty case.contract with exact assertions and correct its environment, commands and verifierAdapter for the files you generate.
Goal: verify github.com/google/go-cmp/cmp.FilterPath in pkg:golang/github.com/google/go-cmp@v0.6.0
Kind: HOW
Use EXACTLY these public packages and versions:
- pkg:golang/github.com/google/go-cmp@v0.6.0
Demonstrate these symbols/APIs:
- github.com/google/go-cmp/cmp.FilterPath
Rules:
- One focused purpose; the smallest project that proves the goal.
- Include a contract test (test/contract.*) that runs OFFLINE and exits 0 exactly when the goal behavior works.
- Pin every dependency with a lockfile so resolution is reproducible.
- No secrets, credentials, or tokens. No real URLs (only example.com or localhost). No absolute paths.
- No personal names, emails, company names, or project identifiers of any kind.
- No binaries and no generated output (node_modules, dist, target, venv, .git, .env).
- Keep it under 200 files and 256KB packed.
{"case":{"caseId":"case:sha256:b9805c7fee7143a341b88bad3b7e425ebdc11471d78c55fe39b91dae30f89ba4","contract":["cmp.FilterPath scopes string transformers to specific struct fields, preventing ambiguous option panics","unfiltered cmp.Ignore panics while cmp.FilterPath combined with cmp.Ignore selectively ignores target struct fields","cmp.FilterPath enables path-based filtering on nested slice element fields","overlapping cmp.FilterPath predicates targeting the same path panic with ambiguous applicable options","cmp.FilterPath panics at construction time when passed a nil filter function","cmp.FilterPath returns nil when passed a nil option"],"goal":"verify github.com/google/go-cmp/cmp.FilterPath in pkg:golang/github.com/google/go-cmp@v0.6.0","kind":"HOW","packages":["pkg:golang/github.com/google/go-cmp@v0.6.0"],"schemaVersion":1,"symbols":["github.com/google/go-cmp/cmp.FilterPath"]},"contractCommand":["go","run","./test"],"environment":{"arch":"x64","distro":"ubuntu","ecosystem":"golang","libc":"glibc","libcVersion":"2.39","os":"linux","osVersionBucket":"24","packageManager":"go","schemaVersion":1},"license":"MIT-0","packages":["pkg:golang/github.com/google/go-cmp@v0.6.0"],"schemaVersion":1,"subject":"pkg:golang/github.com/google/go-cmp@v0.6.0","symbols":["github.com/google/go-cmp/cmp.FilterPath"],"verifierAdapter":"golang@1"}
package filterpathcmp
import (
"fmt"
"strings"
"github.com/google/go-cmp/cmp"
)
// UserAccount represents a user account record with multiple string fields.
type UserAccount struct {
ID string
Username string
Email string
AuthToken string
}
// OrderItem represents an item in an order with details.
type OrderItem struct {
SKU string
Quantity int
Notes string
}
// Order represents an order containing header information and items.
type Order struct {
OrderID string
Items []OrderItem
}
// CompareWithoutFilterAmbiguous attempts to compare UserAccount using two unfiltered string transformers.
// This panics at comparison time because go-cmp cannot decide which transformer applies to string fields.
func CompareWithoutFilterAmbiguous(a, b UserAccount) (diff string, panicMsg string) {
defer func() {
if r := recover(); r != nil {
panicMsg = fmt.Sprint(r)
}
}()
optUser := cmp.Transformer("NormalizeUser", strings.ToLower)
optEmail := cmp.Transformer("NormalizeEmail", strings.TrimSpace)
diff = cmp.Diff(a, b, optUser, optEmail)
return diff, panicMsg
}
// ScopedUserAccountOption returns cmp.Options that disambiguate string transformers
// by binding them to specific struct fields using cmp.FilterPath.
func ScopedUserAccountOption() cmp.Option {
optUsername := cmp.FilterPath(func(p cmp.Path) bool {
if sf, ok := p.Last().(cmp.StructField); ok {
return sf.Name() == "Username"
}
return false
}, cmp.Transformer("LowerUsername", strings.ToLower))
optEmail := cmp.FilterPath(func(p cmp.Path) bool {
if sf, ok := p.Last().(cmp.StructField); ok {
return sf.Name() == "Email"
}
return false
}, cmp.Transformer("TrimEmail", strings.TrimSpace))
return cmp.Options{optUsername, optEmail}
}
// CompareUserAccountsScoped compares two UserAccount records with scoped transformers.
func CompareUserAccountsScoped(a, b UserAccount) (diff string, equal bool) {
opts := ScopedUserAccountOption()
diff = cmp.Diff(a, b, opts)
equal = cmp.Equal(a, b, opts)
return diff, equal
}
// TryUnfilteredIgnore attempts to use unfiltered cmp.Ignore(), which panics at comparison time.
func TryUnfilteredIgnore(a, b UserAccount) (panicMsg string) {
defer func() {
if r := recover(); r != nil {
panicMsg = fmt.Sprint(r)
}
}()
_ = cmp.Equal(a, b, cmp.Ignore())
return ""
}
// IgnoreAuthTokenOption uses cmp.FilterPath and cmp.Ignore() to ignore the AuthToken field.
func IgnoreAuthTokenOption() cmp.Option {
return cmp.FilterPath(func(p cmp.Path) bool {
if sf, ok := p.Last().(cmp.StructField); ok {
return sf.Name() == "AuthToken"
}
return false
}, cmp.Ignore())
}
// CompareIgnoringAuthToken compares UserAccount records while ignoring differences in AuthToken.
func CompareIgnoringAuthToken(a, b UserAccount) (diff string, equal bool) {
opt := IgnoreAuthTokenOption()
diff = cmp.Diff(a, b, opt)
equal = cmp.Equal(a, b, opt)
return diff, equal
}
// IgnoreOrderItemNotesOption uses cmp.FilterPath to ignore Notes on OrderItem structs within Order.Items.
func IgnoreOrderItemNotesOption() cmp.Option {
return cmp.FilterPath(func(p cmp.Path) bool {
if sf, ok := p.Last().(cmp.StructField); ok && sf.Name() == "Notes" {
return true
}
return false
}, cmp.Ignore())
}
// CompareOrdersIgnoringNotes compares Orders while ignoring Notes inside nested OrderItems.
func CompareOrdersIgnoringNotes(a, b Order) (diff string, equal bool) {
opt := IgnoreOrderItemNotesOption()
diff = cmp.Diff(a, b, opt)
equal = cmp.Equal(a, b, opt)
return diff, equal
}
// CompareOverlappingFilterPath demonstrates that if two FilterPath options match the exact same
// node path with conflicting transformers, an ambiguity panic is triggered.
func CompareOverlappingFilterPath(a, b UserAccount) (panicMsg string) {
defer func() {
if r := recover(); r != nil {
panicMsg = fmt.Sprint(r)
}
}()
f1 := cmp.FilterPath(func(p cmp.Path) bool {
if sf, ok := p.Last().(cmp.StructField); ok {
return sf.Name() == "Username"
}
return false
}, cmp.Transformer("T1", strings.ToLower))
f2 := cmp.FilterPath(func(p cmp.Path) bool {
return strings.HasSuffix(p.String(), "Username")
}, cmp.Transformer("T2", strings.TrimSpace))
_ = cmp.Diff(a, b, f1, f2)
return ""
}
// TryNilFilterPathFunc verifies that passing a nil filter function to cmp.FilterPath panics.
func TryNilFilterPathFunc() (panicMsg string) {
defer func() {
if r := recover(); r != nil {
panicMsg = fmt.Sprint(r)
}
}()
_ = cmp.FilterPath(nil, cmp.Ignore())
return ""
}
// TryNilFilterPathOption verifies that passing a nil Option to cmp.FilterPath returns nil.
func TryNilFilterPathOption() cmp.Option {
return cmp.FilterPath(func(p cmp.Path) bool { return true }, nil)
}
module example.com/filterpathcmp
go 1.22
require github.com/google/go-cmp v0.6.0
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
{
"schemaVersion": 1,
"goal": "verify github.com/google/go-cmp/cmp.FilterPath in pkg:golang/github.com/google/go-cmp@v0.6.0",
"kind": "HOW",
"packages": [
"pkg:golang/github.com/google/go-cmp@v0.6.0"
],
"symbols": [
"github.com/google/go-cmp/cmp.FilterPath"
]
}
package main
import (
"fmt"
"os"
"strings"
sample "example.com/filterpathcmp"
"github.com/google/go-cmp/cmp"
)
func main() {
// Assertion 1: cmp.FilterPath scopes string transformers to specific struct fields, preventing ambiguous option panics
userA := sample.UserAccount{
ID: "USR-001",
Username: "ALICE_DEV",
Email: " alice@example.com ",
AuthToken: "token-secret-alpha",
}
userB := sample.UserAccount{
ID: "USR-001",
Username: "alice_dev",
Email: "alice@example.com",
AuthToken: "token-secret-alpha",
}
_, ambigPanic := sample.CompareWithoutFilterAmbiguous(userA, userB)
if ambigPanic == "" {
fmt.Fprintf(os.Stderr, "FAIL: expected unfiltered multiple transformers to panic on ambiguity\n")
os.Exit(1)
}
if !strings.Contains(ambigPanic, "ambiguous set of applicable options") {
fmt.Fprintf(os.Stderr, "FAIL: expected ambiguity panic message, got: %s\n", ambigPanic)
os.Exit(1)
}
diffScoped, equalScoped := sample.CompareUserAccountsScoped(userA, userB)
if !equalScoped {
fmt.Fprintf(os.Stderr, "FAIL: expected user accounts to be equal with scoped FilterPath transformers, diff: %s\n", diffScoped)
os.Exit(1)
}
if diffScoped != "" {
fmt.Fprintf(os.Stderr, "FAIL: expected empty diff for scoped matching accounts, got: %s\n", diffScoped)
os.Exit(1)
}
if !cmp.Equal(userA, userB, sample.ScopedUserAccountOption()) {
fmt.Fprintf(os.Stderr, "FAIL: direct cmp.Equal with ScopedUserAccountOption failed\n")
os.Exit(1)
}
userDiffID := userB
userDiffID.ID = "USR-002"
diffID, equalID := sample.CompareUserAccountsScoped(userA, userDiffID)
if equalID || diffID == "" {
fmt.Fprintf(os.Stderr, "FAIL: expected user accounts with different IDs to not be equal\n")
os.Exit(1)
}
// Assertion 2: unfiltered cmp.Ignore panics while cmp.FilterPath combined with cmp.Ignore selectively ignores target struct fields
unfilteredPanic := sample.TryUnfilteredIgnore(userA, userB)
if unfilteredPanic == "" {
fmt.Fprintf(os.Stderr, "FAIL: expected unfiltered cmp.Ignore to panic\n")
os.Exit(1)
}
if !strings.Contains(unfilteredPanic, "cannot handle unfiltered Ignore") && !strings.Contains(unfilteredPanic, "unfiltered") {
fmt.Fprintf(os.Stderr, "FAIL: expected unfiltered Ignore panic message, got: %s\n", unfilteredPanic)
os.Exit(1)
}
userDiffToken := userA
userDiffToken.AuthToken = "token-secret-beta"
diffToken, equalToken := sample.CompareIgnoringAuthToken(userA, userDiffToken)
if !equalToken || diffToken != "" {
fmt.Fprintf(os.Stderr, "FAIL: expected CompareIgnoringAuthToken to equate accounts differing only in AuthToken\n")
os.Exit(1)
}
if !cmp.Equal(userA, userDiffToken, sample.IgnoreAuthTokenOption()) {
fmt.Fprintf(os.Stderr, "FAIL: direct cmp.Equal with IgnoreAuthTokenOption failed\n")
os.Exit(1)
}
userDiffEmail := userDiffToken
userDiffEmail.Email = "different@example.com"
_, equalEmail := sample.CompareIgnoringAuthToken(userA, userDiffEmail)
if equalEmail {
fmt.Fprintf(os.Stderr, "FAIL: expected CompareIgnoringAuthToken to detect difference in Email\n")
os.Exit(1)
}
// Assertion 3: cmp.FilterPath enables path-based filtering on nested slice element fields
orderA := sample.Order{
OrderID: "ORD-999",
Items: []sample.OrderItem{
{SKU: "ITEM-A", Quantity: 2, Notes: "Urgent shipping requested"},
{SKU: "ITEM-B", Quantity: 5, Notes: "Gift wrap required"},
},
}
orderB := sample.Order{
OrderID: "ORD-999",
Items: []sample.OrderItem{
{SKU: "ITEM-A", Quantity: 2, Notes: "Standard ground"},
{SKU: "ITEM-B", Quantity: 5, Notes: "No wrap"},
},
}
diffOrder, equalOrder := sample.CompareOrdersIgnoringNotes(orderA, orderB)
if !equalOrder || diffOrder != "" {
fmt.Fprintf(os.Stderr, "FAIL: expected CompareOrdersIgnoringNotes to equate orders differing only in item Notes, diff: %s\n", diffOrder)
os.Exit(1)
}
if !cmp.Equal(orderA, orderB, sample.IgnoreOrderItemNotesOption()) {
fmt.Fprintf(os.Stderr, "FAIL: direct cmp.Equal with IgnoreOrderItemNotesOption failed\n")
os.Exit(1)
}
orderDiffSKU := orderB
orderDiffSKU.Items[0].SKU = "ITEM-Z"
diffSKU, equalSKU := sample.CompareOrdersIgnoringNotes(orderA, orderDiffSKU)
if equalSKU || !strings.Contains(diffSKU, "SKU") {
fmt.Fprintf(os.Stderr, "FAIL: expected CompareOrdersIgnoringNotes to detect SKU difference, diff: %s\n", diffSKU)
os.Exit(1)
}
// Assertion 4: overlapping cmp.FilterPath predicates targeting the same path panic with ambiguous applicable options
overlapPanic := sample.CompareOverlappingFilterPath(userA, userB)
if overlapPanic == "" {
fmt.Fprintf(os.Stderr, "FAIL: expected overlapping FilterPath predicates to panic\n")
os.Exit(1)
}
if !strings.Contains(overlapPanic, "ambiguous set of applicable options") {
fmt.Fprintf(os.Stderr, "FAIL: expected overlapping filter ambiguity panic, got: %s\n", overlapPanic)
os.Exit(1)
}
// Assertion 5: cmp.FilterPath panics at construction time when passed a nil filter function
nilFilterPanic := sample.TryNilFilterPathFunc()
if nilFilterPanic == "" {
fmt.Fprintf(os.Stderr, "FAIL: expected nil filter func to panic at construction time\n")
os.Exit(1)
}
if !strings.Contains(nilFilterPanic, "invalid path filter function") {
fmt.Fprintf(os.Stderr, "FAIL: expected 'invalid path filter function' panic, got: %s\n", nilFilterPanic)
os.Exit(1)
}
// Assertion 6: cmp.FilterPath returns nil when passed a nil option
optNil := sample.TryNilFilterPathOption()
if optNil != nil {
fmt.Fprintf(os.Stderr, "FAIL: expected TryNilFilterPathOption to return nil, got: %v\n", optNil)
os.Exit(1)
}
fmt.Println("PASS: all cmp.FilterPath contract assertions verified successfully")
}
Seeder de origem
anônimo