Skip to content

Latest commit

 

History

History
50 lines (29 loc) · 9.91 KB

File metadata and controls

50 lines (29 loc) · 9.91 KB

Backlog

Ledger, not narrative. Top unblocked item is next. Markers: [ ] open, [b] blocked.

Rules:

  • One line per item: - [ ] <ID> (<Severity>, <class>, <dimension>): <finding>. Acceptance: <runnable command or observable fact>.
  • Class is one of runtime, test, build-ci, docs, dev-tooling, chosen by the files the fix will touch; a line without one is read as runtime. Within a section, order by severity first, then runtime before the other classes.
  • A finished task is deleted from its section and recorded as one line in the JOURNAL entry that closed it. No done markers accumulate here.
  • Run context, audit scores, and DONE annotations live in JOURNAL.md only. No prose sections and no headings beyond the ones below, ever.

Now

Next

Later

  • [b] E4 (Low, build-ci, developer experience): .github/workflows/verify.yml is written and runs both gates on push and pull_request; blocked on the two clauses this loop cannot satisfy - it never pushes, so no green run can be observed on the default branch, and the PLAN.md Verify command is a Windows venv path that cannot execute on a runner, so the workflow drives the same two gates through uv instead. Every shell command in it was verified against a fresh git clone, which is what CI checks out; the runner steps were not executed.

Proposed

Items needing a user decision before any work, one plain line each, never a checkbox task: envelope changes, audit escalations, challenges to a settled class. Never worked without explicit user approval and never counted against convergence.

  • Should the published tables be invariant to the row order of a pull, not merely reproducible from one? D1 made every ranking sort stable, which pins the tie-break to the export's order but cannot make a result independent of that order. Two mechanisms remain order-dependent and both were reproduced by permuting the current pull: latest_per_parcel keeps the last of several rows sharing a parcel's latest date, and the export emits such repeats for 3929 parcel-date groups whose rows all differ; and consolidate picks primary and median_acquired through value_counts().idxmax() and a median over the group, which moved for 3 and 1 interests respectively, all holding one or two parcels and so below the league table's five-parcel cut. Closing this needs a decision on which deed row and which of several equal-count names is authoritative, which is data semantics rather than a keyword. Reproduced only by permuting a machine-generated file, so Low at most under the envelope as filed.
  • Site Address in the sale exports still publishes street lines: universe_sales_40_79 carries 63 distinct values that are not township-range descriptors and sales_window carries 51, out of 11,389 and 848 records. None matches a known mailing street today, so the repaired gate is green, but the next pull can overlap and the remedy is not mechanical - the notebook parses that field with TRS_PAT, so tokenising it as the tax export now does would erase the section, township and range the whole analysis runs on. Needs an owner decision on what to publish there.
  • STATUS.md must be updated when E2, E3 and E8 close: its Open section still lists all three as deliberately not fixed, its Do-not-touch section still reserves the six strict xfail markers, and its Next prompt still points at coverage gap 4. The owner approved all three on 2026-08-04, so the reservation is spent, but only the owner's own file records that. Re-checked at the iteration 3 audit and every clause of it is now stale rather than merely pending: no xfail marker remains anywhere under tests, the two pins STATUS.md names by class were each replaced by real assertions rather than deleted, at tests/test_elko_client.py TestToken for the valueless and empty token and at tests/test_verify_outputs_scan.py TestCheckPrivacy for a street inside a committed gzip snapshot, and coverage gap 4 is closed, with tests/test_screen_refresh.py asserting both STAMP-derived filenames against refresh.STAMP.

Settled classes

