mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-11 05:11:49 +01:00
Gate paced streaming gaps from retained paint timestamps
This commit is contained in:
1 parent
9df002488b
commit
e27b338315
4 files changed
+28
-5
No files matched your search
@@ -350,7 +350,7 @@ Registered v2 browser protocol SHA256: `5498ed8dfc7139285aeda582c540eb572f07a1ad
|
||||
Comparator SHA256: `d8cf6f55339ad811ca1743f4bc73b74afa3a321b93e17ef913fc0339b47b4d7d`. Individual source hashes and
|
||||
H's exact committed revision are retained with each qualification/execution receipt.
|
||||
|
||||
### V2 admission qualification correction, before fresh A/A
|
||||
### V2 admission qualification correction, before fresh browser A/A
|
||||
|
||||
H `96b1a5f1a4497d1389c21b0cc52d55b86641690d` passed the compiled
|
||||
single-run smoke and completed paced 128, burst 16, and ten runs of 128 events.
|
||||
@@ -372,7 +372,7 @@ pg_stat_activity capture exists. The product admission hazard remains separate
|
||||
from this ingestion change; increasing pool size or request timeouts is not
|
||||
part of the experiment.
|
||||
|
||||
Before any fresh A/A, H now schedules each background using the same normal
|
||||
Before any fresh browser A/A, H now schedules each background using the same normal
|
||||
PATCH, then requires that exact participant's provider GET and original-clock
|
||||
hello before scheduling the next. All 100 providers remain live behind the
|
||||
closed common emission gate. A **shared 180-second readiness budget starts
|
||||
@@ -385,8 +385,19 @@ rejects reports without it. Original exceptions, exact activation progress and
|
||||
separate cleanup errors are retained without accepting a cleanup failure.
|
||||
|
||||
Registered corrected browser protocol SHA256:
|
||||
`b955ff1f84d82655e5e1d331b2494cb811f459f44aee0e29205a70636c07dc84`.
|
||||
`5430314c028c9e05ddf4e27e6e22a0191ee0d4a61ffc61649627fd93777acebc`.
|
||||
Comparator SHA256:
|
||||
`55eab8950528a6ec6a30728fb7614b5a9fb7aa210526cb8b7d3237a82db65672`.
|
||||
`c1b7249022a95ff2186e72784247ca83125550c02910d8ad2bf52e1389cf9afc`.
|
||||
The corrected H commit and source hashes are recorded before its full baseline
|
||||
qualification and new browser A/A. Earlier H96b samples never enter that series.
|
||||
|
||||
The original sparse-stream acceptance also requires no regression in gaps between
|
||||
rendered chunks. After terminal drainage, H derives consecutive gaps between
|
||||
distinct observed paint timestamps from the existing retained `visibleMs` values.
|
||||
Reports include paint count, gap count, median gap and maximum observed gap;
|
||||
no tail quantile is inferred from a small gap sample. The comparator requires
|
||||
observed paced-stream gaps and gates the maximum observed gap against the same
|
||||
five-pair A/A noise envelope. This adds the previously missing acceptance check
|
||||
before browser A/A; it changes neither the streaming observer nor emitted work.
|
||||
The independent source-owner A/A may run during local H work because its workload,
|
||||
measurement code and gates remain unchanged.
|
||||
@@ -47,6 +47,10 @@ for (const pair of pairs) for (const arm of ["baseline", "candidate"] as const)
|
||||
assert.equal(result.persistedAfterReload, true);
|
||||
assert.equal(result.matchedVisibleClocks, result.visible?.length, "Every observed marker needs its original provider clock");
|
||||
assert.ok(result.matchedVisibleClocks >= (result.stop ? 3 : result.events), "Missing foreground render/clock observations");
|
||||
if (name === "paced") {
|
||||
assert.ok(result.interChunkGaps?.count >= 1, "Paced streaming needs observed inter-chunk paint gaps");
|
||||
assert.equal(result.interChunkGaps.paintCount, result.interChunkGaps.count + 1);
|
||||
}
|
||||
if (result.prelude) {
|
||||
assert.equal(result.preludeProof?.individualDeltas, result.prelude, "Existing history requires independently stored prelude deltas");
|
||||
assert.equal(result.preludeProof?.uniqueSourceIdentities, result.prelude);
|
||||
@@ -66,6 +70,7 @@ const metric = (item: any, key: string): number => key.split(".").reduce((value,
|
||||
const measurements = names.flatMap(name => {
|
||||
const observed = first.baseline.cases.find((item: any) => item.name === name);
|
||||
const keys = ["firstVisibleAfterEmissionMs", "emissionToVisible.medianMs", "drainThroughTerminalMs",
|
||||
...(name === "paced" ? ["interChunkGaps.maxMs"] : []),
|
||||
...(observed.emissionToVisible.p95Ms === undefined ? [] : ["emissionToVisible.p95Ms", "intendedToVisible.p95Ms"]),
|
||||
...(observed.stop ? ["stopThroughTerminalMs", "stopThroughAcknowledgementMs"] : [])];
|
||||
return keys.map(key => {
|
||||
|
||||
@@ -82,6 +82,7 @@ function browserReport(revision, latency) {
|
||||
epochMs: 1000, preludeProof: workload.prelude ? { individualDeltas: workload.prelude, uniqueSourceIdentities: workload.prelude, verifiedAtMs: 999 } : undefined,
|
||||
visible: Array(workload.stop ? 3 : workload.events).fill({}), matchedVisibleClocks: workload.stop ? 3 : workload.events,
|
||||
firstVisibleAfterEmissionMs: latency, emissionToVisible: { medianMs: latency, p95Ms: latency },
|
||||
interChunkGaps: { paintCount: workload.events, count: workload.events - 1, medianMs: latency, maxMs: latency },
|
||||
intendedToVisible: { p95Ms: latency }, drainThroughTerminalMs: latency,
|
||||
stopThroughTerminalMs: latency, stopThroughAcknowledgementMs: latency,
|
||||
durable: Array.from({ length: workload.runs }, (_, index) => ({ token: String(index), ordered: true,
|
||||
@@ -126,6 +127,7 @@ test("browser CLI rejects the three-pairs-above-noise counterexample and ineligi
|
||||
["unqualified-admission", report => { delete report.admissionProtocol; }, /admission protocol/],
|
||||
["unfinished-cleanup", report => { report.cleanup.complete = false; }, /completed fixture cleanup/],
|
||||
["cleanup-error", report => { report.cleanup.errors.push({ step: "restore", message: "timeout" }); }, /cleanup errors/],
|
||||
["missing-paced-gaps", report => { delete report.cases[0].interChunkGaps; }, /inter-chunk paint gaps/],
|
||||
["unmatched-visible-clock", report => { report.cases[0].matchedVisibleClocks--; }, /original provider clock/],
|
||||
["unmatched-durable-clock", report => { report.cases[0].durable[0].matchedSourceClocks--; }, /original provider clock/],
|
||||
["browser-trace", report => { report.browserRecording.trace = "on"; }, /trace capture off/],
|
||||
|
||||
@@ -331,8 +331,13 @@ test("native ingestion reaches the shipped UI promptly and survives reload", asy
|
||||
return { ...original!, ...marker }; // Keep the original paint timestamp; never restamp after clock arrival.
|
||||
});
|
||||
if (!stop) expect(new Set(visible.map(item => item.index)).size).toBe(workload.events);
|
||||
// Terminal drainage has finished. Derive paint gaps from the retained
|
||||
// observer timestamps without adding work to the streaming observer.
|
||||
const paintTimes = [...new Set(visible.map(item => item.visibleMs))].sort((a, b) => a - b);
|
||||
const { count, medianMs, maxMs } = stats(paintTimes.slice(1).map((at, index) => at - paintTimes[index]));
|
||||
const interChunkGaps = { paintCount: paintTimes.length, count, medianMs, maxMs };
|
||||
const clockEvidence: Array<Record<string, unknown>> = [];
|
||||
const result = { ...workload, stop, nonce, markerCode, epochMs, preludeProof, clockEvidence, runIds: runs.map(run => run.id), participants: participants.length, visible, matchedVisibleClocks: visible.length,
|
||||
const result = { ...workload, stop, nonce, markerCode, epochMs, preludeProof, clockEvidence, interChunkGaps, runIds: runs.map(run => run.id), participants: participants.length, visible, matchedVisibleClocks: visible.length,
|
||||
firstVisibleAfterEmissionMs: visible[0].visibleMs - visible[0].emittedMs,
|
||||
emissionToVisible: stats(visible.map(item => item.visibleMs - item.emittedMs)),
|
||||
intendedToVisible: stats(visible.map(item => item.visibleMs - item.intendedMs)),
|
||||
|
||||
Reference in new issue
Block a user