Commit graph

10 commits

Author SHA1 Message Date
jedarden
c17ce713ee feat(pdftract-5xq16): implement JSON-RPC 2.0 framing layer
Add hand-rolled JSON-RPC 2.0 implementation for MCP server transports.

Module: crates/pdftract-cli/src/mcp/framing/
- Id enum with Number/String/Null variants preserving JSON type
- Request, Response, Notification, ErrorObject structs
- BatchMessage for batch request handling
- Strict jsonrpc version validation (must be "2.0")
- All 6 spec-defined error codes (-32700, -32600, -32601, -32602, -32603, -32099..-32000)
- Constructor helpers for common patterns

Acceptance criteria verified:
- Round-trip serialization/deserialization
- ID type preservation (number/string/null)
- Parse error responses with null id
- Method not found error construction
- Notification detection (no id field)
- Batch request handling
- Rejection of invalid jsonrpc versions
- Empty batch rejection

16 unit tests covering all spec requirements.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 00:00:47 -04:00
jedarden
6a35bdd869 feat(pdftract-29z7b): implement unified diagnostic system + CLI commands
- Added `cmd_explain_diagnostic` function to CLI for detailed diagnostic code explanation
- Added `--list-diagnostics` and `--explain-diagnostic <code>` CLI commands
- Verified all Phase 1.1-1.5 modules use unified DiagCode (lexer, parser, xref, stream, catalog, outline, pages)
- DIAGNOSTIC_CATALOG provides metadata for all 61 diagnostic codes
- Diagnostic struct size: 56 bytes (within 48-64 target range)
- emit! macro provides ergonomic diagnostic emission
- INV-8 maintained: no panics in error paths

All diagnostic codes follow naming convention:
- STRUCT_*: PDF structure errors
- STREAM_*: Stream decoder errors
- XREF_*: Cross-reference table errors
- ENCRYPTION_*: Encryption-related errors
- OCR_*: OCR pipeline errors
- REMOTE_*: Remote source errors
- PAGE_*: Page-level errors
- FONT_*: Font pipeline errors
- GSTATE_*: Graphics state errors
- LAYOUT_*: Layout and reading order errors
- MCP_*: MCP server errors
- CACHE_*: Cache errors

References: Phase 1.6 (error recovery), INV-8, Phase 0.4 (clippy enforces doc comments)
2026-05-22 22:38:31 -04:00
jedarden
e0b293c3d6 fix(pdftract-2a6rk): fix xref.rs u64 literal overflow in proptest
Fixed compilation error in xref.rs where u64 literal 0x5DEECE66D was used
with u32 state, causing overflow. Changed state to u64 for proper Java
Random algorithm behavior.

The OCG /OCProperties parsing implementation was already complete and
all tests pass. See notes/pdftract-2a6rk.md for verification.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 17:26:27 -04:00
jedarden
9aa26a449e docs(pdftract-49f8): establish Cargo.lock policy and documentation
This commit implements the Cargo.lock policy for reproducible builds
across all workspace members (pdftract-core, pdftract-cli, pdftract-py).

Changes:
- Add CONTRIBUTING.md with lockfile-update workflow documentation
- Add .renovaterc.json for weekly lockfile-only PRs (human-gated)
- Add crates/pdftract-core/README.md with rationale for checked-in lockfiles
- Add notes/pdftract-49f8.md with verification note

The Argo workflow updates (pdftract-ci.yaml) are committed separately
in the declarative-config repo.

Acceptance criteria:
- PASS: Cargo.lock tracked by git, not in .gitignore
- PASS: Argo workflow templates document --locked/--frozen requirements
- WARN: Enforcement to be completed when placeholder templates are implemented
- WARN: Binary reproducibility verification deferred to pdftract-build-binaries implementation

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 18:13:14 -04:00
jedarden
660a9401ef feat(pdftract-59zz): implement MCP bearer token ingress channels and TH-03 enforcement
Implements secure MCP bearer-token ingress channels and TH-03 startup abort
enforcement per plan lines 874, 915-921, 922-924.

## Changes
- Add `--auth-token-file PATH` flag (RECOMMENDED channel)
- Add `PDFTRACT_MCP_TOKEN` env var support
- Reject `--auth-token VALUE` unless `PDFTRACT_INSECURE_CLI_TOKEN=1`
- Enforce TH-03: require token for non-loopback bind addresses (exit 78)
- Loopback exemption for 127.0.0.0/8 and ::1/128

## Files
- crates/pdftract-cli/src/mcp/auth.rs: Token resolution with priority order
- crates/pdftract-cli/src/mcp/bind.rs: TH-03 bind security check
- crates/pdftract-cli/src/mcp/server.rs: MCP server entry point
- crates/pdftract-cli/src/mcp/mod.rs: Module exports
- crates/pdftract-cli/src/main.rs: CLI arguments
- crates/pdftract-cli/Cargo.toml: Add secrecy, tempfile dependencies

## Acceptance Criteria
-  --auth-token-file PATH flag implemented
-  PDFTRACT_MCP_TOKEN env var resolved
-  --auth-token VALUE rejected (exit 64) unless PDFTRACT_INSECURE_CLI_TOKEN=1
-  mcp --bind ADDR with non-loopback ADDR and no token: aborts with exit 78
-  mcp --bind ADDR with loopback ADDR and no token: succeeds
-  mcp --bind ADDR with token: succeeds regardless of address
- ⏸️ Inspector token: Phase 7.9 (not yet implemented)
- ⏸️ TH-03 test: separate bead

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 02:47:54 -04:00
jedarden
77a8a6d7f3 feat(pdftract-2ka7): implement secure password ingress channels
Implement TH-07 password ingress channels for CLI:
- --password-stdin flag (reads one line from stdin)
- PDFTRACT_PASSWORD env var
- --password VALUE (rejected unless PDFTRACT_INSECURE_CLI_PASSWORD=1)

Exit code 64 for insecure password usage with stderr hint.
Stderr warning emitted when --password VALUE accepted via opt-in.

Priority order: stdin > env var > value (opt-in) > none.
Empty password (bare newline) treated as no password.

Acceptance criteria:
- --password-stdin: PASS
- PDFTRACT_PASSWORD: PASS
- --password VALUE rejection (exit 64): PASS
- Stderr warning on opt-in: PASS
- Exit codes: PASS
- Python/MCP/Serve: N/A (crates don't exist yet)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 02:20:02 -04:00
jedarden
8c288a742d fix(pdftract-2hm4): fix keyword lexer to use Vec<u8> and improve diagnostics
- Fix Token::Keyword to use b"..." .to_vec() instead of static strings
- Improve unknown keyword diagnostics to show actual keyword bytes
- Remove unused has_valid_line_ending variable in stream keyword lexer
- Add stream_header_valid_line_endings test for stream keyword validation

All hex string lexer tests pass (16 unit tests + 2 proptests).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bead-Id: pdftract-2hm4
2026-05-18 02:11:40 -04:00
jedarden
4777c3d0c3 feat(pdftract-1534): complete Tera-template-driven code generator
Add verify_receipt method support to Go templates:
- client.go.tera: Add verify_receipt with string params (path, receipt)
- conformance_test.go.tera: Add testVerifyReceipt test case

Code generator cleanup:
- Add uses_string_params and string_param_count to Method struct
- Fix unused variable warnings in contract parsing
- Document TODO for full markdown contract parsing

Verification:
- All 9 methods generated correctly (extract, extract_text, extract_markdown, extract_stream, search, get_metadata, hash, classify, verify_receipt)
- All 7 error types generated with exit code mapping
- Drift detection working (validate command)
- Protection against overwriting hand-written code (GENERATED marker)

See notes/pdftract-1534.md for full acceptance criteria status.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 01:48:27 -04:00
jedarden
e176fa68ad fix(pdftract-2hm4): fix hex string lexer invalid char handling and whitespace/comment skipping
Two fixes:

1. Hex string lexer now flushes dangling nibble when encountering invalid
   characters. For `<4X8Y>`, the X and Y are invalid, so we flush nibble 4
   as 0x40, then flush nibble 8 as 0x80, producing `\x40\x80`.

2. Fixed skip_whitespace_and_comments() to properly handle whitespace
   after comments. The previous logic only continued looping if the next
   byte was `%`, missing cases where whitespace follows a comment.

All 52 lexer tests pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 01:47:17 -04:00
jedarden
857f928732 feat(pdftract-5omc): implement SDK conformance test runner pattern
Implement the conformance test runner pattern that every SDK will
implement to validate against the shared test suite.

- Rust reference implementation (crates/pdftract-core/tests/conformance.rs)
  * Full test suite loader and executor
  * Comparison engine with min/max, string constraints, tolerances
  * Skip logic for unsupported features and schema versions
  * Report generation in JSON format

- CLI compare subcommand (crates/pdftract-cli/src/main.rs)
  * pdftract compare - Compare actual vs expected with tolerances
  * Cross-language comparison tool to avoid reimplementations

- Documentation (docs/conformance/sdk-contract.md)
  * Complete pattern specification with pseudocode
  * Per-language runner locations
  * CI integration requirements

- Python reference stub (tests/python-conformance/test_conformance.py)
  * Full pytest-based implementation following the pattern

Closes: pdftract-5omc
2026-05-18 01:22:23 -04:00