Skip to content

Remove code for auditability (scan picks A, B1-B4, C7, C10-C13) - #146

Draft
BenWestgate wants to merge 3 commits into
codex/split146-storagefrom
claude/project-thread-2q3smy
Draft

BenWestgate wants to merge 3 commits into
codex/split146-storagefrom
claude/project-thread-2q3smy

Conversation

@BenWestgate

@BenWestgate BenWestgate commented Oct 14, 2026 •

Copy link
Copy Markdown
Owner

Requested by Ben · project thread

Before: the library was 4,894 logical lines. The CLI ran its own correction driver, card comparer and error wording, the library carried cl and bip39 profiles, and several guards re-checked already-validated values. correct could not be told a known prefix or length.

After: the library is 4,399 logical lines (−495). The CLI and GUI share one correction driver, one shift-aware card comparer and one set of messages. Only BIP93's ms rules remain. correct takes --prefix, and codex32 correct takes --length.

14 atomic commits on reviewability-v1 (9b99862), each passing lint, strict mypy and the full suite on its own, then 4 commits answering the security review:

  • A cleanup: remove dead and unused code.
  • C7 bip93: keep only the ms rules and fold the profile registry. cl and bip39 strings now parse as generic codex32, so the cl threshold-0 rejection from api: Remove unused public entry points #130 is gone.
  • B1 cli: the CLI calls the library's _correct_complete, which gains the CLI's set-validity filter and, for the CLI only, the competitor scheduler. This supersedes the _correction_plan part of cli: Remove unreachable recovery and search paths #105.
  • B2 generation: ConfirmationResult now carries shift-aware mismatched_groups and entered_groups, so a dropped character marks only its own group. Entries more than 16 characters longer than the card are marked wrong without alignment. The CLI keeps only its region-retry prompt.
  • B3 errors: user-facing messages now live in the library exceptions. _FRIENDLY_SET_ERRORS and _prefixed_input_error are removed.
  • B4 generation: ceremony thresholds and identifiers are validated through Header.
  • C11 errors: drop the never-raised InvalidHeader and InvalidPayload. The specific reasons now derive from CodexError.
  • C12 bip93: drop the _artifact_tail re-decode and the defensive sequence copy (a share set is now read at most ten items deep).
  • C13 cli: confirmations need interactive stdin; the /dev/tty/CONIN$ fallback is removed.
  • Bails helpers: remove the Bails seed-digest identifier rules (now Check backup identifiers against Bails' seed-digest rule Bails#351). A no-record restore of an unshared backup still says whether its identifier matches the fingerprint, and that a match does not prove it is the expected wallet.
  • AGENTS.md: remove what CONTRIBUTING.md and AI_POLICY.md already say, and say when to read them.
  • ci: CI now replaces the editable install with the built wheel and runs pytest against it. verify_wheel_environment.py, verify_installed_wheel.py and bitcoin_core_main_smoke.py are removed.
  • Known prefix and length cli: correct --prefix ms12name keeps a known start fixed. codex32 correct --length N limits the search to the original's length, which helps with inserted or dropped characters; ms32 correct keeps --bytes. Both are rejected with --residue.

Security review follow-ups (review 5608668817):

  • 815b923 restores the artifact construction token and the CreationCeremony copy/pickle traps (backs out those two C12 cuts).
  • 916b585 rewords the no-record identifier match so it does not overstate what it proves.
  • db1924a reverts C10: Core is probed on five chains again and every RPC call is pinned with -chain, matching the security model and API guide.
  • 02d226d keeps public correct() fail-closed on expired required work; only the CLI uses the competitor scheduler. A deterministic deadline test covers both paths.

Still needed before merge: the GUI branches import profiles.ms32, CoreLightningSecret and Profile, so they need a follow-up.

Checks run locally (Python 3.13): pytest and python -O -m pytest (873 passed), ruff, mypy --strict, verify_correction_constants.py and differential_correction.py --verify (57 cases).

🤖 Generated with Claude Code

https://claude.ai/code/session_01XGMpowzJwwgyHMEd63ijDe


Generated by Claude Code

@BenWestgate BenWestgate self-assigned this Oct 14, 2026
@BenWestgate
BenWestgate marked this pull request as ready for review October 20, 2026 10:26
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-24T09:09:36.503410Z 58f9487 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@BenWestgate
BenWestgate marked this pull request as draft October 20, 2026 10:26

Copy link
Copy Markdown
Owner Author

@codex review


Generated by Claude Code

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cfbba960e6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/codex32/bip93.py
Comment thread src/codex32/cli.py
Comment thread src/codex32/generation.py Outdated
Comment thread src/codex32/bip93.py Outdated
Comment thread src/codex32/generation.py

Copy link
Copy Markdown
Owner Author

@codex security review

Focus: correction (_correct_complete, the new --prefix/--length options), share-set validation, the shift-aware confirmation alignment, and the removed construction and copy guards.


Generated by Claude Code

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@BenWestgate BenWestgate left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security review and patch-risk assessment

Reviewed the immutable PR #146 comparison 9b99862eb14d..ffebbbd5fa5d (binary diff SHA-256 14752d8dd89c066ef8008dd92fee88c1a7f321e1a165de4527de06f8089cafa9). The Codex Security diff scan completed review of all 25 changed source/workflow/tooling items, investigated seven candidates, and found no standalone exploitable vulnerability under the repository's documented trust model. This is not an unconditional security sign-off: the separate patch-risk assessment recommends revise, not auto-merge.

Risk dimensions: impact if wrong high; regression likelihood high (source-visible/reproduced boundary changes); regression protection partial; recoverability managed; confidence moderate. Exact-head GitHub Actions Python package and Bitcoin Core fixtures both passed. They do not cover the removed construction/copy guards or the public required-work timeout contract.

Changes requested before merge

  1. Reconsider the unchecked exported artifact constructor (existing review thread). With two synthetic, unfunded seeds, MasterSeed(first.text, first.header, first.hrp, second.payload_symbols) displays the first seed's text but master_xprv derives the second seed's key. This is conditional on an API consumer directly constructing artifacts, which the new guide calls unsupported, but it contradicts the validated-artifact security invariant. Restore the factory-only guard or validate at the sensitive consumers and align the contract.
  2. Restore the public correction API's fail-closed behavior when required competitor work expires. The new competitors=True path can return one candidate marked search_complete=False even during required work, contrary to docs/security/invariants.md. I reproduced this with a synthetic card, an adjacent swap and a deterministic expiry after the fixed pass. The CLI's whole-card confirmation mitigates downstream risk but does not satisfy the public API contract.
  3. Reword the recordless restore message: a fingerprint-derived identifier matches any internally consistent unshared card, including the wrong wallet's. “So this is not a mixed-up card” overstates what the check establishes and conflicts with the adjacent no-record warning.
  4. Resolve the Core chain policy and documentation together. The adapter now follows the network selected by bitcoin-cli configuration, but docs/security/model.md:227-229 and docs/developer/api.md:564-569 still promise five-chain probing and explicit -chain on every call. Later calls are not pinned to the chain observed at preflight. Either bind the destination or explicitly revise the mandatory contract and test the intended config-change behavior.
  5. Make an explicit decision on the open ceremony-copy guard thread. deepcopy of a live synthetic ceremony now succeeds; no in-repository copy path exists, so this is an API safety/recoverability risk rather than a proven exploit.

The deliberate removal of BIP39/Core Lightning application rules is documented as generic-HRP behavior; it remains a public-contract migration consideration. The detailed, schema-validated risk assessment is included below for auditability.

Machine-readable patch-risk assessment
{
  "schemaVersion": 1,
  "patch": {
    "repository": "BenWestgate/python-codex32",
    "sourceType": "commit_range",
    "base": "9b99862eb14d15d86977cec202a6d39abcac2a88",
    "head": "ffebbbd5fa5d5ad15459bb798c9c12ce332c2bfd",
    "changedFiles": [
      ".github/workflows/python-package.yml",
      "AGENTS.md",
      "README.md",
      "docs/developer/api.md",
      "docs/security/invariants.md",
      "docs/security/model.md",
      "docs/user/guide.md",
      "src/codex32/__init__.py",
      "src/codex32/_bitcoin_core.py",
      "src/codex32/_cli_input.py",
      "src/codex32/_cli_parser.py",
      "src/codex32/bip93.py",
      "src/codex32/cli.py",
      "src/codex32/correction.py",
      "src/codex32/errors.py",
      "src/codex32/generation.py",
      "src/codex32/indel.py",
      "src/codex32/profiles/__init__.py",
      "src/codex32/profiles/bip39.py",
      "src/codex32/profiles/cl32.py",
      "src/codex32/profiles/ms32.py",
      "src/codex32/wallet.py",
      "tests/data/README.md",
      "tests/data/malformed_inputs.json",
      "tests/data/sharing_vectors.py",
      "tests/test_alignment.py",
      "tests/test_bip39.py",
      "tests/test_bip93.py",
      "tests/test_bitcoin_core.py",
      "tests/test_cli.py",
      "tests/test_cli_lengths.py",
      "tests/test_competitors.py",
      "tests/test_correction_bch.py",
      "tests/test_correction_disclosure.py",
      "tests/test_correction_indel.py",
      "tests/test_crc.py",
      "tests/test_generation.py",
      "tests/test_generic_hrp.py",
      "tests/test_lengths.py",
      "tests/test_malformed_corpus.py",
      "tests/test_mixed_case_deadline.py",
      "tests/test_public_api.py",
      "tests/test_sharing.py",
      "tools/alignment_benchmark.py",
      "tools/bitcoin_core_main_smoke.py",
      "tools/bitcoin_core_regtest.py",
      "tools/correction_benchmark.py",
      "tools/differential_correction.py",
      "tools/fuzz_correction_context.py",
      "tools/fuzz_untrusted_boundaries.py",
      "tools/verify_installed_wheel.py",
      "tools/verify_wheel_environment.py"
    ],
    "sha256": "14752d8dd89c066ef8008dd92fee88c1a7f321e1a165de4527de06f8089cafa9"
  },
  "recommendation": "revise",
  "workflowLabel": "revise",
  "impact": {
    "rating": "high",
    "rationale": "This changes exported artifact trust, correction behavior, recovery identity messaging, Core network selection and public HRP contracts in wallet-backup software; wrong backup or wallet selection can cause costly recovery failure."
  },
  "regressionLikelihood": {
    "rating": "high",
    "rationale": "Exact-head source and bounded synthetic reproductions establish that unchecked MasterSeed construction and incomplete required-work correction now succeed; Core safety documentation contradicts implemented chain selection."
  },
  "regressionProtection": {
    "rating": "partial",
    "rationale": "Exact-head Python, wheel, cross-platform and Core-fixture jobs pass, but tests for constructor and ceremony guards were removed, the main-chain smoke and fuzz harnesses were deleted, and no test asserts public required-work fail-closed or chain pinning.",
    "exactHeadChecksPassed": true
  },
  "recoverability": {
    "rating": "managed",
    "rationale": "Code can be reverted without schema migration, but users may have printed backup cards or imported into Core wallets under the changed behavior; recovery requires auditing those artifacts and wallet records."
  },
  "confidence": {
    "rating": "moderate",
    "rationale": "The immutable commit range, all 25 changed-source review items, supporting docs/tests, exact-head CI and bounded reproductions are inspected; external consumers and natural timeout frequency are not established."
  },
  "applicability": {
    "status": "confirmed",
    "rationale": "Both published CLI entrypoints and exported Python API reach the changed code; package and Bitcoin Core test workflows run at the exact head."
  },
  "statusQuoRisk": {
    "rating": "unknown",
    "rationale": "The PR identifies a substantial auditability cost from legacy code, but no current exploit or quantified operating risk of retaining it is demonstrated."
  },
  "autoMergeExclusions": [
    "public_contract",
    "privileged_boundary",
    "architecture_specific_rollout"
  ],
  "affectedRuntimeRoots": [
    "codex32.cli:main",
    "codex32.cli:ms_main",
    "codex32.parse_codex32",
    "codex32.correct",
    "codex32.MasterSeed",
    "codex32.CreationCeremony",
    "codex32.wallet.master_xprv",
    "codex32._bitcoin_core.BitcoinCore.connect/initialize"
  ],
  "importantCallers": [
    "CLI check/correct/create/share/wallet flows",
    "External Python package consumers of exported artifact classes",
    "Bitcoin Core subprocess adapter and wallet initialization"
  ],
  "riskDrivers": [
    "Direct MasterSeed constructor accepts inconsistent text and payload; synthetic reproduction derives the payload's xprv rather than the displayed text's key.",
    "Public correction can return a sole candidate when required competitor search expires, contrary to docs/security/invariants.md:20-25.",
    "Recordless restore says a self-consistent card is not mixed up, although no wallet record binds it to the intended wallet.",
    "Core adapter no longer pins -chain and authoritative security/developer docs still claim five-chain explicit probing.",
    "Ceremony deepcopy succeeds after pending share; noncopyability tests and other boundary fuzz/mainnet smoke checks were removed."
  ],
  "protectiveFactors": [
    "Parser/factories still validate/reparse normal CLI artifacts and output suggestions remain explicitly untrusted.",
    "CLI requires exact-card correction confirmation and recordless restore still prints a broader warning.",
    "Exact-head Python package and Bitcoin Core fixture workflows completed successfully across Linux, Windows and macOS."
  ],
  "materialBoundaries": [
    {
      "id": "validated-artifact",
      "invariant": "Only validated artifacts may authorize derivation and wallet operations.",
      "runtimeRoot": "MasterSeed/Share Python API and wallet.master_xprv",
      "counterexample": "Construct MasterSeed from one synthetic seed's text and another's payload; master_xprv derives the latter without parsing.",
      "legitimateControl": "Normal parser/factory call sites validate; developer docs declare direct construction unsupported, but the exported constructor is callable.",
      "result": "contradicted"
    },
    {
      "id": "correction-required-work",
      "invariant": "Public API returns no candidate if required correction search is incomplete.",
      "runtimeRoot": "codex32.correct",
      "counterexample": "Adjacent-swap synthetic input with competitor deadline expiry returns one incomplete candidate.",
      "legitimateControl": "search_complete=False flags truncation and CLI requires exact-card confirmation; these do not enforce the documented public fail-closed rule.",
      "result": "contradicted"
    },
    {
      "id": "recordless-identity",
      "invariant": "No-card-record message must not imply that internal identifier consistency proves wallet identity.",
      "runtimeRoot": "ms32 wallet/create --existing",
      "counterexample": "An unrelated valid unshared backup self-matches its fingerprint identifier and triggers 'not a mixed-up card'.",
      "legitimateControl": "NO_RECORD_WARNING separately says nothing proves expected wallet and requires explicit confirmation.",
      "result": "contradicted"
    },
    {
      "id": "core-chain",
      "invariant": "Core chain used for wallet mutation remains bound to preflight and documented contract is accurate.",
      "runtimeRoot": "BitcoinCore.connect/_rpc/initialize",
      "counterexample": "bitcoin-cli config can change after connect; later _rpc has no -chain and may target another local network.",
      "legitimateControl": "The selected bitcoin-cli and config are trusted; chain is reported at connect, but not pinned and docs still promise explicit -chain.",
      "result": "contradicted"
    },
    {
      "id": "non-ms-application",
      "invariant": "Generic HRPs must not be presented as application-validated by this library after profile removal.",
      "runtimeRoot": "parse_codex32/codex32 check",
      "counterexample": "Checksum-valid but application-invalid BIP39 or CL text now parses generically.",
      "legitimateControl": "README and user guide explicitly delegate non-ms application semantics; removed profile exports make old typed consumers fail imports.",
      "result": "supported"
    },
    {
      "id": "secret-channel",
      "invariant": "Private wallet key material remains off command arguments and normal diagnostics.",
      "runtimeRoot": "BitcoinCore._rpc/initialize",
      "counterexample": "A changed subprocess wrapper might put xprv in argv or print it.",
      "legitimateControl": "Current _rpc uses child stdin and fixed command arguments; Core errors are suppressed; exact-head tests exercise wallet fixtures.",
      "result": "supported"
    }
  ],
  "validation": [
    {
      "name": "Exact-head GitHub Actions Python package run 39560631259",
      "status": "passed",
      "protects": "Python 3.10-3.15 compatibility, Linux/Windows/macOS tests, type/lint, differential correction and installed-wheel test."
    },
    {
      "name": "Exact-head GitHub Actions Core fixtures run 39560631342",
      "status": "passed",
      "protects": "Frozen wallet fingerprint agreement with pinned Bitcoin Core."
    },
    {
      "name": "Synthetic isolated MasterSeed mismatch reproduction",
      "status": "passed",
      "protects": "Confirms direct constructor allows text/payload mismatch and master_xprv follows payload."
    },
    {
      "name": "Synthetic isolated correction expiry reproduction",
      "status": "passed",
      "protects": "Confirms required-work timeout can still return one incomplete public candidate."
    },
    {
      "name": "Main-chain smoke, removed construction/copy tests, and fuzz harnesses",
      "status": "unavailable",
      "protects": "Previously tested or exercised Core mainnet integration and hardening boundaries; removed in this patch."
    }
  ],
  "unknowns": [
    {
      "summary": "External package consumers that relied on removed BIP39/CL profile validation or direct artifact construction are not inventoried.",
      "decisionCritical": false
    },
    {
      "summary": "Natural ten-second correction expiry frequency for affected damaged-card shapes is not measured.",
      "decisionCritical": false
    }
  ],
  "evidencePlan": []
}

Security scan ID: 5b29126a-05e7-48d5-81be-98e895575148. No local integration suite was run; the bounded reproductions used synthetic, unfunded material in an isolated checkout.

Comment thread src/codex32/correction.py Outdated
Comment thread src/codex32/cli.py Outdated
Comment thread src/codex32/_bitcoin_core.py Outdated
BenWestgate added a commit that referenced this pull request Oct 22, 2026
Security review on #146: MasterSeed(first.text, first.header, "ms",
second.payload_symbols) showed one seed's text while master_xprv derived
another, and a live CreationCeremony could be deep-copied and confirmed
twice. Bring back the construction token and the ceremony __init__ and
__reduce_ex__ traps, with their tests.

