Skip to content

P2p: mapping inputs reach the CLI as temporary files (#6), and release 0.1.1 - #7

Merged
npstorey merged 4 commits into
mainfrom
ts135/p2p-stdin
Oct 5, 2026
Merged

npstorey merged 4 commits into
mainfrom
ts135/p2p-stdin

Conversation

@npstorey

@npstorey npstorey commented Oct 5, 2026

Copy link
Copy Markdown
Owner

PRODUCE-PY P2p: mapping inputs reach the CLI as temporary files, and release 0.1.1

Part of npstorey/typedstandards#135. G0 record: 5985856524, cards D14 = A and D17 = A. Fixes #6.

Head: 19eb4544de67ad3dda92def86fb153018118bfc4. Base: main 7513583.

Why

0.1.0's verify removes a served bundle's top-level trustRegistry (D9, npstorey/typedstandards#136)
and sends the result to the CLI on standard input. CLI 0.2.0 reads --input - with
readFileSync(0), which fails with EAGAIN once the document is larger than a pipe buffer holds
(npstorey/typedstandards#138). So any served bundle above that size failed with UsageError
(exit 2). A bundle that signs a notebook inline is above it. The same applied to any large mapping
given to sign, withdraw or attest.

Commits

Commit What By
7c1d8f0 tests only: the red. src/ is identical to 7513583 impl (Opus 5.5)
b956475 the fix: a mapping input is written to a temporary file, removed when the call returns or raises; run always gives the child stdin=DEVNULL; README transport sentences; CHANGELOG entry impl (Opus 5.5)
cb7ca9a CLAUDE.md: names scripts/publish.sh and its modes; says who pushes the rollback tags; says a branch that changes .gitleaks.toml is pushed from its own worktree (D17) ORCH
19eb454 Release 0.1.1: __version__ 0.1.1, CHANGELOG dated 2026-10-05 (the publish day the owner named); uv.lock unchanged (the version is dynamic) ORCH
$ git diff --numstat main...19eb454
8	0	CHANGELOG.md
11	3	CLAUDE.md
5	3	README.md
1	1	src/typedstandards/__init__.py
8	6	src/typedstandards/_cli.py
38	29	src/typedstandards/_commands.py
24	2	tests/conftest.py
6	3	tests/test_commands.py
12	2	tests/test_d9.py
2	0	tests/test_guards.py
171	0	tests/test_large_inputs.py

Blast zone: _commands.py, _cli.py, tests/, the README's transport sentences, CHANGELOG.md,
CLAUDE.md and __version__. uv.lock, .github/, scripts/, package*.json, the vendored
CLI and tests/fixtures/ are untouched.

Acceptance: red, then green

Red at 7c1d8f0. Driven by the impl and reproduced by the ORCH in a separate worktree on macOS,
Node 24.21.0, Python 3.12. The impl also reproduced it in a Debian bookworm container on Node
24.21.0. Result: 8 failed, 4 passed. Every failure is at the EAGAIN error or at its assertion:

E   typedstandards.errors.UsageError: typedstandards verify exited 2: typedstandards verify: --input - cannot be read: EAGAIN: resource temporarily unavailable, read
E   typedstandards.errors.UsageError: typedstandards sign exited 2: typedstandards sign: --input - cannot be read: EAGAIN: resource temporarily unavailable, read
E   AssertionError: the document reached the CLI on standard input
FAILED tests/test_large_inputs.py::test_verify_a_large_served_bundle_as_a_mapping
FAILED tests/test_large_inputs.py::test_verify_a_large_served_bundle_as_a_path
FAILED tests/test_large_inputs.py::test_sign_from_a_large_input_mapping
FAILED tests/test_large_inputs.py::test_no_mapping_input_reaches_the_cli_on_a_pipe
FAILED tests/test_large_inputs.py::test_temporary_files_are_removed_when_the_cli_fails
FAILED tests/test_d9.py::test_verify_drops_only_trust_registry
FAILED tests/test_d9.py::test_verify_drops_it_from_a_path_too
FAILED tests/test_commands.py::test_mapping_input_goes_in_a_temporary_file

Green at b956475 and again at 19eb454:

  1. A served bundle over 2 MiB verifies, given as a mapping and as a path. The test signs a
    UTF-8 file over 2 MiB inline under a fresh seed, runs view, and inlines a trustRegistry in
    host-core's shape.
  2. Signing from an input mapping over 2 MiB succeeds.
  3. No input travels on a pipe. For sign, withdraw, attest and verify given mappings,
    --input names a file, the child's stdin is DEVNULL, and the file is gone after the call. It
    is also gone when the CLI exits 2, or exits 1 for verify.
  4. D9 stays pinned. The CLI receives the bundle minus trustRegistry, with key order kept and
    the caller's mapping unchanged. test_the_cli_itself_refuses_the_key is unchanged and passes.
  5. The guards pass, and still fail on a planted hashlib, a seed read and env= (the impl's
    mutation run: 5 failed). One check was added: the run-time guard now also fails if the seed
    appears in an input file.
  6. The suite, lint and wheel pass: 243 passed (238 on main plus 5).
Cell Who ran it Result
py3.11, node 24.21.0 impl 243 passed
py3.12, node 24.21.0 impl, ORCH 243 passed
py3.14, node 24.21.0 impl, ORCH 243 passed
py3.12, node 22.23.1 impl 243 passed
py3.11, node 22.23.1 ORCH 243 passed
Linux container, py3.12, node 24.21.0 impl 243 passed

ruff check and ruff format --check are clean. The wheel job (clean clone, uv build, wheel in
a fresh environment, smoke_wheel.py) passed.

Release dry run

DRY_RUN=1 RELEASE_REF=HEAD scripts/publish.sh from a clean clone of 19eb454. It built and
checked both files, smoke-tested the wheel (typedstandards 0.1.1, CLI_VERSION 0.2.0, 232
vendored files), and ran uv publish --dry-run. PyPI still answers 404 for 0.1.1.

0d23dc9906ec2261d2264c492c8e1bcff43c299df9c1aa99fea587343ff499b2  typedstandards-0.1.1.tar.gz
55c650135c4531b628aa174f3db9919e0a74f9f81c7bc12f505206112990dcf3  typedstandards-0.1.1-py3-none-any.whl

The owner reruns the dry run from a clean checkout of main at the merge commit, then publishes
on 2026-10-05. publish.sh refuses the live run on any other local date.

gitleaks, sign-off, signatures

$ gitleaks git --log-opts="main..19eb454" --no-banner
INF no leaks found
$ git log --format='%h %G? %ae | %(trailers:key=Signed-off-by,valueonly)' main..19eb454
19eb454 G npstorey@users.noreply.github.com | Nathan Storey <npstorey@users.noreply.github.com>
cb7ca9a G npstorey@users.noreply.github.com | Nathan Storey <npstorey@users.noreply.github.com>
b956475 G npstorey@users.noreply.github.com | Nathan Storey <npstorey@users.noreply.github.com>
7c1d8f0 G npstorey@users.noreply.github.com | Nathan Storey <npstorey@users.noreply.github.com>

Fixtures

None added or changed. The large bundle is built at test time from a fresh random seed. The pinned
first-note.bundle.json check (cb11d2a2…) is unchanged.

Model

The impl ran on Opus 5.5: every turn in its metadata reads claude-opus-5-5, at its agent file's
effort: high. The ORCH, Opus 5.5 at xhigh, wrote cb7ca9a and 19eb454.

Flagged, not fixed

🤖 Generated with Claude Code

https://claude.ai/code/session_012qX8dRbkzJr3B24DbHS3wM

npstorey and others added 4 commits October 4, 2026 20:13
Red at this commit, against 7513583's package code: a served bundle over
2 MiB fails verify, and an input mapping over 2 MiB fails sign, with
UsageError (--input - cannot be read: EAGAIN); every mapping input reaches
the CLI as --input - on a pipe (#6,
npstorey/typedstandards#138).

The spawned fixture now records each input file's bytes as the child
starts, so the D9 tests read the document the CLI received from its
--input file, and the run-time guard checks those files for the seed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012qX8dRbkzJr3B24DbHS3wM
Signed-off-by: Nathan Storey <npstorey@users.noreply.github.com>
sign, withdraw, attest and verify wrote a mapping input to the CLI's
standard input (--input -). CLI 0.2.0 reads it with readFileSync(0),
which fails with EAGAIN once the document is larger than a pipe buffer
holds, so verify failed on every large served bundle (the D9 workaround
turns a bundle path into a mapping). Each mapping is now written to a
temporary file, as view already did, removed when the call returns or
raises; the child's standard input is the null device. verify still drops
only a bundle's top-level trustRegistry.

Fixes #6; the CLI side is
npstorey/typedstandards#138.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012qX8dRbkzJr3B24DbHS3wM
Signed-off-by: Nathan Storey <npstorey@users.noreply.github.com>
… worktree pushes

Three corrections the last orchestrator proposed in its closeout (typedstandards#135, G0 D17 = A):
- publishing names scripts/publish.sh and its dry-run, live and read-back modes;
- the orchestrator pushes the rollback tags, or hands them to the owner in the merge script;
- a branch that adds or changes .gitleaks.toml is pushed from its own worktree, because gitleaks
  reads that file from the directory it runs in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012qX8dRbkzJr3B24DbHS3wM
Signed-off-by: Nathan Storey <npstorey@users.noreply.github.com>
The version moves to 0.1.1 and the Unreleased entry is dated 2026-10-05, the publish day the owner
named (typedstandards#135, G0 D14 = A). uv.lock is unchanged: the package's version is dynamic and
its editable entry carries none. The CLI pin stays 0.2.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012qX8dRbkzJr3B24DbHS3wM
Signed-off-by: Nathan Storey <npstorey@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant