PSDP — verification record and withdrawal ledger

This page holds the primary material split out of the PSDP product page: the pre-release testing carried out on 2026-08-17–18, an independent audit by a separate engine, the claims of ours that did not survive it, and the corrections that followed. The product page carries only what passed.

The purpose of this page is to keep the records that are inconvenient for us. Withdrawn claims are left struck through, with when and by what they fell. A product that sells "it does not break" cannot go quiet when its own claims break.

1. Withdrawn claims withdrawn

On 2026-08-17 an independent audit (a consistency audit by a separate AI engine) raised findings, and we reproduced every one of them ourselves. All of them reproduced. The measured values and digests themselves held up (no sign of fabrication). What fell apart were the generalizations and the checker.

Claim withdrawnWhy it fell (reproduced)
Sealed measurement records can serve as the basis for success-fee billing They cannot. verify never compared the record_sha256 that build had written. Build ba2f77d1… against verify 4c202cca… still returned VALID. Chained prev_hash checking, Ed25519 signature verification, duplicate-key rejection, required-value and type-range checks were all unimplemented. The hash was decoration and proved nothing. (Fixed — see §3)
Zero false-safe verdicts (saying "commutative" when it breaks) It fell. Two counterexamples — (1) FROM sales JOIN lines … ORDER BY sales.id was marked [OK] even though the primary key repeats after the join; (2) ORDER BY u on u INT UNIQUE was marked [OK] even though PostgreSQL permits multiple NULLs. Causes: only the first table in the FROM clause was examined (joins were not recognized), and UNIQUE was not checked for NOT NULL.
f64 addition is associative if the values are integral and the total is within 253 False. Counterexample a=253, b=1, c=-253 gives (a+b)+c = 0 but a+(b+c) = 1.
Correction: every value integral and every partial sum within 253 in absolute value, under any split order. For non-negative inputs the total-sum bound suffices, but money carries negative values from refunds, discounts and credit notes, so the advice "hold money as integers in minor units and you can parallelize the SUM" was also stopped as unsafe for accounting with offsets.
Incorrect partitioning does not go faster / half the cases get slower Wrong. Recounting our own table, 4 of 5 cases were "faster but broken" (numerics 6.11× / image dithering 5.47× / spreadsheet 2.05× / RDB violation arm; only TCP packet splitting was slower at 0.43×). The correct statement is "incorrect partitioning is more often faster — which is exactly why the temptation is strong and a checker is needed".
BigDecimal.add is associative Needs qualification. Only the unbounded-precision exact add. The MathContext overload rounds at each step and is non-associative (MathContext(3), a=1.00, b=0.006, c=0.006 gives 1.02 vs 1.01).
The checker verifies that code is safe Refuted by a second audit. In substance it was "grep with opinions". Fed a .sql file containing three ORDER BY clauses it reported "0 sites / 0 dangerous / 0 undecided, exit code 0" — the same output as for an empty file, so CI passes straight through. The analysis logic was fail-closed inside, but the entry point was fail-open.

Of the seven accumulated stop conditions, three were fail-open. We had declared "fail-closed is the line this product holds" while the implementation was, in fact, fail-open. The current accepted standing is: not usable for automatic remediation, safety certification or success-fee determination; usable, conditionally, only as a search aid that a human re-checks.

1-b. ★★ How to read "zero false acceptances" correctly

The old entry point was effectively a dedicated signature: compute(seed) → a 2-D float array. Across 102,750 real Python functions, exactly 0 matched. Everything was rejected on shape before semantic judgment was ever reached.

So "only the official fixtures pass" is a consequence of those fixtures being convention-conforming kernels — it does not mean "dangerous code was rejected on semantic grounds". ★ Zero false acceptances must not be read as safety on general code.

What the wild-code testing directly supportsStatus
Under the old signature admission, reach into real-world code was essentially zeroestablished
Bit-exactness holds for convention-conforming kernels (0xe718490618e7f144 agreeing across 6 languages)established
A general semantic admission layer is still to be builtnot started

★★ The single principle that unifies those three is the central contract on the product page:

"PSDP parallelizes only the regions whose semantic equivalence can be proven. Regions that cannot be proven keep their original sequential execution."

Under that one sentence, the 4 cases we did not parallelize, the decision to admit HNSW only by freezing the artifact, the bit-exact evidence, and the pivot to semantic admission all line up as consequences of the same product principle. Where we stand today is that "provable regions" still means the inside of the convention.

2. How previously published figures are handled awaiting primary records

For the figures below, the 2026-08-17 testing could not locate primary records (bench output, logs, CSV). That is not proof they do not exist — only that they did not turn up within the scope searched. They are off the product page until records appear.

