Commit Graph

5 Commits

Author SHA1 Message Date
byrongamatos
ac5c5ad20d ci: cover gap-fill manifest key scans
Signed-off-by: byrongamatos <xasiklas@gmail.com>
2026-07-13 13:25:44 +02:00
topkoa
5dcf39cd62 test: drop unused sys import (review)
Signed-off-by: topkoa <topkoa@gmail.com>
2026-07-13 01:14:02 -04:00
topkoa
203f82b6fe ci: legible failures for malformed exceptions file; docs catch up
_parse_exceptions() now validates the document shape — top level must be a
mapping, 'exceptions' must be a list, each entry a mapping, and YAML parse
errors are caught — each failing with a ::error:: instead of an
AttributeError traceback. CI output must say what to fix. Parametrised
tests cover all four malformed shapes.

docs/feedpak-spec-gate.md: the Limitations section still described the
pre-flow-aware scanner (KEY_OPS, name-list-only receivers). Now states the
actual residual gaps: function-parameter manifests are recognised by name
only, and helper-mediated literal keys (song.py's
_gap_fill_manifest_absent(manifest, "album")) are unseen by both the scan
and the readers-complete guard, since they share one detector.

Signed-off-by: topkoa <topkoa@gmail.com>
2026-07-13 00:53:09 -04:00
topkoa
0158286d06 ci: flow-aware manifest discovery — a name list missed real readers
Review found lib/routers/chart.py binding `m = load_manifest(p) or {}` and
reading eight manifest keys through it. `m` was not in MANIFEST_VARS and
`m.get` did not match the readers-complete regex, so the module was
invisible to BOTH halves of the gate — unlisted and unscanned. Same for
lib/routers/song.py (binds `manifest` from load_manifest for enrichment
gap-fill). Both are now in READERS.

The structural fix, not the name-list patch: keys_touched() now discovers
receivers flow-aware — any local assigned from load_manifest(...) is a
manifest dict, whatever it is called. MANIFEST_VARS remains only as the
fallback for manifests that arrive as function parameters (ws_highway).
A plain `m = {}` is not a receiver; test pins that.

readers-complete now reuses keys_touched() itself instead of a parallel
KEY_OPS regex — the two detectors diverged once already (that is exactly
how chart.py slipped through), so now there is one detector and one truth.

check_reverse() gets a 300s subprocess timeout: the validator executes at a
pinned SHA, but a pathological pack or validator bug should fail the job,
not hang the runner to the Actions-level timeout.

Tests: flow-aware receiver under an arbitrary name (read + write), and the
negative — a plain dict named `m` stays out of the scan. 17 pass.

Signed-off-by: topkoa <topkoa@gmail.com>
2026-07-13 00:45:38 -04:00
topkoa
b54b65d35c test: give the spec gate its own regression suite
Self-review finding: the gate is what keeps the app from drifting off the
feedpak spec, but the gate itself had zero pytest coverage — a refactor
could quietly weaken keys_touched or the allowlist logic and nothing would
notice. The protector needs protecting.

tests/test_spec_gate.py pins the load-bearing behaviours:

- read/write classification: get() reads; subscript Store and setdefault()
  write (the two forms that were blind spots in review); the
  load_manifest-wrapped get; unrelated dicts and non-literal keys ignored.
- exceptions file: duplicate keys and issue-less entries rejected.
- the closed allowlist: growth fails, shrink and steady state pass,
  bootstrap skips.
- live-tree checks, same as CI: READERS matches the codebase, and the only
  non-spec key core touches is the grandfathered original_audio.

Also fixes stale "Layer 2/3" docstrings on check_forward/check_reverse
(they are layers 3/4 since allowlist-closed landed) — the same
docs-lag-the-code class this PR's review kept catching; now the numbering
is asserted by the printed [n/4] headers next to them.

Signed-off-by: topkoa <topkoa@gmail.com>
2026-07-13 00:39:36 -04:00