{"id":16,"date":"2026-09-22T01:08:35","date_gmt":"2026-09-22T01:08:35","guid":{"rendered":"https:\/\/spectrcyde.com\/?p=16"},"modified":"2026-09-29T01:26:03","modified_gmt":"2026-09-29T01:26:03","slug":"the-run-that-is-not-a-capture-building-evidence-that-cannot-flatter-itself","status":"publish","type":"post","link":"https:\/\/spectrcyde.com\/?p=16","title":{"rendered":"The Run That Is Not a Capture: Building Evidence That Cannot Flatter Itself"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><strong>Date:<\/strong> September 13, 2026<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Author:<\/strong> SCYTHE Team<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Category:<\/strong> Evidence-Centered Computing, RF, GraphOps, Promotion Discipline<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>&#8212;<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">An SDR is plugged into this workstation. A `Realtek RTL2838` sits on<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">`Bus 001 Device 026`, tuned to nothing, doing nothing. Over the last several<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">weeks SCYTHE built the entire path that would let a live walk produce evidence<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">good enough to promote into GraphOps \u2014 the durable ledger, the ownership lock,<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">reconciliation, ceilings, the execution boundary, the derived-evidence reader<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">and its producer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And then, at the moment the run was scoped, the answer came back: **do not open<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">the radio.**<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Not because the radio is dangerous. Because a capture would have changed<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">nothing, and running one anyway would have been authorization theater with a<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">USB cable attached.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That decision, and the six slices of code that followed from it, are the most<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">interesting thing SCYTHE has built this quarter. The engineering story is not<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;we captured RF.&#8221; It is &#8220;we established exactly what our evidence is allowed to<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">claim, and then wrote code that cannot claim more.&#8221;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>## The Finding That Made the Run Small<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The question was simple: what does a walk verdict actually depend on?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">SCYTHE&#8217;s walk checker compares two position fixes against a kinematic budget.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Did the operator move further than a person walking could have moved in the<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">elapsed time? Two hashes travel with each fix:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`text<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">signal_chain_hash &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sensor identity, sample type, rate, antenna,<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;feedline, extension, gain &nbsp;&#8212; all DECLARED<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">receiver_state_chain_hash &nbsp;a manifest of position, speed and orientation<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;authorities<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Neither touches a sample. `check_walk_step` never sees one either. A walk<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">verdict is a statement about displacement, and displacement is computed from<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">latitude, longitude and time.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So we asked what a capture would buy. It would activate the volatile IQ buffer,<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">`rtl_tcp`&#8217;s socket binding, the ring&#8217;s invalidation rules, and the recovery<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">subsystem&#8217;s posture \u2014 the entire Q1 surface \u2014 and produce an artefact<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>identical in every field the verdict depends on<\/strong>. A live observation does not<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">become more meaningful because a receiver was consuming samples nobody looks at.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The act was classified instead:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`text<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">LIVE_POSITION_ATTESTATION &nbsp; &nbsp; &nbsp;a real bounded observation over real<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;attested positions<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">INSTRUMENT_CONFIGURED_IDLE &nbsp; &nbsp; the instrument is declared, and idle<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">RF_MEASUREMENT_NOT_PERFORMED &nbsp; no sample was taken, and none was needed<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The RTL2838&#8217;s presence may be <em>declared<\/em>. The run must not open, tune, reset,<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">claim, or otherwise communicate with it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>## The Schema Could Not Express That, So It Changed<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here is where a contract stops being prose. The artefact provenance in<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">`scythe_derived_evidence` is a <strong>closed<\/strong> field set \u2014 a name that is not in the<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">set is refused rather than ignored \u2014 and it carried no measurement status at<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">all. An artefact could describe a sample rate and a gain, and nothing in the<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">record distinguished <em>configured<\/em> from <em>exercised<\/em>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Adding a required field to a closed set changes what the old schema name means,<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">so the name changed with it:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`text<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">scythe.derived-evidence-artefact.v1 &nbsp;-&gt; &nbsp;.v2<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A v1 artefact is now refused as foreign \u2014 carrying the new fields or not,<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">because the version is not a hint to be overridden by whatever happens to be<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">present. There is <strong>no migration and no default<\/strong>, and none is needed: no v1<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">artefact was ever produced. Writing a compatibility path for a population of<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">zero would mean inventing exactly the defaults the amendment forbids, for a<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">reader that would never meet one.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The two new fields are closed to a single value each:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`python<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">MEASUREMENT_STATUSES = (RF_MEASUREMENT_NOT_PERFORMED,)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">INSTRUMENT_STATES &nbsp; &nbsp;= (INSTRUMENT_CONFIGURED_IDLE,)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">One member is the honest size. This tree can produce exactly one kind of<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">artefact, and a second value would name a capability that does not exist, read<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">by a reader that has never seen one produce anything. When a measurement path<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">is contracted, its amendment adds its value.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>## Configuration Is Not Measurement<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The subtler rule is the one a well-meaning classifier would get wrong.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">An artefact may legitimately carry the configuration it did not exercise \u2014<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">`sample_rate_hz = 2_400_000`, `gain_db = 40.2`, `device_id = &#8220;rtl2838-0bda:2838&#8243;`<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u2014 and it is still a run where nothing was measured. Every populated setting<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">travels beside its own label:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`text<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">sample_rate_hz &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2400000<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">sample_rate_hz_exercise &nbsp; &nbsp;CONFIGURED_NOT_EXERCISED<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">gain_db &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;40.2<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">gain_db_exercise &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CONFIGURED_NOT_EXERCISED<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A setting without its label, a label without its setting, and any other label<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">are each refused \u2014 and neither the reader nor the producer supplies the missing<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">claim, because labelling on the caller&#8217;s behalf would make the label unable to<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">be wrong.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The reader&#8217;s status function reads one field and looks at nothing else:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`python<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">def declared_measurement_status(provenance):<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp; &nbsp; &#8220;&#8221;&#8221;What the artefact says, never what the reader would guess.&#8221;&#8221;&#8221;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp; &nbsp; return provenance[&#8220;measurement_status&#8221;]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Not `device_id`: an RTL2838 in the manifest is an instrument that was <em>named<\/em>,<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">and naming one is not using one. Not the settings: a populated rate and gain<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">are a configuration, and the whole rule is that a declared configuration must<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">not imply it was exercised.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The important design choice is what happens to that configured-idle artefact:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">it is <strong>accepted, with its status preserved<\/strong>, not refused. Refusing it would<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">teach a producer to omit the configuration entirely, after which the reader<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">knows <em>less<\/em> about what was attached than it does now. That is the refusal that<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">makes the record worse.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>## The Observer Cannot Say It Either<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The artefact is only half the record. The observation record \u2014 the thing that<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">says what this run <em>was<\/em> \u2014 also has to carry the declaration, and here the<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">property is an absence rather than a feature.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The observer has:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8211; no constructor field for a measurement status<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8211; no `run` parameter for one<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8211; and, enforced by an AST test over the entire module, **no occurrence of<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp; `RF_MEASUREMENT_NOT_PERFORMED` or `INSTRUMENT_CONFIGURED_IDLE` as a name or<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp; inside any string**<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Containment, not equality \u2014 a token spliced into a longer literal would reach a<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">record just as surely as one standing alone.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The only route is an `Artefact`, taken nominally:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`python<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">InstrumentDeclaration.from_artefact(artefact) &nbsp; # type(artefact) is Artefact<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The observer never met an instrument and neither did the producer. The only<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">party with a claim to make is the artefact, and the artefact makes it in<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">writing. So a run carries a declaration or says it has none:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">| run | authority | status |<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">| &#8212; | &#8212; | &#8212; |<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">| derived artefact | `CARRIED_FROM_ARTEFACT` | the artefact&#8217;s own values |<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">| constructed | `NO_INSTRUMENT_DECLARATION` | `NO_INSTRUMENT_DECLARATION` |<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A constructed run has <strong>no instrument<\/strong> \u2014 not an idle one, not a configured<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">one, none. A constructed run handed a carried declaration, and a live run<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">handed one from nowhere, both publish <em>no record at all<\/em>: the mismatch is<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">refused before the first verdict rather than recorded beside the numbers it<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">would undermine.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>## One Read, Or The Record Describes A Different File<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Verdicts and the declaration must come from the same bytes. Reading the<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">artefact path once for the verdicts and again for the declaration would attest<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">an instrument belonging to whatever the second open found.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So the verdict source became a type rather than two arguments:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`python<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">VerdictSource(declaration=&#8230;, verdicts=&#8230;) &nbsp; # one artefact, one read<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A declaration passed <em>*beside*<\/em> an iterator is a declaration about whatever the<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">caller says. One test counts the opens; one negative control performs the<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">second one and fails that test.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The same rule surfaced again a directory down. The record reports whether the<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">promotion lineage changed during the observation, by digesting every published<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">generation before and after. An empty digest map turned out to have <strong>**three**<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">causes:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`text<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">{} &nbsp; the namespace does not exist<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">{} &nbsp; it exists and holds no generation<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">{} &nbsp; the listing failed<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A record publishing only the map flattens all three into one \u2014 and the<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">flattened version reads as the most reassuring of them: *a valid empty<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">generation was observed and did not change*. Nobody made that claim.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The fix is a single snapshot from a single directory listing:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`python<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">LineageSnapshot(presence, digest)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"># &nbsp; NO_LINEAGE_NAMESPACE | LINEAGE_HOLDS_NO_GENERATION | LINEAGE_PRESENT<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Two listings can describe two filesystem instants, so presence answered by one<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">and digests taken from the other is a record about no single moment. And a<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">listing that fails for any reason other than a missing namespace raises<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">`LINEAGE_INSPECTION_REFUSED` and publishes nothing \u2014 <em>*we could not look*<\/em> is not<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">an answer to <em>*what was there*<\/em>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">An earlier draft of that record also carried a `lineage_present` boolean beside<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">the enum. It was removed. A serialized copy is a second answer that can<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">disagree with the one next to it, and a reader has no way to tell which one the<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">writer meant. The convenience survives as a derived property; the evidence does<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">not store it twice.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>## Names Are Checked By Machine, And Rejected Rather Than Judged<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">SCYTHE keeps two disjoint verdict vocabularies: <strong>**merit**<\/strong> codes say something<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">about the subject, <strong>**executability**<\/strong> codes say whether a verdict could be<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">reached at all. They are named disjointly and counted separately, and a name<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">that reads like a member of the other set is a bug even when the code is<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">correct.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A test enforces this mechanically. It parses every non-test module in the tree<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">via AST \u2014 never raw text \u2014 and discovers the universe rather than trusting a<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">hand-maintained list:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`text<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">discovered tokens &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;395<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">declared merit codes &nbsp; &nbsp; &nbsp; &nbsp;25<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">declared executability &nbsp; &nbsp; &nbsp;50<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The check is component-level containment in both directions, plus negation-pair<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">detection for `UN`\/`NON`\/`NOT` prefixes. Every hit is either a real collision or<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">a recorded judgement with a reason. There is no third state.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The interesting part is the names it has killed. In the last three slices alone:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">| candidate | collided with | outcome |<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">| &#8212; | &#8212; | &#8212; |<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">| `DECLARED_NOT_EXERCISED` | `LEDGER_GENERATION_UNDECLARED` | renamed `CONFIGURED_NOT_EXERCISED` |<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">| `ARTEFACT_DECLARED` | `LEDGER_GENERATION_UNDECLARED` | renamed `CARRIED_FROM_ARTEFACT` |<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">| `ARTEFACT_ATTESTED` | `LOCK_EXCLUSION_UNATTESTED` | rejected |<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">| `LINEAGE_ABSENT` | `ABSENT` (a coordinate kind) | renamed `NO_LINEAGE_NAMESPACE` |<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">| `LINEAGE_INSPECTION_FAILED` | `FAILED` | renamed `LINEAGE_INSPECTION_REFUSED` |<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Each rejection is itself a test. `DECLARED_NOT_EXERCISED` <em>would have<\/em> collided,<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">and a test asserts it \u2014 so the reason survives after the prose explaining it has<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">been forgotten.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>## Every Property Has A Mutation That Breaks It<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A passing test suite proves that code runs. It does not prove the tests are<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">watching anything. SCYTHE&#8217;s answer is a negative control per property: a<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">deliberate mutation that must make <strong>exactly<\/strong> that property&#8217;s tests fail and no<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">others.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The last four slices added 53, on a set that numbers 132 at the time of<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">writing. A representative sample:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`text<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">status inferred from populated sample rate and gain &nbsp; &nbsp;-&gt; 4\/4 broken<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">status inferred from device identity &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt; 4\/4 broken<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">the observer writes the status into the record itself &nbsp;-&gt; 1\/1 broken<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">a measurement value spliced into the observer&#8217;s source -&gt; 1\/1 broken<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">the artefact opened twice, declaration and verdicts apart -&gt; 1\/1 broken<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">presence inferred from an empty digest map &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt; 2\/2 broken<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">an unreadable namespace reported as an empty lineage &nbsp; -&gt; 2\/2 broken<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">a second answer serialized beside the enum &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt; 2\/2 broken<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Each control also runs every <em>other<\/em> test in its slice, to catch a mutation<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">that breaks half the suite and therefore proves nothing about which property<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">the tests are watching.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Controls earn their keep by finding real weaknesses, and three did:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8211; the closed-set test read its constants at import and never saw the sets open;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8211; the AST test compared strings by equality, so a token spliced into a longer<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp; literal passed it;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8211; an undeclared-name control reached only the reader&#8217;s copy of a set the<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp; producer binds separately.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">All three were test bugs, found by the mutation rather than by review.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>## Merge Is Not Acceptance<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">One process lesson is worth recording because it cost three repairs.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The governing discipline here is <strong>proposal \u2192 acceptance \u2192 implementation<\/strong>, each<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">a separate commit, merged before any code depends on it. Three times, an<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">amendment was merged while the document still described itself as `PROPOSED`.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Each was repaired by a forward acceptance commit rather than a rewritten merge:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">treating the conversation as acceptance while the document said otherwise would<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">leave a contract contradicting itself, which is worse than a visible two-step.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The tempting generalization \u2014 <em>a merge instruction implies acceptance<\/em> \u2014 was<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">drafted, reviewed, and thrown out. It deletes a decision the contract exists to<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">require. A proposal may be merged precisely to preserve it as a proposal<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>without<\/em> authorizing what it describes. What landed instead is a gate:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&gt; A proposed amendment requires an explicit acceptance decision and an<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&gt; acceptance commit before implementation or execution. Merge approval alone<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&gt; does not supply acceptance unless it expressly says that the amendment&#8217;s<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&gt; substance is accepted.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>## Where It Stands<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`text<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Promotion Execution Contract &nbsp; &nbsp;3,596 lines, amendments A-M<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Test suite &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1,493 tests, OK (skipped=1)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Negative controls &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 132, all discriminating<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Slices landed &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 3, 4, 6, 6b, 7, 8, 9, 10a-10g<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Counts as of merge `f6bdf69`. They move every slice; the contract line count<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">and the vocabulary figures move more slowly.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The directories for the bounded run are pinned, resolved against the host, and<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">created at mode `0700`:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`text<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">lineage root &nbsp; \/home\/spectrcyde\/scythe-ledger\/promotion &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; absent<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">derived &nbsp; &nbsp; &nbsp; &nbsp;\/home\/spectrcyde\/scythe-live-observation\/derived &nbsp; &nbsp; empty<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">records &nbsp; &nbsp; &nbsp; &nbsp;\/home\/spectrcyde\/scythe-live-observation\/records &nbsp; &nbsp; empty<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The namespace-refusal check was run against the real function, not by eye \u2014<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">a detail worth stating, because the rule is wider than it looks. The lineage<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">root is a <em>*filename prefix*<\/em>, not a directory, so the forbidden namespace is its<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">parent. Placing the lineage root directly inside the observation tree refuses<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>both<\/strong> output directories, and that is the arrangement anyone tidying paths<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">would reach for first.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>## The Last Blocker Is A Person<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Everything mechanical is done. What remains is not mechanical.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The run needs twelve <strong>operator-declared<\/strong> fixes: real positions, observed<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">during a walk, read off a screen and typed in by a person, roughly fifteen<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">seconds apart, each stamped with the host&#8217;s `monotonic_ns` at the instant the<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">runner accepts it. That is the host&#8217;s <em>*ingestion*<\/em> time, not the receiver&#8217;s fix<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">time, and the artefact says so \u2014 the two differ by however long the<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">transcription took, and no elapsed time may be computed across a phone&#8217;s wall<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">clock and a host monotonic value.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The authority chain is recorded in three fields rather than one, because<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">collapsing them would lose the step where the authority actually degrades:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`text<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">position source &nbsp; &nbsp; &nbsp; PHONE_DISPLAYED_FIX<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">transfer &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;HAND_TRANSCRIPTION<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">accepted authority &nbsp; &nbsp;OPERATOR_DECLARED<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8220;`<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The phone may hold a genuine GNSS fix. What reaches the artefact is what a<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">person read and retyped. **A fix read off a screen and typed in is a typed<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">fix**, and it is not elevated to device-attested GNSS merely because a phone<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">displayed it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So the run waits. Not on a missing feature, and not on a device \u2014 on somebody<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">walking.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It is worth being exact about what the code enforces here, because the<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">temptation is to describe the intent and let a reader hear a guarantee.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>**The cadence is attested, not enforced.**<\/strong> The runner requires an interactive<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">terminal, which rejects a pipe or a redirected file. It cannot prove a person<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">was not pasting a buffer they prepared earlier: a paste into a live terminal<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">arrives through the same descriptor a typed line does. So the fifteen-second<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">spacing is an operator&#8217;s attestation and a target, never a refusal \u2014 M.5<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">declares only the count and the duration as active bounds. What the artefact<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">carries is the <em>*actual*<\/em> monotonic interval between accepted fixes, which means a<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">reviewer can see a cadence that does not look like walking even though nothing<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">refused it at the time.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>**A short run publishes nothing.**<\/strong> The runner will not interpolate a missing<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">fix, will not repeat one to make the count, and will not substitute constructed<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">evidence. What it does with an incomplete set is refuse: on the 240-second<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">deadline it raises `ENTRY_DEADLINE_REACHED` and no artefact is written at all.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">An earlier draft of this post said such a run &#8220;ends on its bounds with what it<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">has&#8221; \u2014 that describes the amendment&#8217;s intent for a run and not the code&#8217;s<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">behaviour, which has no notion of a partial artefact. Eleven fixes produce<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">nothing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The no-fallback prohibition is the one that would be tempting at the moment it<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">mattered, which is exactly why it is written down.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>&#8212;<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">*The Promotion Execution Contract lives at `docs\/PROMOTION_EXECUTION_CONTRACT.md`.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The vocabulary rules it conforms to are in `SCYTHE_VERDICT_VOCABULARIES.md`.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nothing described here has promoted anything to GraphOps: promotion authority<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">remains a separate explicit act, and the ARMED path stays blocked until a<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">completed observation record is reviewed.*<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Date: September 13, 2026 Author: SCYTHE Team Category: Evidence-Centered Computing, RF, GraphOps, Promotion Discipline &#8212; An SDR is plugged into this workstation. A `Realtek RTL2838` sits on `Bus 001 Device 026`, tuned to nothing, doing nothing. Over the last several weeks SCYTHE built the entire path that would let a live walk produce evidence good [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":68,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-16","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scythe"],"_links":{"self":[{"href":"https:\/\/spectrcyde.com\/index.php?rest_route=\/wp\/v2\/posts\/16","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/spectrcyde.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/spectrcyde.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/spectrcyde.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/spectrcyde.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=16"}],"version-history":[{"count":1,"href":"https:\/\/spectrcyde.com\/index.php?rest_route=\/wp\/v2\/posts\/16\/revisions"}],"predecessor-version":[{"id":17,"href":"https:\/\/spectrcyde.com\/index.php?rest_route=\/wp\/v2\/posts\/16\/revisions\/17"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/spectrcyde.com\/index.php?rest_route=\/wp\/v2\/media\/68"}],"wp:attachment":[{"href":"https:\/\/spectrcyde.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=16"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/spectrcyde.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=16"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/spectrcyde.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=16"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}