docs: record the internal auth boundary and why a 403 proves nothing - #25
Merged
Conversation
Tax-season tooling wanted `lofty documents list/download` over the two
catalogued `taxdocuments/v2` routes. They cannot be reached from this CLI,
and the reason is structural rather than a missing feature — so write down
the finding instead of shipping a command that would 403 for everyone.
- `/prod/taxdocuments/v2/*` lives on the internal surface, behind a website
Cognito session. GET and POST, anonymous and with the SDK Bearer key, all
return 403. The API key and the website session are unrelated credential
systems, and the key's only permission axis is trading — there is no
documents or tax scope to enable.
- The public SDK has no document route at all: across `@loftyaicode/sdk`
0.2.0–0.2.4 there are 19 routes (properties, orders, account, amm,
lp-rewards) and no tax/document/download route was ever published. Lofty's
help center documents tax forms as a dashboard-only feature.
- The trap that cost the most time: a gated route and a route that certainly
does not exist return byte-identical `{"message":"Forbidden"}`, unchanged
even by a malformed Authorization header (a Cognito authorizer would answer
401). So a 403 never means "exists but forbidden", and this API cannot be
probed for route discovery.
That last point also settles the catalog's status: it is a static harvest of
the website bundle, records no HTTP method, and cannot be verified by probing.
AGENTS.md and the README now say so.
Follow-ups noted in the doc: bump cli-common off v0.1.2 to pick up the new
documents/v1 profile (pk-cli-documents) before any document command is
written, so this CLI adopts the family spelling rather than inventing one;
and observing the real response shapes needs an interactive browser session,
since fixtures must be scrubbed captures and never invented.
piekstra-dev
approved these changes
Aug 12, 2026
piekstra-dev
left a comment
Collaborator
There was a problem hiding this comment.
Automated PR Review
Reviewed commit: a9b1cb43c862
Profile: reviewer - Posting as: piekstra-dev
Summary
| Reviewer | Findings |
|---|---|
| documentation:docs | 0 |
| policies:conventions | 0 |
| structure:repo-health | 0 |
Reviewer Coverage
| Reviewer | Status | Inspected | Skipped | Constraints |
|---|---|---|---|---|
| documentation:docs | complete_broad | README.md, docs/api.md | unavailable | unavailable |
| policies:conventions | complete_broad | AGENTS.md, docs/api.md | unavailable | No local convenience copies of the shared cli-common/docs or .github breadcrumbs were present in the review context, so this reviewer could not check the new AGENTS.md/docs/api.md text against those canonical docs for duplication or drift. |
| structure:repo-health | complete_broad | AGENTS.md, docs/api.md | unavailable | unavailable |
0 PR discussion threads considered. 0 summarized; 0 resolved.
Completed in 2m 20s | $1.36 | claude-sonnet-5 | cr 0.10.268
| Field | Value |
|---|---|
| Model | claude-sonnet-5 |
| Reviewers | documentation:docs, policies:conventions, structure:repo-health |
| Engine | claude_cli · claude-sonnet-5 |
| Reviewed by | cr · piekstra-dev |
| Duration | 2m 20s wall · 3m 57s compute |
| Cost | $1.36 |
| Tokens | 90 in / 14.7k out |
Per-workstream usage
| Workstream | Model | In | Out | Cache read | Cache create | Cost | Duration |
|---|---|---|---|---|---|---|---|
| orchestrator-selection | claude-sonnet-5 | 6 | 1.0k | 55.6k | 12.5k | $0.11 | 16s |
| documentation:docs | claude-sonnet-5 | 24 | 3.1k | 426.9k | 28.7k | $0.35 | 47s |
| policies:conventions | claude-sonnet-5 | 32 | 6.5k | 529.2k | 24.6k | $0.41 | 1m 51s |
| structure:repo-health | claude-sonnet-5 | 22 | 3.7k | 381.2k | 35.2k | $0.38 | 52s |
| orchestrator-rollup | claude-sonnet-5 | 6 | 406 | 65.6k | 15.0k | $0.12 | 9s |
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 & why
Tax-season tooling needs
lofty documents list/documents download. Beforewriting them I tried to dogfood the two catalogued endpoints,
/taxdocuments/v2/alland/taxdocuments/v2/zip-documents. They cannot bereached from this CLI, and the reason is structural rather than a missing
feature — so this PR is docs-only. Shipping the command group would have meant
a command that returns
403for every user, backed by fixtures invented ratherthan captured.
What blocks it:
session.
GETandPOST, anonymous and with the SDK Bearer key, all return403.api --internalsends no credential by design.the key's only permission axis is trading — there is no documents or tax
scope to switch on.
@loftyaicode/sdk0.2.0–0.2.4 there are 19 routes (properties, orders, account, amm,
lp-rewards); searching the bundle and its type definitions for
tax/1099/K-1/document/download/statement/zip/pdf yields no functional hit.
Nothing was published and later withdrawn. There is no OpenAPI spec and no
developer docs site.
The trap worth the writeup: a
403from this API proves nothing. A gatedroute and a path that certainly does not exist return byte-identical
{"message":"Forbidden"}, unchanged even by a malformedAuthorizationheader(a Cognito authorizer would normally answer
401). So the API cannot be probedfor route discovery, and a
403never means "exists but forbidden" — we cannoteven confirm the two
taxdocumentspaths are live, only that nothing we cansend reaches them.
That also settles the catalog's status: it is a static harvest of the website
bundle, records no HTTP method, and cannot be verified by probing. Rather than
hand-edit the
@generatedsrc/catalog.rs, the caveat is recorded indocs/api.mdandAGENTS.md, keeping this PR free of code changes.User-visible changes
None — documentation only. No commands, flags, or
schematags added orchanged. New
docs/api.md;README.mdandAGENTS.mdpoint at it.Follow-ups, both recorded in the doc:
cli-commonoff the pinnedv0.1.2. UpstreamHEADadds thedocuments/v1profile (pk-cli-documents) fixing the canonical spellingdocuments list+documents download <ID> -o <PATH>and thedocument-list/v1/document-download/v1/document-download-batch/v1DTOs. Bump before any document support iswritten here, so this CLI adopts the family shape instead of inventing one.
Deliberately not attempted in this PR.
/taxdocuments/v2/*needs aninteractive session at a logged-in browser. Response shapes are currently
entirely unobserved, and fixtures must be scrubbed captures — never invented
to fit an assumed shape. If
getZipFilereturns a pre-signed URL, that URLis a live credential and never lands in a fixture or a commit.
Checklist
make verifypasses locally (fmt + clippy + tests + smoke)— n/a, no code change; the existing suite still passes
(including fixtures — dummies only)
--force(exit6when non-interactive)— n/a, no mutations