Skip to content

C2 seam extraction — instance-free request/auth path for the live captcha wiring - #71

Merged
GodSpeed313 merged 2 commits into
mainfrom
m7-c2-request-seam-extraction
Aug 17, 2026
Merged

C2 seam extraction — instance-free request/auth path for the live captcha wiring#71
GodSpeed313 merged 2 commits into
mainfrom
m7-c2-request-seam-extraction

Conversation

@GodSpeed313

Copy link
Copy Markdown
Owner

C1 decided what things mean; C2 is making the transport structurally capable of carrying that decision, not making any new decisions.

This PR is the structural half only. No classification logic, no C1 semantics, no new governance authority.

Why

The live captcha wiring must build submit_captcha_fn before MoltbookHTTPTransport exists, because Note E's fail-closed presence check takes it as a constructor argument. It therefore cannot reach a bound method, and _real_request was trapped behind an instance it does not yet have. The factory shape was never the problem; the trapped default was.

What changed

  • real_request(base_url, method, path, body, headers) at module level, containing _real_request's prior body with only the Note D comment relocated into the docstring. No logic, HTTP semantics, redirect posture, error handling, or timeout change.
  • Deliberately no leading underscore: this module uses module-level underscore to mean "internal, do not import" (_collapse_letter_runs, _normalize_captcha_prompt, _word_number_value). One here would signal the opposite of why it was extracted.
  • real_request is not itself a request_fn — the seam signature is (method, path, json_body, headers); callers partially apply the base_url.
  • auth_headers(api_key) at module level, transport-scoped.
  • _real_request() / _auth_headers() reduced to one-line delegations, each with a guard comment stating instance-specific behavior does not belong in the wrapper.