One line per class: the idiom or defect class, the surface it applies to, and how it was settled - fixed class-complete with its enumerating check, or declined with the reason. Audits must not file findings inside a settled class unless its implementing code changed after settlement.

  • Sorting a frame whose order or rank reaches a published value without kind=stable, across distress.py, ownership.py and screen.py: fixed class-complete at D1. The enumeration is grep -rn "sort_values" --include=*.py excluding .venv, tests and .jeffy, which returns seven sites. Four now sort stably: latest_per_parcel, _real_estate (already stable before this task), assign_tiers, and consolidate. Three were driven and settled rather than changed: concentration's share sort feeds only order-invariant aggregates and its outputs were identical under three permutations of its input; vintage sorts a groupby result whose year column is unique, so no tie exists; and screen.py sorts on (tier, rank_in_tier), which was verified unique over all 415 screened rows. A later finding of this shape belongs to this class.

  • A guard that checks a locator is present but never checks that parsing it succeeded, across elko_client.py and snapshot.py: fixed class-complete at E3. The enumeration was built by provoking a failure at every step of both operations rather than by grepping for calls, and it is kept as tests: five sites raise the module's documented clear error now - elko_client.token on a missing or empty value attribute, elko_client.search on a present locator with an unparseable count, elko_client.export on a body that passes the content-type guard and fails to parse, elko_client.pull on rows lacking the reconciliation key, and snapshot.stamp_of on a recognised suffix with no underscore or a stamp that is not eight digits. Two sites were provoked, examined and deliberately left: elko_client.pull raises TypeError on an unhashable value under the key, which the export does not emit and which fails loudly rather than returning a wrong count, and snapshot.load raises JSONDecodeError on a malformed body, which is the project's own machine-generated file at rest and carries no documented clear-error contract.

  • Hand-listing AST node types to decide what binds a name, in verify_outputs.check_headline_names: fixed class-complete at E2. Enumeration is the REBINDING_FORMS and WRITES_THROUGH_THE_NAME tables in tests/test_verify_outputs.py, which drive every binding form Python has plus the two writes that bind nothing, and a further case asserts the table's own membership so a form cannot be dropped from it quietly. The walk now keys on Store-context Name nodes, which covers ten forms at once and is also what distinguishes rebinding from mutation, plus the four binders that carry a plain string. Any future finding of this shape belongs to this class, not to a new instance.

  • Joining a bill-level tax export on Account ID as if it were unique, across distress.py and valuation.py: fixed class-complete at E1. Enumeration is grep -rn "Account ID" --include=*.py . excluding .venv and tests, whose merge lines are exactly distress.derive and valuation.carry_rate; both are now fed a frame carrying one row per Account ID, _real_estate by an earliest-Delinquent-Since stable dedup and carry_rate by a groupby sum of the year's bills. pull_tax.py names the same column only for export reconciliation, which already counted distinct ids. The other index lookups in valuation and fred_client key on period, year and date, all unique by construction, so they are outside this class.

  • An aggregation reaching a published value whose pinning fixture makes the aggregation choice irrelevant: fixed class-complete at G1, over both axes on which the earlier claim at R3 was false. Neither the modules nor the method names are listed by hand any more. FILES in .jeffy/probes/aggregation-mutations/probe.py is derived from the modules on disk, so a module added to the project enters the enumeration by existing; and every method name those modules call is classified into AGG, which reduces many values to one or selects which is returned, or NOT_AGG, which does neither, with a name in neither failing the battery by name rather than being silently absent from it. That inversion is the fix: listing only what you are looking for cannot report what you missed. enumerate_sites keys each call file|function|attr|ordinal and check_coverage fails unless every key is mutated or set aside. The enumeration returns 57 sites across 14 modules, where the grep this class was first settled under returned 28 and the table covered 16; 53 carry 55 mutations and all 55 are killed, and 4 are set aside, being the two value_counts tabulations whose published value is chosen by the adjacent idxmax that is itself mutated, the mail_state emptiness guard, and _street_addresses' unique, the last two equivalent mutants with their evidence recorded in the probe. Across R2, R3, G2 and G1 twenty-two mutations were observed surviving before they were killed, and every one was closed by strengthening a fixture or writing the missing check, never by weakening a mutation.

Declined

Findings judged not worth fixing, one line each with the reason. Audits must not re-file these.

  • fred_client.latest_snapshot takes the stamp as p.stem.split("")[-1], so a fred_meta file whose tail is not a date is returned as the stamp and shadows the real snapshot; reproduced with a fred_meta_notadate.json, after which load_series raises FileNotFoundError. Declined: data/fred/fred_meta.json is machine-generated, the generator never emits that name, and the failure is loud rather than a wrong number, so it is out of envelope and Low at most. Recorded because it is the same idiom as the class settled at E3, whose enumeration was scoped to elko_client.py and snapshot.py and so never covered fred_client.py.

Converged

One line per convergence, appended, never rewritten: Converged: - . The ratchet reads the latest line here. Converged: 06edbf12f1b23b71727744fa963d036a9a074e6b - 2026-08-07