Previously publishedCurrent standing
2.97–4.23× (matrix multiply N=700) Re-measured. At 200,000 tasks of fixed total work on 20 cores: Go 4.05× / C# 2.81×. Both the magnitude and the ordering (Go > C#) hold — the claim was not inflated. But the sample differs: the converters bundle only N=16 of matmul (all 22 converters surveyed), and no primary record for N=700 was found. The product page now carries the measured values with their conditions.
90 / 90 fault-injection rollbacksNo primary record found. Publication stopped.
TPC-H Q1 / Q6 4.38–5.20×No primary record found. Publication stopped.
CDC replay 4.26× The 2026-08-17 measurement showed it getting slower (0.46–1.00×), dominated by epoch construction cost. Publication stopped, and recorded as "does not work".
SQLite WAL reader 9.76×No primary record found. Publication stopped.
AVX-512 3072 / 3072 bit-exact PASSNo primary record found. Publication stopped. Separately, generalizing the AVX-512 result of 0.93–1.04× (memory-bound) to numerical computing as a whole was an error.
1,900–3,800× versus PostgreSQL with SlimeTree-VSAM integration A projection we had explicitly labelled as synthesized, but its inputs were the 2.97–4.23× figures above (matrix multiply only). Publication stopped.
Reads bytecode at build time to find parallelizable sites and "injects" a parallel version No implementation of this mechanism was found by full-text search. In substance it is a wrapper generator around kernels written to a compute(seed) convention. Publication stopped.
Bit-exact parallelization of FFT / Conv2D / LU decomposition No such samples exist. Publication stopped (they remain candidate applications).
I/O bound — "PSDP parallelizes computation, so it does not shorten waiting. Out of scope for PSDP" ★★ Refuted by our own measurements. Work dominated by waiting is where the largest speedups appear — real TCP 16.88× (the largest across four domains), round-trip-latency bound 8.57×, pages with N+1 5.95×. Moreover CPU use drops to 0.63–0.71× (the threads merely block and do not consume CPU). Databases in practice answer from cache far more often than assumed, which makes parallelism apply cleanly. What is genuinely out of scope is only pure I/O saturating device bandwidth; the old wording invited the false generalization "I/O = slow = nothing can be done". Publication stopped.
★ That said, parallelizing waits increases connection occupancy (conn-ms) (6.34 → 8.47), so for N+1 collapsing into one query is a fifteenth (0.42 conn-ms). Choosing the lever is itself part of the judgment.
378 / 378 bit-exact Real, and reproduced (golden d2fc575a50086c6f). But Track A states its own execution model as sequential in topological (phase) order, and the generated artifacts contain no threads at all. It is evidence of determinism, not of parallel performance. The product page keeps it in a block separate from speed.

3. History of the checker — every fix created a new defect

The analyzer is implemented in Rust. What follows is the record of the defects we built into it.

