Skip to content

Helper FT integrity r2: mill v2.6 Clopper-Pearson forward fail-closed - #90

Draft
jcdavis131 wants to merge 64 commits into
mainfrom
cursor/helper-ft-integrity-r2
Draft

jcdavis131 wants to merge 64 commits into
mainfrom
cursor/helper-ft-integrity-r2

Conversation

@jcdavis131

@jcdavis131 jcdavis131 commented Oct 19, 2026 •

Copy link
Copy Markdown
Owner

Draft PR B for the HELPER FT kick gate. Draft, no force-push, not ready. Do not merge.

Head 3bd49ce946851be380a4ad2617c0c97688749443 on cursor/helper-ft-integrity-r2 (PR #90). Confirmed a744cda15ac1c0b2bac3e72eb6537cd0eae91d50 lives only on this branch, not on #89's cursor/leakgate-fixtures-generated.

This turn (merge main / #89)

#89 is merged to main as 09b07651. PR #90 base was already main (not #89's branch); no retarget needed.

Merged origin/main with a normal merge commit efd3cd20166c22f3e24895105e802d3d0693c8db (parents a744cda1 + 09b07651). No conflicts. Follow-up a7129f5b pins the r2-only labeled-data allowlist to main's #89 leak-gate hashes:

  • source.json 8cd184c53874dea20b858dc11fdb30f0193fa8c72744901b4215e8c23718cfe3
  • MANIFEST.json 81209b912e35e7c9850e09a155d25595e76cd3b67051a464a4f92a7f4b9adb56

Stay on mill v1 with v2.6 placeholders. No mill files past v1. No force-push, no rebase.

CODE_PINS (live, this head — unchanged vs a744cda1)

  • kick_helper_ft.py e1eb6bfc5d4972594c1a0c5873b38cd0423a9e861aa83d3b879ed75fc2a4043c
  • helper_ft_kickoff.py b91b4e7d24ef4d4d65ba8c2679ef5a1efc3817f21eff31361257dd68b920f683
  • cam_pin_spec.py 98a0eba8088f8cf4c11ef633795e10898bc90272ff58a28b7bd5db9dcb66920a
  • content_uuid.py fab86b4cbe219c0ca4b25c511e31fc5a7395ccd43d409565ce222a73d084d6e2
  • denied_field_schema.py 4b70478e0a212950e729f80eefb40f95d465911fd7778d7904db7057038b5a1a
  • row_fields.py 6121ad044374c0494a3afb84a7854ae8bba37c5bf810e7e1fe5169470c3026fc
  • neardup_tokens-v1.py 50d5015a051832608391208b7fc3f48259d6e94443213bb46143a06aa2a4f173
  • neardup_tokens-v1.golden.json 69609b85cb779a57f071aabc4a94af300f106ea04617d956135d267454d4b7bc
  • cam_pin_ed25519.pub 052694cbc9dff61398753b5fc474629d5700efea8900cabf5283846b1f5adab2
  • cam_pin_key_id 265df0c50a64e8a522cab9c11454c70d1a167ab20481f5339906038ba2407d88
  • reserved_content_uuids.jsonl bc8926d5a18adf4105372c528fcbcfd32ca898e6235c1701859b837be435163c
  • reserved_near_dup_fingerprints.jsonl 9ce40baf0bbdc30f78a88282a6ab833b3b0adf820315d441f77c9a8e7f16aae5

None of the 12 CODE_PINS shas changed. Factory tests now a4d9ab85fedda20847b158d3b69948c34a7fd9e2e2fb19da85c7421a4f78c18d (changed by the #89 merge, not a CODE_PIN). Mill v1 golden digest unchanged: 5abd1a7b73f7e83869b2184f86df3b1291553c5f97e81ae3565156520ed90e47.

Local apps/dottie-os/tests discover: 431 ran, OK, skipped=58.

S105 (lint-and-test)

uvx ruff@0.15.22 check packages/dottie-loop failed only on HEAD: _inbox_is_latest loop variable token. Renamed to piece in 3bd49ce9. No ruff config change. forge_runner.py is not a CODE_PIN.

dottie-os-smoke (not implemented; Critic)

Job step greps ^OK$. #90 prints OK (skipped=59) on CI. 58 skips are skip-until-vendored mill/critic integrity tests; the 59th is test_numpy_scalars_fold_when_imported (numpy not installed). Options proposed in the agent report; not implemented.

Actions on a7129f5b (pre-S105)

Open in Web Open in Cursor 

cursoragent and others added 5 commits October 19, 2026 04:38
An empty wait (no process, pid, or exit_code) previously counted as
exit 0 MATCH. Unobserved trainer exit is now REFUSED and cannot be
treated as success.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
Booleans were coerced to None and dropped before scoring, so a
one-bit halt vs not column was invisible. Canonicalize True/False
to distinct category tokens and refuse a gold-aligned bool field.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
JSON null is a distinct __null__ category; a field missing from a row
is __absent__. Each column also yields a __present__ feature and each
mapping a __key_count__ feature, so halt-only presence and extra-key
leaks refuse. Synthetic features are not scored against noul.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
A leak confined to the holdout (~33%) was averaged away in the pack
union. Score train, holdout, and pooled independently and refuse if
any slice leaks.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
When PINS.json sits four directories above kick_helper_ft.py, skip
every git lookup, re-hash kick/cam_pin_spec/trust files against the
exact {head, files} map, record head/map/map-sha/file-sha/staged path,
set script_git_sha null with reason pinned-copy, and bind trust/ inside
the copy. Tampered trust bytes and a missing files entry both refuse.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
@vercel

vercel Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
arxiviq Ready Ready Preview Oct 23, 2026 1:47pm UTC
dottie-os-console Ready Ready Preview Oct 23, 2026 1:47pm UTC

Request Review

cursoragent and others added 7 commits October 19, 2026 04:58
Copy pack/train/holdout by reading each file into a buffer, hashing that
buffer, and writing the same bytes into the 0700 run-private dir. The
trainer is given only those copies. Checkpoint evidence is created with
O_EXCL, hashed from the bytes written, and checked by held-fd dev/inode
so HQ completion uses the in-memory status. A 5 MiB same-size rewrite of
the original path cannot change what the trainer reads; a swapper cannot
post MATCH.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
Mill and the kick gate hash the same canonical bytes: state + questions
only, labels/ids/timestamps excluded, NFC strings, sorted keys, compact
`,`/':' separators, UTF-8, sha256. A claimed 64-hex uuid that does not
recompute is forged and refused. Identical content with different labels
is a label conflict listing both row ids; identical content and labels
is reported as a duplicate. Neither case is silently deduped.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
When MANIFEST.reserved_eval_partition records n and k (no passing
default), training rows with sha256(uuid) mod n == k are refused.
Rows whose content uuid is in content_shas are refused. A row needs
source.uuid or a content uuid the gate recomputes; missing both
refuses. Clean twins outside the slice pass.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
If the completion event fails to post after a MATCH write, rewrite the
0400 evidence to REFUSED with reason hq_post_failed. Kick refuses and
never treats the run as MATCH or verified.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
Capture stdout around start_training, re-print it, and record
stdout_spoof/scorable on the held-fd evidence. A forged
INTEGRITY_EVIDENCE line cannot change hashes or result; smoke
stays unscorable.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
Tracked leakgate source.json and MANIFEST.json must match frozen
sha256 pins. An extra curated_pack jsonl or an edited allowlisted
file refuses. CI workflow wiring stays a separate Cam commit.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
Smoke assigns ckpt-{run_id} and deletes a forged ckpt-real instead of
using the launcher name or a runs/smoke alias. latest is refused as a
path component or _/- token, including /tmp/latest and pack_latest.
FORGE_ENTRYPOINT_PINS require exact repo-relative paths plus trust
files, and FORGE_PINS_SOURCE_COMMIT must equal git head when present.
Pinned-copy tests bind the real #85 head. The leak gate scores
non-user message roles, pairwise XOR/concat of binary fields, and
unique-id residues after stripping unique affixes.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
@cursor cursor Bot changed the title Helper FT integrity r2: unobserved exit, leak-gate slices, pinned-copy Helper FT integrity r2: label-conflict uuid, leak extras, smoke ckpt Oct 19, 2026
@cursor
cursor Bot changed the base branch from cursor/leakgate-fixtures-generated to main October 19, 2026 05:15
cursoragent and others added 4 commits October 19, 2026 05:21
Never treat source.uuid as a content uuid, even when it is 64 hex.
The no-uuid reserved-partition rule is satisfied by a verified
source.content_uuid. A 64-hex dataset id must MATCH; a forged
source.content_uuid must refuse.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
Canonical JSON uses allow_nan=False and walks state/questions for
non-finite floats (type is float, so bools are not coerced). json.dumps
renders 1 and 1.0 as different bytes; true/false never collapse with 0/1.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
Only top-level field selection (state + questions) is allowed. Nested
id/timestamp stay in the hash; a nested id change must alter the uuid.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
A duplicate spanning train and holdout is content_uuid.cross_split_duplicate,
not content_uuid.duplicate (within one split) and not
content_uuid.label_conflict (same content, different labels).

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
@cursor cursor Bot changed the title Helper FT integrity r2: label-conflict uuid, leak extras, smoke ckpt Helper FT integrity r2: content-uuid critic rulings Oct 19, 2026
Recursively coerce finite f.is_integer() floats to int(f) before hashing
(1.0 → 1, -0.0 → 0). Check type is bool first so True/False stay distinct
from 1/0. NaN and ±Infinity still refuse.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
cursoragent and others added 2 commits October 19, 2026 05:42
N is int(sha256(source.uuid.encode()).hexdigest(), 16) % 10 in {0, 5}.
The modulus and residues live in RESERVED_EVAL_PARTITION; a pack MANIFEST
may add residues or content shas but cannot remove them or change n.
A pinned reserved-content-uuid list (--reserved-content-uuids plus sha256)
is required. Uuid-less rows refuse as uuid_missing unless source.hf is
openbmb/UltraData-Math; those still need a verified content_uuid.
Hash the raw source.uuid with no strip. Distinct reasons: uuid_mod vs
content_uuid.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
Cover fail-open (omitted MANIFEST still refuses 0 and 5), MANIFEST
override attempts, safe residues 1-4/6-9, content-uuid denylist with a
different source.uuid, uuid-less allowlist vs uuid_missing, missing and
mismatched reserved-list pins, whitespace-malformed uuid, and a
cross-check of Mill's sha256-mod-10 formula.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
Fail-closed schema check on fields the v1 near-dup extractor never
reads. N/free text in those fields refuses the row; a valid row keeps
labels and questions intact in trainer_input. Unknown state.meta keys
refuse. CODE_PINS includes denied_field_schema.py; mill v1 stays pinned.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
@cursor cursor Bot changed the title Helper FT integrity r2: mill tokenizer v2 pin Helper FT integrity r2: denied-field schema gate (v1 pin) Oct 19, 2026
One CODE_PINS module owns readable scan paths and the deny list. The
near-dup gate and trainer both import it. Trainer input is those fields'
original UTF-8 bytes plus schema-passed denied fields, never mill
normalize or message_text.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
@cursor cursor Bot changed the title Helper FT integrity r2: denied-field schema gate (v1 pin) Helper FT integrity r2: row_fields + raw trainer bytes Oct 19, 2026
Mill tokenizer v2.2 will own field paths, DENY_KEYS, and denied-field
schema via extract_paths/check_denied. row_fields.py is only an import
seam: until v2.2 is vendored after Critic GO, extract_paths, check_denied,
trainer input, and gate tokenize refuse. v1 stays pinned for live near-dup.
Contract tests skip until vendored.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
@cursor cursor Bot changed the title Helper FT integrity r2: row_fields + raw trainer bytes Helper FT integrity r2: mill v2.2 extract_paths fail-closed seam Oct 19, 2026
Build Critic's NO_TEXT, keyed-hasher, short-ref, nchar-leak, and
trainer-allowlist checks behind the fail-closed mill v2.2 seam.
Keep v1 pinned; do not vendor v2.1 or v2.2. Pin Critic's v2.1 suite
byte-identical and skip it until neardup_tokens-v2_1 is vendored.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
@cursor cursor Bot changed the title Helper FT integrity r2: mill v2.2 extract_paths fail-closed seam Helper FT integrity r2: v2.2 seam for NO_TEXT, hasher, fingerprints Oct 19, 2026
Replace the public |B|<16 load check. Once mill v2.2 is live, N sets
are bucket-padded; the keyed loader drops dummy tags and refuses real
|B|<16. Signed v2 pins must carry matching min-ref and bucket fields.
v1 stays pinned; dummy derivation is mill's, not the gate's.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
cursoragent and others added 11 commits October 19, 2026 11:44
v2.2 path round-trips replace byte spans. Trainer input reads only
via mill get_by_path on extract_paths. check_denied raises
DeniedFieldError. CAP, SAMPLE_MARGIN, and BUCKETS come from mill.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
Stay on mill v1. Gate refuses a fingerprint file on duplicate or gapped
indexes, n != signed |N|, missing/wrong mill KCV before any reference,
or a mill index-binding failure. Never load a partial file; never log
KCV, key, or computed value.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
S-MULTI-I uses signed n_refs, not |N|. Refuse missing n_refs /
n_refused_short / candidate count, n != n_refs, header n mismatch, and
n_refs + n_refused_short != candidates. Call mill load_fingerprint_file
when ready; keep KCV, rec_mac, stoplist_sha, strict-dummy, and
Clopper-Pearson forward backstops. Stay on mill v1.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
Refuse unless signed n_refs + n_refused_short equals mill's candidate-count
field. Missing n_refused_short or candidate count refuses. Mill skip tests
cover valid, n != n_refs, sum mismatch, and missing fields.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
Keep rec_mac index-binding, unbound real tags, index-bound mill dummies,
KCV, file MAC, n_refs identity, and strict-bucket refuse for non-CAP
zero-dummy sets. Stay on mill v1 until Critic GO.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
Keep v2.4 rec_mac / KCV / file MAC / strict-dummy / n_refs identity.
Forward containment uses no stoplist. Reverse-only stoplist is pinned
by STOPLIST_SHA256 placeholders; below-floor reverse hits are report-only.
Stay on mill v1 until Critic GO.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
CAP=1024 and mill BUCKETS through 1024. Fixed 0.43 forward threshold.
Forward fail-closed below 64 effective tags as
forward_sample_too_small_refused. Strict-dummy at the 1024 bucket.
Reverse stoplist/floor unchanged. Stay on mill v1 until Critic GO.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
Below 64 effective tags, refuse only if the 99% CP upper bound on
hits/effective is >= 0.5. Fewer than 7 tags always refuses. Zero hits
with 7 or more clears. Count refusals as forward_sample_too_small_refused.
Stay on mill v1 until Critic GO.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
Bring in merged #89 leak-gate fixtures. No conflicts. Stay on mill v1
with v2.6 placeholders.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
Keep main's merged leak-gate source.json and MANIFEST.json. The r2-only
guard still pinned pre-#89 shas. Stay on mill v1 with v2.6 placeholders.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>
#90 added _inbox_is_latest; the loop variable was named token, which
ruff S105 treats as a password. It is a path-component fragment, not a
secret. Same uvx ruff@0.15.22 check packages/dottie-loop is clean on
main and now on HEAD. No ruff config change.

Co-authored-by: Cam Davis <jcdavis131@gmail.com>

This branch was successfully deployed

2 active deployments
Preview – dottie-os-console — 3bd49ce9 Deployed Oct 23, 2026 by vercel[bot]
Preview – arxiviq — 3bd49ce9 Deployed Oct 23, 2026 by vercel[bot]
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.

2 participants