Unclaimed Property Platform
Search the build
-
10056f22026-08-13 auto-data-snapshot: 2026-08-13T15:04:38 (1 data files) — db/schema.sql -
50995a72026-08-07 auto-data-snapshot: 2026-08-07T11:47:33 (2 data files) — db/ca_unclaimed.sqlite-shm db/ca_unclaimed.sqlite-wal -
941205e2026-08-07 auto-data-snapshot: 2026-08-07T11:14:36 (1 data files) — db/ca_unclaimed.sqlite-wal -
c41cc842026-08-07 auto-data-snapshot: 2026-08-07T10:41:58 (1 data files) — db/ca_unclaimed.sqlite-wal -
60d22952026-08-07 auto-data-snapshot: 2026-08-07T10:09:04 (2 data files) — db/ca_unclaimed.sqlite-shm db/ca_unclaimed.sqlite-wal -
0b2c4c22026-08-07 auto-data-snapshot: 2026-08-07T09:37:33 (1 data files) — db/ca_unclaimed.sqlite-wal -
91b20cb2026-08-07 auto-data-snapshot: 2026-08-07T09:05:06 (2 data files) — db/ca_unclaimed.sqlite-shm db/ca_unclaimed.sqlite-wal -
f9cc59e2026-08-07 auto-data-snapshot: 2026-08-07T08:32:43 (2 data files) — db/ca_unclaimed.sqlite-shm db/ca_unclaimed.sqlite-wal -
d8cf6c02026-08-07 auto-data-snapshot: 2026-08-07T08:00:20 (2 data files) — db/ca_unclaimed.sqlite-shm db/ca_unclaimed.sqlite-wal -
9f2367a2026-08-07 ca: masked search UI (serve_ca.py :8799) + disk-safe full-CA fetch-load loop -
eeef3192026-08-07 ingest: CA adapter + streaming loader — real California DB built (3.76M records, $11.1B) -
42ad8e02026-08-07 outreach: CA has a free public CSV bulk download — no PRA letter needed (letters become fallback) -
5f6f29b2026-08-07 outreach: 51-state public-records request generator + CA letter ready -
5d968bc2026-08-01 chore: v0.1.0 — compile-clean, 11/11 green (session close) -
3b350782026-08-01 docs: LOOP CLOSED — Cycle 11 wrap + final state + deferred backlog; TK-10097 -
3532e9b2026-08-01 Cycle 11 (DTD verdict C): packaging + consolidation, then wrap -
d4ba8b02026-08-01 docs: ledger Cycle-10 record (reconciliation); TK-10097 -
edfce962026-08-01 Cycle 10: feed-completeness reconciliation (catches silent truncation) -
2a43af42026-08-01 docs: ledger Cycle-9 record (outbox worker); TK-10097 -
e3a39c32026-08-01 Cycle 9: outbox worker — completes the transactional-outbox pattern -
e7a163f2026-08-01 docs: ledger Cycle-8 record (claims persistence); TK-10097 -
c3d81a02026-08-01 Cycle 8: concrete SqliteClaimRepository — claims subsystem runnable on real persistence -
afbc9ad2026-08-01 docs: ledger Cycle-7 record (suppression path); TK-10097 -
3ca22d72026-08-01 Cycle 7: state suppression / reinstatement path (near-real-time takedown) -
02a3ead2026-08-01 docs: ledger Cycle-6 record (recall fix); TK-10097 -
f74dc2b2026-08-01 Cycle 6: apostrophe/hyphen search-recall fix (zero schema change) -
48cadf22026-08-01 docs: ledger Cycle-5 record (NAUPA III + XXE guard); TK-10097 -
ac6d7772026-08-01 Cycle 5: NAUPA III XML adapter (completes CSV/NAUPA II/III trio) + XXE guard -
9a964262026-08-01 docs: ledger Cycle-4 record (search service + real limiter); TK-10097 -
bdd1a4b2026-08-01 Cycle 4: runnable masked-search service + REAL rate limiter (closes Sec 1.3) -
3d2a81a2026-08-01 auto-save: 2026-08-01T11:36:26 (2 files) — services/common/rate_limit.py services/search/service.py -
ef78cf72026-08-01 docs: ledger Cycle-3 verification/reconciliation record; TK-10097 -
789f72c2026-08-01 verify: clean commit passes tripwire -
509f6572026-08-01 chore: mark pre-commit-tripwire.sh executable; TK-10097 (hook verified: blocks SSN, exit 1) -
9fbefae2026-08-01 Cycle 3: NAUPA II adapter + candidate-blocking + guardrail tripwire + doc reconcile -
c0f1c682026-08-01 auto-save: 2026-08-01T11:06:15 (4 files) — services/ingestion/ingest.py services/ingestion/naupa2.py tests/test_cycle3_naupa_and_blocking.py tests/test_cycle4_fairness.py -
a02e4b22026-08-01 Cycle 3 complete: blocking_keys, Sec2.5 encryption marker, roadmap doc, 7/7 tests — 4am-loop -
902afd82026-08-01 Cycle 3: NAUPA II/III parsers, jurisdictions.json, pre-commit tripwire, M1+m4 fixes — 15/15 tests pass -
831558d2026-07-31 auto-save: 2026-07-31T15:29:10 (1 files) — docs/LOOP-LEDGER.md -
527cc262026-07-31 docs(marker): Cycle 2 = adversarial-review fixes (see f576a32); TK-10097 -
f576a322026-07-31 auto-save: 2026-07-31T14:58:42 (8 files) — .gitignore services/claims/claim_workflow.py services/common/normalize.py services/common/sqlite_repo.py services/ingestion/ingest.py -
9819a892026-07-31 Cycle 1: scaffold national unclaimed-property platform (B2G, synthetic-only)
Authors
- Steve31
- auto-commit-fleet9
- Steve (yoloforever loop)2
Agents used
- security-auditor1
- code-reviewer1
Skills used
- /synthetic7
- /ingestion4
- /common4
- /search4
- /claims3
- /hyphen2
- /service2
- /ingest2
- /schema1
- /legal1
- /reinstate1
- /zsh1
- /short1
- /over1
- /unknown1
- /returns1
- /fraud1
- /phonetic1
- /naupa31
- /healthz1
- /reconciliation1
- /masking1
- /pre-commit-tripwire1
- /jurisdictions1
- /budget1
- /naupa21
- /normalize1
- /version1
Creative ideas + design notes
3532e9b · 2026-08-01 · Cycle 11 (DTD verdict C): packaging + consolidation, then wrap
DTD 5/5 verdict C (CONTINUE/WRAP/PIVOT -> PIVOT to packaging then wrap); Cody dissent (real blocker is business/legal) folded in as a real DUA template, not dismissed. - scripts/demo_tour.py: one-command narrated end-to-end tour (ingest 3 formats + reconcile -> masked search -> suppress/reinstate -> claim + outbox retry). VERIFIED runs /bin/zsh. - Makefile: make demo / test / serve / install (one-command front door). - README.md: rewritten — what works + proof table, 60-second demo, guardrails, repo map, and the real critical path up front. - docs/04-data-use-agreement-template.md: the fill-in DUA + GTM sequence — the artifact that actually unblocks a real deployment (honors the dissent). - MERGE: removed the orphan parallel NAUPA duplicate triad (naupa2_fixed/naupa3_xml/ test_cycle3) — consolidated to the single pipeline-wired implementation. History retained. Tests: 11/11 suites green after consolidation. TK-10097
edfce96 · 2026-08-01 · Cycle 10: feed-completeness reconciliation (catches silent truncation)
- FeedDefinition.expected_count (state control total; NAUPA trailer in prod); _reconcile() compares parsed (accepted+rejected) vs expected -> ok|short|over|unknown + delta. - 'short' is the silent-truncation signal (a transfer that cut off looks 'successful' otherwise). Persisted on ingestion_batch (expected_count + reconciliation cols); batch_reconciliation() reads it. - tests/test_cycle11_reconciliation.py: ok/short/over/unknown + persistence. Tests: 11/11 suites green. All local/synthetic/$0. TK-10097
e3a39c3 · 2026-08-01 · Cycle 9: outbox worker — completes the transactional-outbox pattern
- services/claims/outbox_worker.py: drains pending outbox_event -> StateAdapter with AT-LEAST-ONCE semantics + bounded retry. Transient fail -> stays pending (attempts++); exhausted -> 'failed' (claim NOT lost, stays SUBMITTING for ops); already-SUBMITTED -> treated as idempotent success (no retry loop). - schema: outbox_event gains attempts + last_error; SqliteClaimRepository fetch_pending_outbox / mark_outbox / outbox_row. - tests/test_cycle10_outbox_worker.py: transient-then-success, no-op re-drain, permanent-fail exhaustion. Now events are not just WRITTEN (Cycle 8) but reliably DELIVERED. Tests: 10/10 suites green. All local/synthetic/$0. TK-10097
c3d81a0 · 2026-08-01 · Cycle 8: concrete SqliteClaimRepository — claims subsystem runnable on real persistence
- services/claims/sqlite_claim_repo.py implements ClaimRepository against claim_case/ claim_event/outbox_event, sharing the SqliteRepository connection (one system-of-record). - Closes the last 'runs only on a test fake' gap: the claim lifecycle now persists end-to-end and the C3 idempotency fix is proven against the REAL UNIQUE(claim_id, idempotency_key) constraint (duplicate -> sqlite3.IntegrityError), not an in-memory imitation. - tests/test_cycle9_claims_persistence.py: full DRAFT->SUBMITTED_TO_STATE lifecycle, outbox, DB-level idempotency, state-only guard, illegal-transition rejection. Tests: 9/9 suites green. All local/synthetic/$0. TK-10097
3ca22d7 · 2026-08-01 · Cycle 7: state suppression / reinstatement path (near-real-time takedown)
- SqliteRepository.suppress_property/reinstate_property: flip search_document_state.is_suppressed so a record leaves/returns to anonymous search IMMEDIATELY (masked_search already filters it), while property + owner + version history are fully retained. Every action writes an immutable audit_event; audit_trail() reads it back. Unknown record -> False (no silent success). - Closes the brief's near-real-time suppression requirement (privacy/fraud takedown) — the gap where nothing could pull a record from public search. State-authenticated in production. - tests/test_cycle8_suppression.py: suppress->gone, data retained, audit written, reinstate->back. Tests: 8/8 suites green. All local/synthetic/$0. TK-10097
f74dc2b · 2026-08-01 · Cycle 6: apostrophe/hyphen search-recall fix (zero schema change)
- normalize_search(): fully-collapsed alphanumeric key (spaces+punct removed) — CATHERINEONEIL. - masked_search matches REPLACE(owner_name_normalized,' ','') LIKE collapsed-query, so 'Oneil' now finds "O'Neil" and 'Smith-Jones' variants match. Does NOT widen normalize_text (masks/ blocking/phonetic unchanged). Empty-query guard (m2) preserved. - tests/test_cycle7_recall.py proves the fix + no-regression. Tests: 7/7 suites green. All local/synthetic/$0. TK-10097
ac6d777 · 2026-08-01 · Cycle 5: NAUPA III XML adapter (completes CSV/NAUPA II/III trio) + XXE guard
- services/ingestion/naupa3.py: namespace-tolerant XML parser via the lazy adapter registry (format_name naupa3_v1); same CanonicalProperty as CSV/NAUPA II. - SECURITY: rejects any DOCTYPE/ENTITY document (XmlSecurityError) -> closes XXE / billion-laughs entity-expansion at the door before parsing. build_naupa3_xml helper for aligned fixtures (optional default xmlns to exercise namespace tolerance). - tests/test_cycle6_naupa3.py: parity, namespace tolerance, XXE refusal, malformed-record reject, idempotency. - Logged backlog: apostrophe/hyphen search RECALL (normalize_text collapses ' to space, so LIKE-search misses 'Oneil' for O'Neil; matching unaffected via phonetic key). Prod = OpenSearch analyzers. Tests: 6/6 suites green. All local/synthetic/$0. TK-10097
bdd1a4b · 2026-08-01 · Cycle 4: runnable masked-search service + REAL rate limiter (closes Sec 1.3)
- services/common/rate_limit.py: SlidingWindowRateLimiter (injectable clock, per-key budgets, retry_after). Replaces the require_rate_limit_STUB masquerade — anti-enumeration is now real. - services/search/service.py: SearchService composes validate -> rate-limit -> masked_search -> assert_public_safe (fail-closed) so every transport enforces identical privacy controls. - services/search/run_local.py: dependency-free stdlib HTTP endpoint ($0). SMOKE-TESTED over real HTTP: 200 masked JSON, 400 empty-query, 429 after budget, /healthz. Single-threaded (SQLite is thread-bound; prod = Postgres pool). - tests/test_cycle5_search.py: deterministic (injected clock) proof of masked results, real 429 + window refill, empty-query rejection, per-client-key isolation. Tests: 5/5 suites green. All local/synthetic/$0. TK-10097
9fbefae · 2026-08-01 · Cycle 3: NAUPA II adapter + candidate-blocking + guardrail tripwire + doc reconcile
Product: - NAUPA II fixed-width parser via lazy adapter registry (_get_parser); same CanonicalProperty as CSV so dedup/masking/search are format-agnostic. build_naupa2_line keeps fixtures aligned. - tests/test_cycle3_naupa_and_blocking.py: NAUPA parity + idempotency + blocking-key bucketing. Matching: - blocking_keys fairness fix: empty-norm (CJK/Arabic) names now fall through to geo keys so they're never un-indexable; tests/test_cycle4_fairness.py asserts the coverage floor. Claims: - FIX regression from M1 refactor: complete_state_submission namespaced its transition key (:transition) so it no longer collides with queue's SUBMITTING event (C3-variant, caught by the Cycle-2 regression test). Guardrails: - scripts/pre-commit-tripwire.sh: blocks SSN-shaped strings + real-feed formats at commit. Docs: - docs/jurisdictions.json (machine-readable, 50+DC); docs/03 roadmap/budget. - RECONCILED docs/03 revenue model from consumer finder-fees -> B2G government-paid, matching the thesis + brief (finder-fee model was explicitly excluded at launch). Fixed data/ -> docs/ jurisdictions.json path (data/* is gitignored). Tests: 4/4 suites green. All local/$0. TK-10097
527cc26 · 2026-07-31 · docs(marker): Cycle 2 = adversarial-review fixes (see f576a32); TK-10097
Cody+security-auditor+code-reviewer fan-out -> 4 criticals + crown-jewel privacy fix, all fixed + regression-tested (tests/test_cycle2_hardening.py, 7/7 pass).
9819a89 · 2026-07-31 · Cycle 1: scaffold national unclaimed-property platform (B2G, synthetic-only)
- Thesis + hard guardrails (no scraping, no real feeds, no autonomous contracting) - 50-state + DC acquisition matrix (feed-first, records-request fallback, public handoff) - Polyglot architecture + canonical schema (provenance/version non-destructive) - Reference services: idempotent NAUPA/CSV ETL, Fellegi-Sunter matcher w/ phonetic key, masked FastAPI search, claim state-machine + transactional outbox - Stdlib-only end-to-end smoke test (ingest idempotency + masking + matching) PASSES at $0 TK-10097
File tree
- .gitignore
- Makefile
- README.md
- VERSION
- data/sample/sample_state_feed.csv
- docs/00-thesis-and-guardrails.md
- docs/01-regulatory-state-acquisition-matrix.md
- docs/02-architecture.md
- docs/03-roadmap-and-budget.md
- docs/04-data-use-agreement-template.md
- docs/LOOP-LEDGER.md
- docs/jurisdictions.json
- outreach/README.md
- outreach/TEMPLATE-public-records-request.md
- outreach/generated/AK-records-request.txt
- outreach/generated/AL-records-request.txt
- outreach/generated/AR-records-request.txt
- outreach/generated/AZ-records-request.txt
- outreach/generated/CA-records-request.txt
- outreach/generated/CO-records-request.txt
- outreach/generated/CT-records-request.txt
- outreach/generated/DC-records-request.txt
- outreach/generated/DE-records-request.txt
- outreach/generated/FL-records-request.txt
- outreach/generated/GA-records-request.txt
- outreach/generated/HI-records-request.txt
- outreach/generated/IA-records-request.txt
- outreach/generated/ID-records-request.txt
- outreach/generated/IL-records-request.txt
- outreach/generated/IN-records-request.txt
- outreach/generated/KS-records-request.txt
- outreach/generated/KY-records-request.txt
- outreach/generated/LA-records-request.txt
- outreach/generated/MA-records-request.txt
- outreach/generated/MANIFEST.json
- outreach/generated/MD-records-request.txt
- outreach/generated/ME-records-request.txt
- outreach/generated/MI-records-request.txt
- outreach/generated/MN-records-request.txt
- outreach/generated/MO-records-request.txt
- outreach/generated/MS-records-request.txt
- outreach/generated/MT-records-request.txt
- outreach/generated/NC-records-request.txt
- outreach/generated/ND-records-request.txt
- outreach/generated/NE-records-request.txt
- outreach/generated/NH-records-request.txt
- outreach/generated/NJ-records-request.txt
- outreach/generated/NM-records-request.txt
- outreach/generated/NV-records-request.txt
- outreach/generated/NY-records-request.txt
- outreach/generated/OH-records-request.txt
- outreach/generated/OK-records-request.txt
- outreach/generated/OR-records-request.txt
- outreach/generated/PA-records-request.txt
- outreach/generated/RI-records-request.txt
- outreach/generated/SC-records-request.txt
- outreach/generated/SD-records-request.txt
- outreach/generated/TN-records-request.txt
- outreach/generated/TX-records-request.txt
- outreach/generated/UT-records-request.txt
- outreach/generated/VA-records-request.txt
- outreach/generated/VT-records-request.txt
- outreach/generated/WA-records-request.txt
- outreach/generated/WI-records-request.txt
- outreach/generated/WV-records-request.txt
- outreach/generated/WY-records-request.txt
- outreach/states-records-law.json
- requirements.txt
- scripts/__init__.py
- scripts/demo_tour.py
- scripts/fetch_all_ca.sh
- scripts/gen_records_requests.py
- scripts/load_ca.py
- scripts/pre-commit-tripwire.sh
- scripts/serve_ca.py
- services/__init__.py
- services/claims/__init__.py
- services/claims/claim_workflow.py
- services/claims/outbox_worker.py
- services/claims/sqlite_claim_repo.py
- services/common/__init__.py
- services/common/normalize.py
- services/common/public_projection.py
- services/common/rate_limit.py
- services/common/sqlite_repo.py
- services/ingestion/__init__.py
- services/ingestion/ingest.py
- services/ingestion/naupa2.py
- services/ingestion/naupa3.py
- services/matching/__init__.py
- services/matching/entity_match.py
- services/search/__init__.py
- services/search/run_local.py
- services/search/search_api.py
- services/search/service.py
- tests/__init__.py
- tests/test_cycle10_outbox_worker.py
- tests/test_cycle11_reconciliation.py
- tests/test_cycle2_hardening.py
- tests/test_cycle3_naupa_and_blocking.py
- tests/test_cycle4_fairness.py
- tests/test_cycle5_search.py
- tests/test_cycle6_naupa3.py
- tests/test_cycle7_recall.py
- tests/test_cycle8_suppression.py
- tests/test_cycle9_claims_persistence.py
- tests/test_ingest_and_match.py