The v1 accidentThe default verdict was "commutative" — fail-open, so on a plain JDBC batch of the shape customers actually write, 2 of 7 loops were misjudged. In particular customerNet.merge(cust, net[i], Double::sum) was answered "safe to parallelize as-is". Measured, that gives bit-level disagreement on 471/512 customers, and 478/512 disagreement even between run 1 and run 2 — per-customer revenue taking a different value every night.
v2 changes(1) default becomes undecided = do not parallelize (fail-closed); (2) merge / put / compute into a shared collection is non-commutative when the folded value is floating point; (3) JDBC objects are non-commutative; (4) writes to a local array indexed by the loop variable are unconditionally commutative; (5) local collections are conditional.
v3 (BigDecimal)Folding with BigDecimal.add is associative in both value and scale (scale = max is associative), so it parallelizes bit-exact. The same aggregation disagreed on 471/512 with double and 0/512 with BigDecimal, at 4.38×.
★ But ADD…ROUNDED (a setScale inside the fold) is non-commutative: HALF_EVEN was measured off by 0.01. HALF_UP agreed, but only by luck.
★★ The split is not "is there rounding" but "is the rounding inside the fold".
Defects created
while fixing (record)
(1) Closing the JOIN / nullable-UNIQUE holes created three new false-safe cases (list.add / sb.append / break all marked OK)
(2) Closing those mistook Math.floor() for an external effect and demoted genuine danger verdicts to undecided
(3) Adding a pure-function exemption was written with the branch wrong and had no effect
(4) Arrays and Collections were on the PURE exemption list, so Arrays.fill came out [OK]
(5) Type resolution overwrote in list order, so an int total in another method beat a double total
(6) Root cause: only the recv.method( form was examined, so unqualified calls such as helper(x) were entirely invisible. That single hole explained most of the findings.
CurrentThe fixed version leans towards demoting to undecided unless it can be shown. Across 601 pgjdbc files: v1 gave OK 47 (1 false warning, 0 unchecked = fail-open); now OK 4 / dangerous 0 / undecided 72 / explicitly unchecked 568. Safe, but whether it is useful is a separate question, and that question is unresolved.
Not yet addressedStill regex-based (replacement with a real parser is a condition of productization); inline while(rs.next()) and the Stream API are unsupported; prev_hash chaining is checked only for format; digests have not been re-measured on different CPUs or operating systems.

4. Evaluation design — we do not discuss performance outside this table

Following the audit's proposal we adopted a 2 × 3 table. With three values, the cell where a real defect lands in [OK] (a false-safe verdict) drops out of view.

Established by execution \ verdictDangerousUndecidedOK
Order dependence presenttrue positivemissed by abstention★ false-safe verdict
Order dependence not establishedcandidate false positiveabstentioncandidate true negative
  • Abstention and a false-safe verdict do not weigh the same. An abstention still gets human eyes on it; an OK ships because nobody looks. The false-safe verdict is a standalone stop condition and is never folded into a weighted average.
  • Asymmetry: change the order and see a difference, and order dependence is demonstrated. See no difference, and nothing is proven safe. Hence row 2 reads "not established", not "order independent".
  • Of the means of changing order, those actually measured are: physical movement via UPDATE, swapping the engine, and changing the degree of parallelism. Fetch size and input distribution are not yet done. A means that produced no difference is recorded as "no difference by that means", not as "safe".
  • The unit of a label is (code, input, execution conditions, observation contract). Collapsing it to the code alone reproduces "it was green before the update".

Record of getting the evaluation frame wrong three times: (1) using coverage (the share of OK verdicts) as the measure of product value; (2) treating abstention as harmless because "it merely does not report"; (3) nearly publishing a "6% recall" figure from labels we had assigned ourselves. A self-serving frame and a self-punishing frame are equally void; the moment we assign the ground truth ourselves, the number is dead. The 2×3 table was adopted because its ground truth comes from execution, which structurally removes the freedom to choose the frame.

We also read 0 as a good number without checking the denominator three times, and borrowed the precision denominator for a false-positive rate once. For example, "0 false warnings across 601 pgjdbc files" is not an achievement — there were 0 danger verdicts at all, so the denominator is 0 and the metric is undefined. The correct phrasing is: "0 danger verdicts; therefore no false positives were observed either, but the false-warning rate cannot be evaluated".

5. The observation contract — the fourth dimension of a label

We ran a real Common Lisp accounting package (cl-ledger, commit b0174f56 / SBCL) over all six permutations of the same three journal entries.

What was observedResult across the six permutations
Final trial balanceidentical, 6 / 6
Running balancedifferent, 6 / 6

Same code, same input, same environment — and the label inverts. The unit of a ground-truth label is therefore (code, input, execution conditions, observation contract), and a "bit-exact" claim with no stated observation contract is void.
This had already happened in our own measurements: the ORDER BY defect produced different line items with a completely identical total (3,238,609.2700000014). Observing only the total, we would not have caught it. We noticed it and wrote it down, but failed to generalize it.

6. Measurements by domain (2026-08-17–18)

Domain / sampleMeasuredHow to read it
Matrix multiply / image convolution / spreadsheet / real TCP (Rust, std only) 6.67× / 6.30× / 5.35× / 16.88× On a correct split axis the digest dfcf3fee29d7d15c is fixed at every thread count 1–20; the violating version returns a different value at every thread count. ★ The correct axis differs entirely by domain (rows / phase / connection / id range), so the wider the domain coverage, the more the checker has to be built out.
RDB nightly batch (PostgreSQL 16.14 real server and 4 others) 3.26–5.81× with fetch splitting Bit-exactness was 20/20 complete (every violation arm broke). The bound is fetch — parallelizing only the application side gives 1.05× overall. It starts paying from about 500k rows.
E-commerce order batch (tax / coupon / points / truncation) 2.98–4.54× (bit-exact on 5 engines) The violation arm reaches 6.09× while changing the low-order bits of the tax (…767999999E8…768000002E8).
E-commerce online (order-history N+1) 5.95× at 50 orders / 5.29× at 200 CPU use drops to 0.63–0.71× (parallelizing waits only blocks threads). ★ But conn-ms rises from 6.34 to 8.47, while collapsing into one query gives 0.42 conn-ms — a fifteenth. Parallelism is the wrong tool for this particular problem.
Load test (shared pool of 16) crossover at 8–16 concurrent Parallel wins decisively from 1 to 8 concurrent (3.3× latency / 3.5× throughput); sequential wins decisively from 16 up. ★ The naive implementation deadlocks (borrowing connections one at a time stalls at 8 concurrent). All-or-nothing acquisition via Semaphore.acquire(n) resolves it.
Contention (real PostgreSQL / C# Npgsql) single account 0.96× / optimistic locking 0.10× Done correctly it is 10.2× slower than sequential, and 87.6× apart from the broken version. The version that loses 93% of updates is fast because it discards 93% of the work. ★ Optimistic locking is the wrong tool for contended rows: row locking / serialization is 9.9× faster and also correct.
Ingestion bound (cl-ledger, 500k entries) trial balance 1.06× 5.208s cold against 0.308s warm — 94.1% is loading and binder construction. Parallelizing the aggregation on infinite cores does not help. The pitch is parallelizing ingestion, not aggregation — but that cannot be done without touching the source.
RAG ranking (Haystack 2.31.0) 24 tied documents → 100 distinct top-5s Not a defect in Haystack but an undecided tie-break: from 24 tied documents there are 5,100,480 equally valid ordered top-5s. ★ A secondary sort on ID makes it deterministic at essentially zero cost — the only "free correctness" we found (the f64 balance needs a type change; contended rows cost 10.2×).

7. There are four kinds of bound

CPU (ingestion) bound1.06× — parallelizing the aggregation does not help
Fetch bound3.26–5.81× — works, but the fetch itself must be rewritten
Round-trip latency bound8.57× — the strongest effect
★ Contention bound1.00× — does not work. This is what accounting systems actually have (control accounts, inventory, number allocation)

The conditions under which 8.57× appears (no contention) are not the conditions of the real system (contention). Rough applicability rule: computation under 20% of the total → out of scope; 20–50% → conditional if money is integral or BigDecimal; over 50% → a candidate. Additionally, double-denominated money with a running balance in the observation contract is out of scope, as is anything memory bound.

8. What has not been verified unverified

  • ★★ There are zero measurements of anything getting faster with the source unchanged. Every published speedup was measured with the parallel execution path implemented by us (via ExecutorService and similar). The correct standing is "the ceiling if the conversion tool worked perfectly" — and neither the implementation nor the measurement exists (unresolved).
  • The checker's detection performance is unmeasured. There are only 3 safe control cases, and a denominator of 3 cannot support a performance claim.
  • Anomalies between transactions (lost updates, deadlocks, isolation levels) are structurally out of scope. Claiming "passing the checker means it is safe to adopt" without stating that range does the same harm as a false-safe verdict.
  • All per-language options (SlimeJava2Java / SlimeCSharp2CSharp / SlimeGo2Go / SlimeRust2Rust and the rest) are unimplemented. The next task is the Go / No-Go samples (a BigDecimal running balance and one e-commerce batch); SlimeJava2Java is the top priority because there are zero speedup measurements for Java.
  • Of the two-stage guarantee (front = bit-exact within one language / rear = full agreement across parallelism, thread count, DB engine and language), the rear stage has its measurements (0xe718490618e7f144 / dfcf3fee29d7d15c / bit-identical on 5 DB engines). What is unimplemented is producing the front stage by automatic conversion.
  • Digests have not been re-measured on a different CPU or operating system (the design premise is that digests should agree across machines while wall-clock times will not).
  • The search for primary records covered the SlimeNENC tree and the site backups only. Other drives were not searched, so "not found" in §2 is not proof of non-existence.

9. Measurement conditions (for reproduction)

DB enginesPostgreSQL 16.14 (real server) / H2 / HSQLDB 2.7.3 / SQLite / Derby
Implementation languagesRust (standard library only) / Java / C# (.NET 8) / Go 1.22
Speed measurement ruleFix the total work and vary only the degree of parallelism (200,000 tasks fixed, 20 cores). An implementation where thread = task cannot vary thread count at fixed total work, so its speed cannot be measured.
Traps (measured)H2 caches query results (941ms cold, 0.3ms warm). Best-of-N makes it look 3,000× faster. We always publish the cold figure too.
★ Measurements on localhost PostgreSQL (RTT ≈ 0.05ms) substantially understate waiting; in production every round trip carries RTT.
★ When comparing against another site's TTFB, an HTTP 202 with size 0 is a bot short-circuit and is not page generation time.
Negative controlsEvery measurement includes an arm that violates the judgment. A measurement counts as valid only once we have confirmed that the violating arm breaks.

← Back to the PSDP product page