Skip to content

trustworthy content-stream tokenization and --ops output#4

Merged
unidoc-anom merged 1 commit into
devfrom
story/14-1-trustworthy-stream-op-output
Jul 16, 2026
Merged

trustworthy content-stream tokenization and --ops output#4
unidoc-anom merged 1 commit into
devfrom
story/14-1-trustworthy-stream-op-output

Conversation

@unidoc-anom

@unidoc-anom unidoc-anom commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Hardens the pdfdebug dump stream --json / --ops machine contract so scripts and AI agents can parse it without silent mislabeling or phantom records.

Changes

  • F1 (correctness): tokenizeContentStream now recognizes a leading + (symmetric to -) per ISO 32000-1 7.3.3, at both edit sites (isNumberStart + the number-consumption loop). Spec-valid operands like +5 / +.5 classify as number tokens instead of being mislabeled as operators and mis-grouped downstream.
  • F2 (contract): emitOps skips FormattedLines with an empty Operator, so --ops NDJSON no longer emits phantom {"op":"","params":[...]} records for comment/dangling-operand lines (one-object-per-operator contract).
  • F3: inline-image EI scan strips the CRLF EOL delimiter (bounded to a single unit) so \r\nEI leaves no stray \r, without eating whitespace-valued bytes that are legitimately part of the opaque payload.
  • F4: documented (comment only) the short-array cap-truncation marker gap in objectsource.go (near-unreachable; no behavior change).

Scope

Backend tokenizer + CLI presenter only. No IPC type / binding / GUI change. internal/pdfcore keeps zero Wails deps.

Tests

  • Unit (co-located, stream_test.go): 14.1-UNIT-001 (leading-sign), 14.1-UNIT-002/-002b (F3 CRLF strip + whitespace-valued-byte preservation).
  • Acceptance (tests/14-1-trustworthy-stream-op-output/, own go.mod): 14.1-INTG-000/-001/-002/-003 driving the built CLI over --json/--ops against two hand-authored fixtures.

Quality gates (green)

go vet ./..., golangci-lint run (0 issues), go test ./..., go test -race ./..., all tests/*/ suites. Frontend untouched by the diff.

Review

Three adversarial review passes (Blind Hunter / Edge Case Hunter / Acceptance Auditor). Notable: review #1 caught and fixed an unbounded F3 whitespace strip that could truncate opaque inline-image payload bytes; the residual bare-LF/0x0D-CR ambiguity is documented as an accepted, irreducible tradeoff. Traceability gate PASS, 100% AC coverage.

🤖 Generated with Claude Code

- F1: tokenize leading-sign numeric operands (+5, +.5) as numbers not
  operators (isNumberStart + number-consumption loop), fixing --json/--ops
  mislabeling of ISO 32000-1 7.3.3 signed operands.
- F2: emitOps skips empty-operator FormattedLines so --ops NDJSON no longer
  emits phantom {"op":""} records for comment/dangling lines.
- F3: strip the CRLF EOL delimiter (bounded to one unit) before inline-image
  EI, removing the stray \r without eating whitespace-valued payload bytes.
- F4: document the short-array cap-truncation marker gap (comment only).
- Tests: 14.1-UNIT-001/-002/-002b + tests/14-1 acceptance module
  (INTG-000/-001/-002/-003) with two hand-authored fixtures.
@unidoc-anom unidoc-anom changed the title fix(14-1): trustworthy content-stream tokenization and --ops output trustworthy content-stream tokenization and --ops output Jul 15, 2026
@unidoc-anom
unidoc-anom requested a review from Copilot July 15, 2026 12:42

Copilot AI 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.

Pull request overview

This PR hardens the machine-parsable contract of pdfdebug dump stream --json and --ops by fixing content-stream tokenization for leading + numeric operands and preventing --ops from emitting phantom NDJSON records, with additional inline-image payload delimiter handling and accompanying regression tests/fixtures.

Changes:

  • Recognize leading + as part of PDF number tokens (symmetric with -) during content-stream tokenization.
  • Enforce the --ops NDJSON contract by skipping formatted lines with Operator == "" to avoid emitting {"op":""...} records.
  • Strip the \r from a \r\n delimiter immediately before inline-image EI without stripping arbitrary whitespace that may be payload data; add unit + integration/acceptance coverage.

Reviewed changes

Copilot reviewed 8 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
internal/pdfcore/stream.go Fixes number tokenization for +-signed operands; tightens inline-image EI delimiter handling to drop CRLF cleanly.
cmd/cli/cmd_stream.go Skips empty-operator formatted lines so --ops emits one NDJSON object per real operator only.
internal/pdfcore/stream_test.go Adds unit tests covering leading-+ numbers and inline-image CRLF delimiter stripping / payload-byte preservation.
tests/14-1-trustworthy-stream-op-output/helpers_test.go Adds black-box CLI build/run harness for acceptance tests over dump stream --json/--ops.
tests/14-1-trustworthy-stream-op-output/stream_contract_test.go Adds integration contract tests asserting correct --json token types and --ops NDJSON operator records.
tests/14-1-trustworthy-stream-op-output/go.mod Introduces an isolated Go module for the acceptance suite.
testdata/correctness/README.md Documents new correctness fixtures and the pre-/post-fix behaviors they exercise.
internal/pdfcore/objectsource.go Adds an explanatory comment documenting a near-unreachable truncation-marker gap (no behavior change).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@unidoc-anom
unidoc-anom requested a review from a team July 15, 2026 15:19

@anovik anovik 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.

LGTM

@unidoc-anom
unidoc-anom merged commit 1d997cd into dev Jul 16, 2026
4 checks passed
@unidoc-anom
unidoc-anom deleted the story/14-1-trustworthy-stream-op-output branch July 16, 2026 11:45
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.

4 participants