Claude-Session: https://claude.ai/code/session_01XGMpowzJwwgyHMEd63ijDe
BenWestgate added a commit that referenced this pull request Oct 22, 2026
Security review on #146: any valid unshared card matches its own
fingerprint, so a match shows the card is consistent, not that it is
the expected wallet.

Claude-Session: https://claude.ai/code/session_01XGMpowzJwwgyHMEd63ijDe
BenWestgate added a commit that referenced this pull request Oct 22, 2026
This reverts "core: Use bitcoin-cli's configured chain". It saved 28
lines but made testers edit bitcoin.conf, and the security review on
#146 found later RPC calls were no longer pinned to the chain seen at
preflight, against docs/security/model.md and docs/developer/api.md.

Claude-Session: https://claude.ai/code/session_01XGMpowzJwwgyHMEd63ijDe
BenWestgate added a commit that referenced this pull request Oct 22, 2026
Security review on #146: moving the CLI onto the library driver also
moved the public correct() onto the competitor scheduler, which returns
a best-so-far candidate when required work expires. That breaks
docs/security/invariants.md item 5. correct() again uses the
fail-closed search; only the CLI asks for the competitor scheduler. A
deterministic test expires every layer after the BCH pass.

Claude-Session: https://claude.ai/code/session_01XGMpowzJwwgyHMEd63ijDe

