Skip to content

October 2026

Exact match earns its registration: the quieter metrics lose more signal than noise

The sensitivity analysis puts the design's resolution at about two exact-match points, which is where the observed effects are, so the obvious lever is a less noisy outcome. Exact match is binary and maximally variable; the run already records a normalised exact match and an edit similarity. Read over the three seeds under the crossed interval, on the same clusters:

Mixed rounds, and a detector that was reading its own reference

Extends the entry above to the deployment question: not "was this named client in the round" with the other participants drawn from other organizations, but "did this organization take part" with the round drawn from every client. The organization's clients are split once into the attacker's reference and the participants it may contribute, so no round is scored against itself.

Secure aggregation does not hide which source was in the round

sphragis/measure/aggregate.py, scripts/aggregate_attack.py, datasets/results/aggregate-attack.json. The per-client attack assumes the server sees each update; secure aggregation shows it only the round's mean, which is what a federated deployment would claim as its protection. Both detectors below are what an honest-but-curious server could run with reference updates of its own, computed exactly from the Gram matrix adapter_geometry already recorded, without touching the weights.

Organization beyond project, tested with the project as the unit

The client-level permutation treated clients as exchangeable, and clients share their project. The honest test leaves each client's own project out of every class mean, so an organization has to be recognised from its other projects, and permutes organization labels across projects, not clients (attribution.group_permutation_p, exact over all distinct relabelings when few enough). On the 34 clients of job 148513:

Review of the RQ2 and power code: one packing flaw, four small ones

Commits 38936f3 to 405462b reviewed, every finding reproduced and fixed. The one that touches a result: clients.partition could get stuck behind a client no remaining change completed, losing every client after it, so client counts depended on the shuffle. The executed run (148513) was affected in count only, its clients disjoint and exactly sized: starlingx/docs gave 4 where 5 are possible. The packer is now first-fit decreasing over open clients, which reaches the maximum for every corpus but starlingx/docs (5 of 6, where very large changes cannot pack exactly). The next client run, with AOSP added, uses it. The others: a skipped micro-batch now stops a client as a skipped step does, since it leaves the client short; conjunctive_power refuses a seed effect with one seed instead of recording one it did not simulate; seed_effect no longer crashes on a pair with no noise; adapter geometry skips the zero-norm initial state.

AOSP as RQ2's third organization, and why it can only ever be RQ2's

To separate an organization from its codebase family, RQ2 needs several projects per organization in one shared language on both sides. Qt's C++ libraries have that; a second organization with several C++ projects on public Gerrit supplies the other side. AOSP (android-review.googlesource.com) does: seven C++-dominant projects (art, system/core, bionic, frameworks/native, frameworks/av, external/perfetto, system/netd), about 40% of merged changes carrying inline comments in a sample of thirty. It answers residential addresses and refuses datacenter ranges, so it is fetched from a workstation, and fetch --project bounds it and records the restricted query in the snapshot.

RQ2's first result: a client's update reveals its organization, within a language too

Corrected the same day, and again with a third organization. The interpretation below overreaches: per project there is no organization pull beyond the codebase family, and once a content type is carried by two organizations at several projects each, organization is not attributable at all (0.416 against a 0.506 majority). See "What the client updates identify is the codebase family" and "The organization is not in the update" below. The numbers stand; the organizational reading does not.

What an adapter update's direction reveals: initialization first, training length second, source barely

datasets/results/adapter-geometry-s1.json, scripts/adapter_geometry.py. RQ2's per-client question in its simplest form: is a LoRA update's direction in weight space closer to updates from its own organization? The cosine between two updates dW = (alpha / r) B A, for every pair of the 35 saved adapters and all 196 adapted modules, computed through r x r traces without forming dW. Run from a worktree pinned at e23b905 so the queued jobs' checkout was untouched; CPU only, three minutes. Weight-space provenance is established for the training objective (Paul, arXiv:2604.08844, AUC 1.00 from spectral features), which names "organic drift from distributional shift", the same objective on different data, as untested. This is that case.

An interval that spans the seeds: built, reviewed, and its coverage measured

sphragis/measure/stats.py crossed_bootstrap, sphragis/experiment/walk.py crossed_gate. Seeds and changes are crossed, every seed scoring every change, so the interval is Owen's pigeonhole bootstrap (Ann. Appl. Stat., 2007): one draw of seeds and one of changes, independent and with replacement, the statistic over their intersection. A nested bootstrap (changes, then runs within each) would treat a seed's shift as independent per change and average it away; an industry comparison of that nested form found it very conservative, 98 to 99% coverage against 95 (Indeed Engineering, July 2026). Built beside the registered gate, not registered.