Skip to content

Delegation preflight: check the endpoint before you delegate, and fix two probes that were understating reality - #19

Open
github-actions[bot] wants to merge 2 commits into
mainfrom
ship/truth-layer-v2
Open

Delegation preflight: check the endpoint before you delegate, and fix two probes that were understating reality#19
github-actions[bot] wants to merge 2 commits into
mainfrom
ship/truth-layer-v2

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Machine-operated ship branch ship/truth-layer-v2.

The ship workflow dispatches the full ci matrix, waits for it, merges only the certified combined state with main, then runs the deployment-aware release gate against the merged SHA — with automatic certified revert on a red gate. See .github/workflows/ship.yml.

AgentTanuki added 2 commits July 31, 2026 07:25
…est passport/funnel/self-eval semantics

DIVERGENCE (P0). Production served two mutually inconsistent views of the
same counters, and POST /ledger/checkpoint/publish returned index 14 /
ledger_length 834 while the published feed was already at 16 / 836.

The READ-side cause is NOT proved and no speculative state fix ships: 40
concurrent /release probes returned one process boot time, 60 concurrent
mixed requests showed zero cross-request body mixing, and unique
cache-busters ruled out URL-keyed caching. What was missing was any way to
tell WHICH process or WHICH state produced a response, so every candidate
explanation fitted the evidence equally. That is fixed:

  * app/instanceid.py - random per-process instance id, boot time, pid
  * X-Guild-Instance / X-Guild-Boot / X-Guild-Store-Rev on every response
  * GET /diagnostics/state - in-memory vs AUTHORITATIVE SQLite counts with a
    `divergence` list naming the exact disagreement (no paths or secrets)
  * live/scripts/detect_divergence.py - classifies split_origin /
    stale_in_process / memory_durable_split / intermediary. This replaces
    "discard the first 2-3 reads", which was a reporting workaround with no
    write-path coverage.

The WRITE-side defect IS proved and is reproduced locally with two Store
instances over one shared SQLite file:
  * authoritative read moved INSIDE BEGIN IMMEDIATE (was a TOCTOU window)
  * StaleDurableStateError when the durable head is behind a head this
    process already observed, or the durable ledger is shorter than memory
  * insert_checkpoint_strict: plain INSERT, so a duplicate index raises
    CheckpointForkError instead of INSERT OR REPLACE silently overwriting a
    pinned commitment; next index from max(index)+1, not len()
  * read-after-write byte verification - a publish that did not land can no
    longer be reported as published
  * all three map to HTTP 409 with a stable machine-readable code
  * SqliteBackend._commit depth clamped at 0: a nested rollback used to leave
    the THREAD-LOCAL connection at depth -1, after which that thread silently
    ran every later "transaction" in autocommit for the life of the process

Evidence is phrased honestly: no durable loss DETECTED (every cumulative
counter on the warm branch >= the previous snapshot); individual event
continuity is not proven and is not claimed.

PASSPORT TELEMETRY. The MCP tool recorded passport_issued on entry and
Store.issue_passport recorded a second one on success: one call counted
twice, and a lookup MISS counted as an issuance. That is how a schema probe
moved the headline "genuine external passports issued" from 1 to 3 with no
agent behind it. Now exactly one event, on success only, carrying transport,
actor, subject_id, self_claim and a request/correlation id; attempts and
failures are separate event types. passport_activity() reports distinct
subjects for self-claim / third-party fetch / third-party verification /
evidence attached, and never emits a single "passports" or "adoption" number.
Raw history is untouched.

QUALIFIED FUNNEL. /funnel/passports keeps raw stage totals for observability
(now labelled as NOT a conversion funnel) and adds a qualified cohort view:
excludes first-party, tooling and registry crawlers structurally,
deduplicates exposure per (actor, source, window), links an exposed actor to
that SAME actor's registration/proof/own-passport/evidence/return, keeps
third-party propagation in a separate loop, reports anonymous exposure as
UNLINKABLE rather than as failed conversion, and reports a zero denominator
as NOT MEASURABLE with the sample size attached instead of "0% conversion".

SELF-EVAL. Utility now reads the production-only block of /evaluation with
n_recommended attached; the mixed/seeded lift survives only under
mixed_bootstrap_lift_NOT_PRODUCTION. Revenue comes only from independently
confirmed external mainnet settlement; the sandbox-credit dollar line is
retired to legacy_sandbox_credit_notional_usd_NOT_REVENUE. Growth uses
adoption-grade external actors. "FLYWHEEL TURNING" now requires BOTH an
external agent holding its own credential AND verified external revenue, and
otherwise names which half is missing.

Tests: 1010 passed, 9 skipped (29 new across test_state_divergence.py and
test_truth_layer_invariants.py). Contract regenerated for /diagnostics/state.
… two probes that were understating reality

WHY THIS AND NOT MORE PASSPORT SURFACE. Measured today: total x402 settled
volume across all networks in July 2026 was $232,329, down 98.9% from the
November 2025 peak on flat transaction count; the median Bazaar listing takes
2 calls and 1 unique payer per 30 days; the median earning agent makes $1.65
per 30 days. Virtuals has 44,051 registered agents and 69 active in July.
Olas has 13.97M lifetime agent-to-agent transactions and $458 of protocol
fees, ever. Five percent of the entire global machine-payments market is
$11.6k/month. The passport remains the right ACQUISITION instrument; it is
not a revenue instrument, and selling to agents earning $1.65/month is
arithmetically dead. Reach is not the constraint either - offer_served went
944 to 1,790 in 24h, all crawlers.

THE GAP WITH ACTUAL EVIDENCE. 170 of 183 a2aregistry agents report healthy
(92.9%); 62 (33.9%) complete a task - 114 agents are green and broken at the
same time. 42 of 3,913 valid cards are signed (0.8%). 141 of 2,459
self-declared paid agents return a 402 (5.7%). The A2A discovery spec states
it prescribes no registry API and never mentions signatures. x402 `exact` is
irreversible with no escrow. Every existing signal grades a repository or a
static card once at publication time; nobody attests to the RUNNING endpoint
at call time, which is where the rug pull lives.

SHIPPED. GET /preflight?url=... and the guild_preflight MCP tool. Free, no
key, one call, live at request time: endpoint_reachable, protocol_handshake
(a real A2A/MCP handshake, not merely HTTP 200), agent_card_resolves,
agent_card_signed (presence, explicitly not claimed as verification),
payment_claim_holds (does an advertised paid endpoint actually 402), and
independent_evidence. Unknowns are reported and EXCLUDED from the verdict,
never averaged in; a clean verdict still publishes its unknown count;
absence of evidence is stated as absence, not as risk. SSRF-screened so it
can never be used as an internal port scanner. Surfaced on llms.txt and MCP.

TWO OF OUR OWN DEFECTS, both UNDERSTATING reality:
  * chunked transfer-encoding was never decoded, so the raw hex chunk-length
    line broke every downstream JSON check. Because the card check is what
    promotes an endpoint from http_responsive to recently_reachable, any
    agent served over chunked encoding was recorded as unproven. This is why
    verified_reachable read 0 for EVERY entry in the demand feed - not
    because nobody was reachable, but because we could not read them.
  * a large but valid card was read as no card at all: the probe read is
    bounded, so verbose cards arrive truncated and fail to parse. Agent
    Guild's own endpoint failed its own preflight until this was fixed.

Instrumentation, baseline and kill thresholds in
docs/EXPERIMENT_PREFLIGHT_2026-07-31.md. No price is live and no payment
configuration was touched; metering is written up as a proposal requiring
explicit approval.

Tests: 1026 passed, 9 skipped (16 new).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants