feat(guard): the build refuses placeholders, fabricated results, boolean literals and hidden errors - #1045
Merged
Conversation
…ean literals and hidden errors Every Rust crate's build script, the Android preBuild and the frontend's start, build, type-check and test scripts run scripts/real_code_guard.py over their own sources. A source line that holds a forbidden token fails the build unless the baseline already records that exact line. Forbidden: the literals true and false and their spellings as constants; placeholder, stub, fake, dummy and mock, TODO/FIXME/HACK and notes that the code does the lesser thing; zero 32-byte values, empty Ok answers, todo!/unimplemented!; every way of hiding an error (unwrap_or*, .ok(), map_err(|_|), Err(_), is_ok/is_err, catch_unwind, an error downgraded to a log line, runCatching/getOrNull, an empty or unbound catch, .catch(() =>, void promises, invented ?? / || defaults, non-fatal / best-effort notes); and every switched-off check (allow, Suppress, ts-ignore, eslint-disable, as any, ignored or skipped tests, testing features, jest test doubles). The baseline holds the 10,211 occurrences that predate the guard and only shrinks: the guard refuses a baseline that gains an entry main does not hold, and a guard that differs from main's. Every run also checks the wiring, so a crate that stops calling the guard, a Gradle task or npm pre-script that goes missing, or a CI job that stops running it fails whichever build still runs. A CI job on every change runs the self-test and the whole tree against main. Verified: self-test 27 rules, 0 failures; whole tree clean against the baseline; a literal true blocks cargo check (dsm_sdk), a literal false blocks the Android preBuild, !0 blocks the frontend type-check and build, .ok(); blocks the storage node, and removing dsm-sphincs's guard call blocks the storage node's build and make lint. make lint passes; the Pico firmware, the anchor library and the hw verifier build through their guarded scripts.
cryptskii
added a commit
that referenced
this pull request
Sep 28, 2026
…ile transfers as a real send does Docker: every Rust crate's build script runs scripts/real_code_guard.py. The storage-node builder image had no python3, so `docker build` of the node has failed on every Rust change since the guard landed (#1045). The builder now installs python3, and the guard runs inside the image as it does everywhere else. CodeQL alert #732 (rust/hard-coded-cryptographic-value): the dispatch tests signed their hostile sender's transfers on nonces written as constants. - The transfer-nonce derivation moves out of process_online_transfer_logic into transfer_nonce(), which the send path now calls. - The tests derive their nonces with it from A's real relationship tip. - They build each transfer as A's send builds one: `to` in Base32, and `recipient` the key A holds. - The "another device" transfer is addressed to A itself, not to an invented id. The mutation controls on the three affected tests (the recipient check, the child-tip bind, and conflicts left to the apply) were run again, and all three are red.
cryptskii
added a commit
that referenced
this pull request
Sep 28, 2026
Main's Docker job has been red since #1045: every crate's build script now runs scripts/real_code_guard.py through python3. - ci/docker/StorageNode.Dockerfile installs python3 (the image copies the whole workspace, so the guard has everything else). - dsm_storage_node/Dockerfile.cloud, the image deploy/push_and_start.sh builds, could not find the guard at all: it copied selected folders and built against stand-ins (fn main(){} crates, invented manifests for tools that no longer exist, empty lib.rs files) behind a cargo build whose failure was thrown away (2>/dev/null || true). Its builder now installs python3, copies the whole workspace as the CI image does, and builds --locked on rust:1.98, the pinned toolchain. The runtime stage is unchanged. Both images build locally and their binaries answer --help. Gemini (gate round 1) was satisfied.
cryptskii
added a commit
that referenced
this pull request
Sep 28, 2026
… ingestion boundary (#1048) * fix(online-transfer): the signed operation is the only authority; one ingestion boundary The recipient recorded a received transfer's amount and token from OnlineTransferRequest fields SIG A does not cover (H-B1), and the proposed refusal of mismatched copies froze a transfer for good: a copy that differed outside the signed bytes staged first, the honest copy was refused, and the send barrier held. The drift behind it: the same fact lived in two places, and transport bytes decided durable state. No unverified storage-supplied field now becomes a durable acceptance, refusal, correlation or liveness dependency. Wire: OnlineTransferRequest keeps SIG A, its canonical operation and the two locator hints; fields 1-4, 6, 7 and 12 are reserved by number and name. ReceiptEvidenceA keeps only the receipt. The Evidence.oracle key the receiver ignored is gone. Recipient: one ingestion boundary (handlers/recipient_dispatch.rs): parse, candidate identity as a hint, verify under the stored key, sender = the contact whose key verified, recipient check, object key, stage, bind by the recomputed child tip. Recognition answers either a verdict about the half or that this device cannot decide (its store or its own id unreadable); only the second is an error. Three identities kept apart: the object (a transfer by its signed operation bytes, a receipt by its commitment), the step ((relationship, parent) and the nonce, decided only by the canonical apply), and the observation (address, observed message id, locator hints: dedup and collection only). Staging (schema 26) holds recognized objects; the barrier reads the verified sender; a copy of an accepted receipt is recognized by its commitment. The pair is accepted inside the apply's transaction and carried forward as the store holds it; the history row, the inbox listing and wallet.history read the signed operation; the credit takes the signed policy commitment. The inbox lists a copy it cannot recognize as unverified, with no sender. Sender: process_online_transfer_logic takes an OnlineSendIntent; the wallet.send app route (called only by the test harness, and taking the sender id from its caller) is deleted; the harness sends through wallet.sendSmart and syncs through the router with the poller's own request. Core: the acceptance bundle's transfer leg carries SIG A and its message; the check of the unsigned field 12 is gone. Published bundles still verify. Tests drive the boundary with what a hostile sender and anyone who can seal to the recipient can put on the spool: a second copy under a lying wrapper, a sender named in a wrapper, junk, a transfer addressed elsewhere, a receipt that does not verify, a rival signed on the same nonce, a wrong locator hint, evidence first, copies of a finished transfer, and the inbox listing. CONFORMANCE_GAPS §6.37 records the pass and what is left open. * test(online-transfer): a forged SIG A is recorded nowhere; every gate has its mutation control The ingestion boundary's SIG A check had no negative test of its own. Junk fails at decode and an unknown sender fails at key lookup, so removing the check turned nothing red. The new test, a_transfer_whose_sig_a_does_not_verify_is_recorded_nowhere, posts the sent request with one signature byte changed. It asserts that the request is not recognized and that nothing is staged. VERIFICATION_MATRIX maps the boundary's eleven gates to their named tests: - SIG A; - the recipient check; - the receipt's sig_a chain; - the child-tip bind; - the object key; - consuming every observed id; - leaving conflicts to the canonical apply; - the barrier's verified sender; - recognizing an accepted receipt; - the inbox's sender; - acceptance inside the apply's transaction. Each named test was observed red with its gate removed or weakened, and the gate was restored afterwards. CONFORMANCE_GAPS §6.37 names the new tests. Under the message pass, it records the transfer-only submission fields that message.send fills with empty values. * ci: the storage-node image runs the real-code guard; tests build hostile transfers as a real send does Docker: every Rust crate's build script runs scripts/real_code_guard.py. The storage-node builder image had no python3, so `docker build` of the node has failed on every Rust change since the guard landed (#1045). The builder now installs python3, and the guard runs inside the image as it does everywhere else. CodeQL alert #732 (rust/hard-coded-cryptographic-value): the dispatch tests signed their hostile sender's transfers on nonces written as constants. - The transfer-nonce derivation moves out of process_online_transfer_logic into transfer_nonce(), which the send path now calls. - The tests derive their nonces with it from A's real relationship tip. - They build each transfer as A's send builds one: `to` in Base32, and `recipient` the key A holds. - The "another device" transfer is addressed to A itself, not to an invented id. The mutation controls on the three affected tests (the recipient check, the child-tip bind, and conflicts left to the apply) were run again, and all three are red. --------- Signed-off-by: Cryptskii <47649969+cryptskii@users.noreply.github.com>
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.
What
The build now refuses placeholders, fabricated results, boolean literals and hidden errors. Nothing waits for GitHub: every Rust crate's build script, the Android
preBuildand the frontend'sstart,build,type-checkandtestscripts runscripts/real_code_guard.pyover their own sources, and a source line holding a forbidden token fails the build unless the baseline already records that exact line.Refused:
trueandfalse, and their spellings as constants (bool::default(),!0,!!1,Boolean(1),1 == 1).TODO/FIXME/HACK; notes that the code does the lesser thing ("for now", "in a real implementation", "simulated", "stand-in").Ok(vec![]),todo!()/unimplemented!().unwrap_or*,.ok(),map_err(|_|),Err(_),is_ok()/is_err(),catch_unwind, an error downgraded to a log line,runCatching/getOrNull, an empty or unboundcatch,.catch(() =>,voidpromises, invented??/||defaults, "non-fatal"/"best-effort" notes.#[allow],@Suppress,@ts-ignore,eslint-disable,as any, ignored or skipped tests,testingfeatures, jest test doubles.No way around it:
scripts/real_code_baseline.txt, 10,211 occurrences that predate the guard) only shrinks. The guard refuses a baseline that gains an entrymaindoes not hold, and--write-baselinecan only remove entries oncemainholds one.main's guard: only the owner changes it.build.rsstops calling the guard (or whoseCargo.tomloverrides its build script), a missing Gradle task or npm pre-script, a CI job or hook that stops running it, fails whichever build still runs the guard.Real-code guard, runs on every change: the self-test and the whole tree againstmain. It is not a required check until branch protection names it.no_fakes_guardholds "fakes"), so it isreal_code_guard.CLAUDE.md (git-ignored, updated in both this checkout and the main one) now states the rule and that violations are penalized with fines.
Verification
true→cargo check -p dsm_sdkexit 101;falsein a Kotlin file →:app:realCodeGuardfailspreBuild;!0in a TS file →npm run type-checkandnpm run buildfail;.ok();→cargo check -p dsm_storage_nodeexit 101;dsm-sphincs's guard call removed → the storage node's build andmake lintfail on the wiring check. Each probe removed; builds clean again.--write-baseline→ still refused.make lint: passed. The Pico firmware, the anchor library, the hw verifier and the guarded-reference tool build through their guarded scripts.