Third corrections: exposure to a price means being SHOWN that price, and one DID is one subject - #33
Open
github-actions[bot] wants to merge 2 commits into
Open
Third corrections: exposure to a price means being SHOWN that price, and one DID is one subject#33github-actions[bot] wants to merge 2 commits into
github-actions[bot] wants to merge 2 commits into
Conversation
added 2 commits
July 31, 2026 13:30
…istaken for money, experiments were promoted by unrelated revenue Five system-level defects found by independent review of 79265a9. Every one passed its own unit tests; each was only visible end to end. 1. A2A DEEP-PREFLIGHT PAYMENT WAS BROKEN END TO END. _preq_from_task always rebuilt payments.check_request(capability) and handle_payment_submission always returned store.check(...), so a deep-preflight challenge settled the WRONG canonical operation and returned a capability shortlist to someone who had paid for an endpoint check. The task now persists the exact operation and its canonical params at quote time; reconstruction is table-driven through payments.request_from_stored, reads ONLY our own stored fields (a submission cannot steer settlement onto another operation) and refuses an unknown operation instead of defaulting. Settlement dispatches to the product actually bought and records a deep_preflight_run with full settlement metadata and the actor quoted. Covered by a payment-required -> submitted -> completed test, not just challenge/card assertions. 2. settlement_mode == "x402" IS NOT PROOF OF MONEY. The same rail defaults to Base Sepolia, where a successful settlement is a successful payment of nothing, and a facilitator claiming success is not a chain receipt. HTTP/MCP/A2A now record confirmed, mainnet, network, amount and tx from auth.settled.record, and revenue requires ALL of: x402 + confirmed + mainnet + genuine-external attribution. Testnet and unconfirmed settlements are reported separately as supporting and can never promote. 3. EXPERIMENTS WERE NOT INDEPENDENTLY ATTRIBUTABLE. Any global primary metric moving could promote any experiment, so unrelated escrow revenue - or a watch sold for a different offer - would "prove" a deep_preflight price change worked. Each experiment is now bound to its operation; exposure, revenue, payers and repeat use are computed from that operation's events only, and revenue is summed from settled amounts rather than a global total. Also enforced ONE applied change per cycle GLOBALLY, not per experiment: two prices moving at once makes both results uninterpretable, which is the whole point of "one independently measurable change at a time". 4. THE A2A CARD STILL OPENED WITH PASSPORT ISSUANCE. It now leads with the endpoint decision and the measured numbers; the passport follows as supporting, with its register snippet intact so the offer funnel stage is not silently dropped. The existing copy-contract test was updated to the new ordering rather than deleted. 5. REMOTE INGEST WAS STILL DORMANT. A bounded local-only cycle is green in production, so the documented, capped MCP Registry adapter is now cleared and on by default, with GUILD_INDEX_INGEST=0 retained as a one-config-change kill switch. Sources we will NOT ingest are named with their exact gate rather than silently omitted: a2a_registry (the A2A discovery spec states it prescribes no registry API, so any endpoint we used would be undocumented - enabling it would mean scraping) and x402_bazaar (bulk automated reading is not covered by a documented public API contract, and a trade-listing surface is exactly where an unclear permission should be resolved before reading at machine speed). Published at /admin/index/cycle -> bounds and indexsources.active_sources. Also re-applies the index autorun default and POST /admin/index/cycle, which were lost when the previous correction branch was re-cut from main. Tests: 1113 passed, 9 skipped (15 new).
…and one DID is one subject Two more defects where a docstring promised something the code did not do, and the gap flattered us both times. 1. FREE USE WAS COUNTED AS EXPOSURE TO A PAID PRICE. qualified_exposure(store, "deep_preflight") counted free preflight_run events. A free-preflight caller has never been quoted the deep-preflight price, so the engine could reach its denominator on people who were never offered anything and then halve or kill that price. "They used the free thing" is not evidence about a price. There is now an explicit impression boundary. Every 402 / payment-required moment records a canonical `paid_offer_challenged` event carrying `challenged_operation`, recorded identically on HTTP, MCP and A2A through one shared helper per transport so the three cannot drift into measuring different things. Exposure to a paid operation is exactly two things: being shown that operation's price, or completing a PAID call of it (a free-tier call of the same shape is not an impression of the price). Adjacent free products never count. Evidence-bundle and watch experiments get the same boundary. The portfolio view (no operation) is retained for the commercial report and labelled NOT VALID FOR PRICING. 2. THE INDEX PROMISED IDENTITY DEDUPE AND PERFORMED ENDPOINT DEDUPE ONLY. The module documented "endpoint fingerprint FIRST, then declared identity" while ingest keyed solely on endpoint, so one subject at several addresses was several entries - inflating the one number the index is judged on, in a product whose entire claim is not overstating. Declared-DID coalescing now happens at ingest: the canonical entry keeps its endpoint, additional endpoints declaring the same did:key become `alias_endpoints` retaining their own provenance and last observation, and every alias source is also recorded on the canonical entry. Summaries report subjects and endpoints SEPARATELY (total_entries, alias_endpoints_folded, distinct_endpoints_known) so neither can be quoted as the other. reconcile_identities() migrates duplicates that already exist - oldest entry wins as canonical, deterministic and idempotent, run at the start of every cycle and a no-op when there is nothing to merge. OPERATOR equivalence is explicitly NOT inferred. Two endpoints sharing a name, a domain or a contact string are not evidence of one operator, and guessing would launder one party's evidence into another's - a worse error than the one being fixed. Operator stays `unknown` unless a deterministic declared identifier says otherwise, and the public view says so. Also corrects the stale indexops module comment: remote ingest is bounded default-ON for CLEARED_SOURCES only, with GUILD_INDEX_INGEST=0 retained as the one-config-change kill switch. Tests: 1130 passed, 9 skipped (17 new, including "free preflight alone cannot make deep pricing decisive" and "a genuine external deep challenge can").
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Machine-operated ship branch
ship/index-fixes3.The ship workflow dispatches the full
cimatrix, 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.