|
| 1 | +# Live predicate, verified over a real network — 2026-09-21 |
| 2 | + |
| 3 | +`live-collection` was written to verify a real collection and had never been run. This |
| 4 | +records what happened when its success predicate was executed for real, keyless, against |
| 5 | +live sites — and the defect that found. |
| 6 | + |
| 7 | +**Status: local keyless live predicate verified.** Not "live-collection verified". The |
| 8 | +distinction is the point of this file. |
| 9 | + |
| 10 | +## Method |
| 11 | + |
| 12 | +A scratch project outside the repository, `--transport http-keyless`, two direct URLs and |
| 13 | +no search provider, so nothing was spent. Each condition of the workflow's predicate was |
| 14 | +run and its exit code read. |
| 15 | + |
| 16 | +## The defect: the predicate asked a question collection cannot answer |
| 17 | + |
| 18 | +The workflow required **`preflight` to exit 0** on the scratch project it collects into. |
| 19 | +Preflight exits **1** there, and correctly: |
| 20 | + |
| 21 | +``` |
| 22 | +fail discovery-contract/no-unknowns the contract enumerates no blocking unknowns - |
| 23 | + a contract with no unknowns makes no claim |
| 24 | +FAIL 1 blocking, 4 warning(s), 8 passing |
| 25 | +``` |
| 26 | + |
| 27 | +Preflight answers *"is the research sufficient to build?"* — a **human-authored** |
| 28 | +question. A freshly scaffolded project has no unknowns in its contract, so it fails that |
| 29 | +check however perfectly collection worked. **The workflow would have failed on every run, |
| 30 | +always, for a reason having nothing to do with the transport it exists to test.** |
| 31 | + |
| 32 | +Reading the workflow would not have found this. Running it did, on the first attempt, and |
| 33 | +it cost nothing because the keyless route is free. |
| 34 | + |
| 35 | +### The correction |
| 36 | + |
| 37 | +The predicate now requires the checks collection *can* answer — the integrity ones, each |
| 38 | +required individually: |
| 39 | + |
| 40 | +| check | what it asserts | |
| 41 | +|---|---| |
| 42 | +| `provenance` | the chain verifies and every cited capture was actually fetched | |
| 43 | +| `corpus-shape` | the corpus parses and the shape is there | |
| 44 | +| `citations` | every evidence row has a URL, a claim, and a cached page behind it | |
| 45 | +| `transport-provenance` | which adapter fetched each cited capture | |
| 46 | +| `hygiene` | duplicate rows, uncited captures, unparseable dates | |
| 47 | + |
| 48 | +All five pass on a freshly collected scratch corpus. A test now refuses any executable |
| 49 | +line invoking `preflight.mjs` without `--check`. |
| 50 | + |
| 51 | +## What ran, and what it returned |
| 52 | + |
| 53 | +| condition | result | |
| 54 | +|---|---| |
| 55 | +| scaffold a scratch project | ok | |
| 56 | +| `research.mjs --dry-run` | exit 0 | |
| 57 | +| `research.mjs` (2 pages, keyless, real network) | exit 0, 2 collected, 0 failed | |
| 58 | +| ledger exists, parses, records a successful fetch | 2 entries, 2 successful | |
| 59 | +| `handoff.mjs` | exit 0 — "every cited capture on disk, chain verifies" | |
| 60 | +| the five integrity checks | all exit 0 | |
| 61 | +| repository unchanged | no change under `research/` | |
| 62 | + |
| 63 | +Both captures graded `partial`, which the keyless adapter reports honestly rather than |
| 64 | +claiming `full` — itself a small confirmation that the completeness grading survives a |
| 65 | +real fetch. |
| 66 | + |
| 67 | +## What this does and does not establish |
| 68 | + |
| 69 | +**Established, over a real network:** |
| 70 | + |
| 71 | +- the predicate logic is satisfiable by a real corpus, not only by fixtures |
| 72 | +- real network behaviour reaches the collector, and the ledger records it |
| 73 | +- ledger → handoff → integrity-check integration holds outside synthetic tests |
| 74 | +- the "repository unchanged" guard is meaningful: collection wrote only to the scratch path |
| 75 | + |
| 76 | +**Still unproven, and not claimed:** |
| 77 | + |
| 78 | +- the Firecrawl CLI install path in the workflow |
| 79 | +- `cliCompatibility` against a real installed CLI in CI |
| 80 | +- metered credential handling |
| 81 | +- the GitHub environment secret wiring |
| 82 | +- the Actions runner path itself — `workflow_dispatch` has never fired |
| 83 | + |
| 84 | +The gap is now "the CI wiring and the metered route are untested" rather than "the whole |
| 85 | +thing is untested", which is smaller and specific. Closing the rest needs the |
| 86 | +`live-collection` environment and one real dispatch. |
0 commit comments