@BenWestgate BenWestgate left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI-assisted current-head triage.

Concept ACK, not code/security ACK, at 74b6858. The 27-commit cleanup changes parsing, correction, public-facing behavior, and generation boundaries together (52 files). Keep draft pending per-commit tests, BIP-93 and differential vectors, and a focused security review of shared correction and ceremony invariants. Earlier review fixes (including ceremony-copy protection) need confirmation against this head.

@BenWestgate BenWestgate left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI-assisted current-head triage.

Concept ACK, not code/security ACK, at d1714f7. The latest commit changes correction, parsing, generation and validation boundaries across 29 files; the full PR still spans 53 files and 28 commits. Keep draft pending per-commit test evidence, BIP-93/differential regression checks, and a complete security review of the immutable head. Python-package CI was still running at review time.

BenWestgate added a commit that referenced this pull request Oct 22, 2026
Port _from_unchecksummed_string() to string headers and Codex32String.

Claude-Session: https://claude.ai/code/session_01C8Ur3dhqpcWU3gEYsweXNM

Copy link
Copy Markdown
Owner Author

Per-commit evidence for the triage reviews: all 28 commits from 9b99862 to d1714f7 were checked in a clean worktree, each with ruff check, mypy src/codex32, pytest, tools/verify_correction_constants.py and tools/differential_correction.py --verify (57 frozen PR #70 cases). Every commit passes all five checks.

The full suite contains the BIP-93 vectors.

Commits Tests passed
3219d57 906 (run serially: pytest-xdist failed at collection because parameter IDs differ between workers, before any test ran)
9eb856c 883
484f166 877
d5ec8bd .. 30ed485 878
5195440 876
e79e28a 877
2d9d08f .. 47567c4 870
ffebbbd 871
815b923 .. db1924a 872
02d226d .. d1714f7 873

The head also passes under python -O and Python 3.11, and CI is green on d1714f7.

Earlier review fixes on d1714f7:

  • Ceremony copy guard: CreationCeremony.__reduce_ex__ still raises, and test_ceremony_cannot_be_copied_or_serialized passes.
  • Artifact construction guard: replaced on purpose by string-only artifacts. Constructing Codex32String(s) or MasterSeed(s) validates s, and every other attribute is a slice of it. MasterSeed(share.s) raises, so one seed's card can no longer be paired with another seed's payload.
  • Public correct(): it still fails closed when required work expires (test_public_correction_fails_closed_when_required_work_expires).

The PR stays in draft until the security review of the head.


Generated by Claude Code

@BenWestgate BenWestgate left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI-assisted incremental review at bb52ac4 — not ACKing yet. CorrectionContext.from_shares() truncates accepted to 10 with islice; an incompatible 11th share is silently ignored, and its index is not excluded. Reject an oversized sequence instead of accepting a partial set. CI is green; the full cleanup still needs final security/integration review.

Comment thread src/codex32/correction.py Outdated

Copy link
Copy Markdown
Owner Author

Correction to my bb52ac4 review: the 11th-share concern is invalid. _validate_share_set rejects any ten-item set (threshold ≤9), so the factory cannot silently accept an incompatible 11th share. I withdrew the inline finding. Incremental change has no blocker identified by this check; full PR security/integration review is still required.

@BenWestgate BenWestgate left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fresh exact-head review (bb52ac4). GitHub Actions Python package and Bitcoin Core wallet fixtures passed on this SHA. Two reproducible recovery-availability regressions in the new context factory block readiness; please keep this PR in draft until fixed and rerun CI/security review on the replacement head. Neither result by itself shows acceptance of an invalid wallet seed, but both remove previously available backup-correction behavior.

Comment thread src/codex32/correction.py Outdated
Comment thread src/codex32/correction.py Outdated
@BenWestgate
BenWestgate added this pull request to stack #168 October 23, 2026 00:12

@BenWestgate BenWestgate left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional exact-head parser robustness finding: malformed text with a long HRP can now raise an uncaught IndexError instead of a CodexError. Reproduced with synthetic input; the baseline's Header._from_symbols length check handled it. This is separate from the two correction regressions recorded in the earlier review. PR should remain draft.

Comment thread src/codex32/bip93.py

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bb52ac45c3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/codex32/bip93.py
Comment thread src/codex32/_cli_input.py Outdated
Return to v0.6.1's single Codex32String(s) for every share and secret,
with hrp, k, ident, share_idx, payload and checksum read as slices of s,
as in v0.6.1 and rust-codex32. Share, Secret and the Header class go:
shares and secrets differ only by share_idx, and a private _header()
validates new headers. MasterSeed stays as the one subclass with extra
rules (ms, index S) and the seed bytes (data) and from_seed. Every ms
string still gets BIP93's length check when parsed.

Claude-Session: https://claude.ai/code/session_01XGMpowzJwwgyHMEd63ijDe

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

Reviewed commit: 58f9487157

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

A short body after a long HRP passed the 21-character check and then
indexed past the header, raising IndexError instead of InvalidLength.
Restore the six-symbol header check from reviewability-v1.

Claude-Session: https://claude.ai/code/session_01XGMpowzJwwgyHMEd63ijDe
With S accepted in a share basis, its index went into the correction
context's excluded indices, which accept only ordinary indices, so a
damaged next share got no suggestion. Leave S out of the exclusions, as
reviewability-v1 effectively did.

Claude-Session: https://claude.ai/code/session_01XGMpowzJwwgyHMEd63ijDe

This branch has not been deployed

No deployments
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.

1 participant