feat(go): fixture capture + characterization framework (M3)
All checks were successful
Deploy to K8s / deploy (push) Successful in 7s
All checks were successful
Deploy to K8s / deploy (push) Successful in 7s
Closes M3.1–M3.6. Parity safety net proving Go output matches Python
for every ported pure-domain function (M2.1–M2.9) and reconcile (M2.10).
Capture pipeline:
- scripts/capture_fixtures.py: calls each Python function with seeded
inputs, emits JSON fixtures to stdout (never writes files directly).
- scripts/scrub_fixtures.py: deterministic PII scrubber — SHA-256
pseudonyms for member names, digit-preserving hashes for VS/account/
bank_id, name-sweep in message text. Idempotent; no salt.
- scripts/_fixture_seeds.py: handcrafted seeds for all 11 functions;
synthetic names throughout (no real roster members).
- scripts/capture_all_fixtures.sh: convenience wrapper for full corpus
regeneration outside of make.
Fixture corpus (98 files, all PII-free):
- go/tests/fixtures/pure/<func>/<case>.json — 10 function directories.
- go/tests/fixtures/reconcile/<NN>_<case>.json — 10 branch-coverage
cases: greedy, overpayment credit, proportional remainder, even-split,
out-of-window, exception override, other: purpose, junior ?, multi-
person+month fan-out, unmatched.
Go parity tests (//go:build parity):
- go/tests/parity/parityio.go: generic LoadDir/RunAll helpers + typed
In/Out struct pairs for all 10 pure functions; Envelope decoder for
int/float/none disambiguation.
- 10 pure-function test packages + bespoke reconcile test with per-cell
float tolerance (math.Abs <= 0.01 for `paid` values).
Makefile: go-parity, go-test-all, capture-fixtures targets.
go/tests/fixtures/README.md: refresh workflow + PII audit guide.
Gate: make go-test green, make go-parity green (11/11 packages),
make go-lint clean (parity tag), make go-build clean.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
36
go/tests/fixtures/pure/infer_transaction_details/member_in_message.json
vendored
Normal file
36
go/tests/fixtures/pure/infer_transaction_details/member_in_message.json
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"case": "member_in_message",
|
||||
"func": "scripts.match_payments.infer_transaction_details",
|
||||
"captured_at": "2026-05-06",
|
||||
"input": {
|
||||
"tx": {
|
||||
"sender": "Test Payer",
|
||||
"message": "alzbeta testovicka leden 2026",
|
||||
"user_id": "",
|
||||
"date": {
|
||||
"type": "string",
|
||||
"value": "2026-01-15"
|
||||
}
|
||||
},
|
||||
"member_names": [
|
||||
"Alžběta Testovická",
|
||||
"Tomáš Fiktivný (Tov)",
|
||||
"Pavel Smutný (Štrúdl)",
|
||||
"Jana Nováková",
|
||||
"Adam Novák"
|
||||
],
|
||||
"default_year": 2026
|
||||
},
|
||||
"output": {
|
||||
"matches": [
|
||||
{
|
||||
"name": "Alžběta Testovická",
|
||||
"confidence": "auto"
|
||||
}
|
||||
],
|
||||
"months": [
|
||||
"2026-01"
|
||||
],
|
||||
"search_text": "Test Payer alzbeta testovicka leden 2026 "
|
||||
}
|
||||
}
|
||||
36
go/tests/fixtures/pure/infer_transaction_details/member_in_sender.json
vendored
Normal file
36
go/tests/fixtures/pure/infer_transaction_details/member_in_sender.json
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"case": "member_in_sender",
|
||||
"func": "scripts.match_payments.infer_transaction_details",
|
||||
"captured_at": "2026-05-06",
|
||||
"input": {
|
||||
"tx": {
|
||||
"sender": "Tomáš Fiktivný",
|
||||
"message": "FUJ trenink",
|
||||
"user_id": "",
|
||||
"date": {
|
||||
"type": "string",
|
||||
"value": "2026-02-01"
|
||||
}
|
||||
},
|
||||
"member_names": [
|
||||
"Alžběta Testovická",
|
||||
"Tomáš Fiktivný (Tov)",
|
||||
"Pavel Smutný (Štrúdl)",
|
||||
"Jana Nováková",
|
||||
"Adam Novák"
|
||||
],
|
||||
"default_year": 2026
|
||||
},
|
||||
"output": {
|
||||
"matches": [
|
||||
{
|
||||
"name": "Tomáš Fiktivný (Tov)",
|
||||
"confidence": "auto"
|
||||
}
|
||||
],
|
||||
"months": [
|
||||
"2026-02"
|
||||
],
|
||||
"search_text": "Tomáš Fiktivný FUJ trenink "
|
||||
}
|
||||
}
|
||||
36
go/tests/fixtures/pure/infer_transaction_details/month_fallback_from_date.json
vendored
Normal file
36
go/tests/fixtures/pure/infer_transaction_details/month_fallback_from_date.json
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"case": "month_fallback_from_date",
|
||||
"func": "scripts.match_payments.infer_transaction_details",
|
||||
"captured_at": "2026-05-06",
|
||||
"input": {
|
||||
"tx": {
|
||||
"sender": "Alžběta Testovická",
|
||||
"message": "platba",
|
||||
"user_id": "",
|
||||
"date": {
|
||||
"type": "string",
|
||||
"value": "2026-03-15"
|
||||
}
|
||||
},
|
||||
"member_names": [
|
||||
"Alžběta Testovická",
|
||||
"Tomáš Fiktivný (Tov)",
|
||||
"Pavel Smutný (Štrúdl)",
|
||||
"Jana Nováková",
|
||||
"Adam Novák"
|
||||
],
|
||||
"default_year": 2026
|
||||
},
|
||||
"output": {
|
||||
"matches": [
|
||||
{
|
||||
"name": "Alžběta Testovická",
|
||||
"confidence": "auto"
|
||||
}
|
||||
],
|
||||
"months": [
|
||||
"2026-03"
|
||||
],
|
||||
"search_text": "Alžběta Testovická platba "
|
||||
}
|
||||
}
|
||||
28
go/tests/fixtures/pure/infer_transaction_details/no_member_no_month.json
vendored
Normal file
28
go/tests/fixtures/pure/infer_transaction_details/no_member_no_month.json
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"case": "no_member_no_month",
|
||||
"func": "scripts.match_payments.infer_transaction_details",
|
||||
"captured_at": "2026-05-06",
|
||||
"input": {
|
||||
"tx": {
|
||||
"sender": "Unknown Person",
|
||||
"message": "random text",
|
||||
"user_id": "",
|
||||
"date": {
|
||||
"type": "none"
|
||||
}
|
||||
},
|
||||
"member_names": [
|
||||
"Alžběta Testovická",
|
||||
"Tomáš Fiktivný (Tov)",
|
||||
"Pavel Smutný (Štrúdl)",
|
||||
"Jana Nováková",
|
||||
"Adam Novák"
|
||||
],
|
||||
"default_year": 2026
|
||||
},
|
||||
"output": {
|
||||
"matches": [],
|
||||
"months": [],
|
||||
"search_text": "Unknown Person random text "
|
||||
}
|
||||
}
|
||||
36
go/tests/fixtures/pure/infer_transaction_details/serial_date.json
vendored
Normal file
36
go/tests/fixtures/pure/infer_transaction_details/serial_date.json
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"case": "serial_date",
|
||||
"func": "scripts.match_payments.infer_transaction_details",
|
||||
"captured_at": "2026-05-06",
|
||||
"input": {
|
||||
"tx": {
|
||||
"sender": "Jana Nováková",
|
||||
"message": "leden",
|
||||
"user_id": "",
|
||||
"date": {
|
||||
"type": "float",
|
||||
"value": 46027.0
|
||||
}
|
||||
},
|
||||
"member_names": [
|
||||
"Alžběta Testovická",
|
||||
"Tomáš Fiktivný (Tov)",
|
||||
"Pavel Smutný (Štrúdl)",
|
||||
"Jana Nováková",
|
||||
"Adam Novák"
|
||||
],
|
||||
"default_year": 2026
|
||||
},
|
||||
"output": {
|
||||
"matches": [
|
||||
{
|
||||
"name": "Jana Nováková",
|
||||
"confidence": "auto"
|
||||
}
|
||||
],
|
||||
"months": [
|
||||
"2026-01"
|
||||
],
|
||||
"search_text": "Jana Nováková leden "
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user