One HTTP path, not two: the write path and the live verify path now build on the same function, so retry/redirect/timeout posture cannot diverge between them (C1 §5's concern).

Tests — 613 passed, 7 xfailed

Two added. The existing two _real_request tests are deliberately untouched — they now cover the delegation, which is the regression evidence that extraction changed no behaviour.

The new module-level test pins the one property they cannot: callable with no transport instance in existence. Those two would still pass if an instance dependency were reintroduced, because they hold an instance. This one would not — which makes the "pure delegation" guard mechanical rather than a comment asking the next editor to remember.

Deliberate deferrals — recorded as decisions, now tracked in TODO.md

The second commit exists because these were tracked nowhere — only in review conversation and a commit body, which is the state where a reviewer reconstructs a deferral by noticing a mismatch (what #69 had to do for test counts).

  1. Redirect posture — filed as open, deliberately not as post-GO, since GO-1 is granted and this may bear on GO-2. Verified: C1 §5 is provably not violated (POST redirects drop data on 301/302/303; 307/308 raise and fall to §4 residual). Open: classification fidelity (a followed redirect means the status reaching the classifier may not be /verify's own, and C1 §3.2 makes status authoritative), plus a documented credential dimension — moltbook_api_spec.md §1 records that a bare-domain redirect strips Authorization.
  2. client.py:144 duplicates f"Bearer {api_key}", and its comment still calls itself "the ONLY place the key is touched". C2's helper is transport-scoped by decision; consolidating would reach outside C2 and ripple into test_moltbook_credential_integrity.py:196.
  3. Test-count sync — deferred to the C2-complete commit, to be synced once. TODO.md's entry states the count has moved without restating a number, so it cannot itself become a stale count.

Scope

No C1 decision introduced · no submit_captcha_fn policy beyond making the live path authenticable · no TransportResult.rate_limit change · no Note E constructor invariant touched · no write-path behaviour changed · no redirect change · CLAUDE.md/README.md untouched.

🤖 Generated with Claude Code

GodSpeed313 and others added 2 commits August 16, 2026 23:57
… path

C1 decided what things mean; C2 is making the transport structurally capable
of carrying that decision, not making any new decisions. This commit is the
structural half only — no classification logic, no C1 semantics.

The live captcha wiring must build `submit_captcha_fn` BEFORE
MoltbookHTTPTransport exists, because the Note E fail-closed presence check
takes it as a constructor argument. It therefore cannot reach a bound method,
and `_real_request` was trapped behind an instance it does not yet have. The
factory shape was never the problem; the trapped default was.

Extraction only:

- `real_request(base_url, method, path, body, headers)` at module level,
  containing `_real_request`'s prior body with ONLY the Note D comment
  relocated into the docstring. No logic, HTTP semantics, redirect posture,
  error handling, or timeout change.
- Deliberately no leading underscore. This module uses underscore at module
  level to mean "internal, do not import" (`_collapse_letter_runs`,
  `_normalize_captcha_prompt`, `_word_number_value`); one here would signal
  the opposite of why it was extracted.
- `real_request` is NOT itself a `request_fn` — the seam signature is
  (method, path, json_body, headers); callers partially apply the base_url.
- `auth_headers(api_key)` at module level, transport-scoped.
- `_real_request()` / `_auth_headers()` reduced to one-line delegations,
  each carrying a guard comment stating that instance-specific behavior does
  not belong in the wrapper.

One HTTP path, not two: the write path and the live verify path now build on
the same function, so retry/redirect/timeout posture cannot diverge between
them (C1 §5's concern).

Tests: 613 passed, 7 xfailed. Two added. The existing two `_real_request`
tests are deliberately untouched — they now cover the delegation, which is
the regression evidence that extraction changed no behaviour. The new
module-level test pins the one property they cannot: callable with no
transport instance in existence. Those two would still pass if an instance
dependency were reintroduced, because they hold an instance; this one would
not, which makes the "pure delegation" guard mechanical rather than a comment
asking the next editor to remember.

DELIBERATE DEFERRALS — recorded as policy, not omissions:

1. Redirect posture. `_real_request`/`request_fn` follow redirects via
   urllib's default opener. Verified on CPython 3.12.10: on POST it redirects
   for 301/302/303 only and rebuilds the Request WITHOUT `data`, so the
   captcha answer body is never resubmitted and C1 §5 is not violated; 307/308
   raise HTTPError and fall to C1 §4 residual, which is correct. The open
   concern is classification fidelity — a followed redirect means the status
   reaching the classifier may not be `/verify`'s own (a 303 landing on 404
   would classify as C1-4 CONFIRMED_FAILURE, a C1 §9 stop condition, from a
   response `/verify` never gave). Also note `docs/moltbook_api_spec.md` §1:
   a bare-domain request triggers a redirect that STRIPS the Authorization
   header, so redirect behaviour here carries a documented credential-safety
   dimension too. PARKED, unresolved, not touched in this commit.

2. `moltbook/client.py:144` `_auth_header()` duplicates
   `f"Bearer {api_key}"`, and its comment calls itself "the ONLY place the
   key is touched", which `transport.py` has made inaccurate. The DRY helper
   here is deliberately transport-scoped and does NOT consolidate it; fixing
   it would reach outside C2 and ripple into
   tests/test_moltbook_credential_integrity.py:196. PARKED alongside (1).

3. Test-count sync. CLAUDE.md, TODO.md and README.md all still read 611.
   613 is an intermediate count inside active C2 work, not a completed state
   the docs failed to follow — unlike PR #69's situation. Syncing now would
   only be resynced when the classification tests land. DEFERRED by decision
   to the C2-complete commit, to be synced once.

Structurally scoped throughout: no C1 decision introduced, no
`submit_captcha_fn` policy beyond making the live path authenticable, no
`TransportResult.rate_limit` change, no Note E constructor invariant touched,
no write-path behaviour changed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The redirect finding and the client.py auth duplication were tracked nowhere —
they existed only in the review conversation and in 203c016's commit body.
That is the state where a later reviewer has to reconstruct a deferral by
noticing a mismatch, which is what PR #69 had to do for the test counts.

Adds a new "M7 — §C / C2 parked items" subsection. Deliberately NOT filed
under "post-GO engineering debt (NOT prerequisites for GO-1)": GO-1 is
already granted, so that heading's qualifier is spent, and the redirect item
may bear on GO-2. Classifying it as post-GO would assert a readiness
decision that belongs to the operator and to
docs/m7_operator_go_checklist.md, not to this tracker — which its own
readiness-authority note at the top already says.

Three items:

1. Redirect posture — filed as open, with the verified facts separated from
   the unresolved ones: C1 §5 is provably not violated (POST redirects drop
   `data` on 301/302/303; 307/308 raise and fall to §4 residual), while
   classification fidelity and a documented credential dimension
   (moltbook_api_spec §1: bare-domain redirect strips Authorization) remain
   open. Whether it gates GO-2 is explicitly not decided here.

2. client.py:144's duplicate `f"Bearer {api_key}"` and its stale "the ONLY
   place the key is touched" comment — recorded with why C2's helper is
   transport-scoped rather than consolidating it.

3. Test-count sync — recorded as deferred to the C2-complete commit by
   decision, with the reason it differs from #69's case.

Contains no test count. Item 3 states that the documented count has moved
without restating a number, so this commit cannot itself become a stale
count needing a later correction.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@GodSpeed313
GodSpeed313 merged commit 0fdbf88 into main Aug 17, 2026
2 checks passed
@GodSpeed313
GodSpeed313 deleted the m7-c2-request-seam-extraction branch August 17, 2026 04:00
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