- Add pdftract-swift-publish.yaml WorkflowTemplate
- Supports clone, sync-version, conformance tests, tag-and-push, and warm-spi steps
- SPM tag format is numeric (1.0.0) without 'v' prefix
- Container: swift:5.10-jammy
- Runs on iad-ci with GitHub PAT from ESO Secret github-pat-pdftract
Closes pdftract-5lvpu
The bead description mentioned compile errors in hash.rs from API drift,
but those errors were either already fixed or misattributed. The API usage
was already correct:
- compute_fingerprint already takes 3 arguments with source
- len() already propagates Result with ?
- read_at method already used correctly
- Catalog fields accessed via trailer correctly
Only cleanup: removed unused std::fs::File and std::io imports.
Verification: notes/bf-4mkhv.md
- Update setupTooltips to display data-bbox, data-block-ref, data-mcid, and data-reading-idx
- These attributes are already emitted by spans.rs but weren't being shown in tooltip
- Tooltip now shows complete span information on hover
References pdftract-3mdb7 acceptance criteria:
- Tooltip shows the data-* attrs as formatted rows
Bead-Id: pdftract-145s8
Integrates log-policy enforcement as a Tier-1 quality gate in CI and
installs the panic hook for SecretString redaction in backtraces.
Changes:
- Add log-policy-check to quality-matrix in pdftract-ci.yaml
- Install panic_hook in main.rs for crash dump redaction
- Create verification note at notes/pdftract-3990k.md
Existing implementations verified:
- secrecy crate (v0.10) in workspace dependencies
- SecretString used consistently for credentials
- redact_headers_for_log() in mcp/http.rs strips auth headers
- check-log-policy.sh CI gate scans for forbidden patterns
- CONTRIBUTING.md documents NEVER-log secrets policy
- Fuzz test (tests/log_secret_fuzz.rs) with 10,000 case coverage
Acceptance criteria:
- secrecy crate added ✅ PASS (already in workspace)
- SecretString used for credentials ✅ PASS
- CI gate runs on every PR ✅ PASS
- Fuzz-test confirms no credential leaks ✅ PASS
- Auth headers stripped from logging ✅ PASS
- Panic hook redacts SecretString ✅ PASS
- CONTRIBUTING.md section ✅ PASS
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copy of WorkflowTemplate from declarative-config, synced via ArgoCD.
The workflow builds Python wheels for 5 target triples using maturin:
- Linux x86_64 (manylinux_2_28_x86_64)
- Linux aarch64 (manylinux_2_28_aarch64)
- macOS x86_64 (macosx_11_0_x86_64)
- macOS aarch64 (macosx_11_0_arm64)
- Windows x86_64 (win_amd64)
Plus source distribution (sdist).
Publish to PyPI on milestone tags (vX.Y.Z, vX.Y.Z-rc.N) via twine
using PyPI token from sealed-secret pypi-token-pdftract.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add schema-gen step to quality-matrix that regenerates
docs/schema/v1.0/pdftract.schema.json and compares to committed file.
Fails build on any diff with actionable error message.
Bead: pdftract-16h0a (Phase 6.1.3)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Convert test-matrix from single container to DAG with two parallel branches:
- test-glibc: Full test suite including OCR (tesseract available on Debian)
- test-musl: Production binary feature set (no OCR, unavailable on Alpine)
Musl leg configuration:
- Image: ghcr.io/cross-rs/x86_64-unknown-linux-musl:main
- Test: cross test --release --target x86_64-unknown-linux-musl --features default,serve,decrypt
- Output: JUnit XML artifact (test-results-musl.xml)
- Test threads: 4 (parallel execution)
Also updates:
- .nextest.toml: Add JUnit XML output settings to profile.ci
- Cross.toml: Add cross configuration for musl target
Bead: pdftract-5gtcj
Plan section: Phase 0.3
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add fifth quality gate to quality-matrix DAG:
- New template: clippy-unwrap
- Runs clippy with features default,serve,decrypt -- -D warnings
- Runs library-only pass with -D clippy::unwrap_used -D clippy::expect_used
- Uses pdftract-test-glibc:1.78 base image (precompiled dep tree)
- Enforces INV-8 (no panic at public boundary of pdftract-core)
This completes the 5 Tier 1 hard gates from Phase 0.4 Quality Targets.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add compute-sha256sums step to pdftract-ci publish-if-tag that produces
an aggregate SHA256SUMS file covering all distributed artifacts: binary
archives, Python wheels, sdist, and CycloneDX SBOM.
Key changes:
- Glob-based artifact collection (tar.gz, zip, whl, cdx.json)
- Deterministic sorting with LC_ALL=C sort -k 2 for reproducibility
- Local verification via sha256sum --check before publishing
- Dynamic artifact upload array instead of hardcoded EXPECTED_ARTIFACTS
- SBOM added as optional input artifact
The SHA256SUMS file format matches GNU coreutils sha256sum output,
enabling one-command verification with cosign verify-blob.
References:
- Plan line 3369: SHA256SUMS aggregate
- Plan line 3419: sign-blob of SHA256SUMS
- Plan line 3460: one cosign verify-blob umbrella
Co-Authored-By: Claude Code <noreply@anthropic.com>
- Wire generate-provenance and verify-provenance steps into workflow DAG
- Update publish-if-tag to upload multiple.intoto.jsonl to GitHub Release
- Fix provenance reproducibility by using SOURCE_DATE_EPOCH from git commit
- Docker images already have cosign attest --type slsaprovenance
Acceptance criteria:
- PASS: generate-provenance step wired into DAG
- PASS: provenance uploaded to GitHub Release
- PASS: Docker image cosign attest already implemented
- WARN: Full slsa-verifier verification requires OIDC issuer registration
- PASS: Provenance is reproducible using git commit timestamp
- PASS: Automated smoke test validates JSON structure
Refs: pdftract-3gk5, plan line 3415 (Signing and Provenance)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Implement the publish-if-tag step in pdftract-ci that activates on
version tags (v*.*.*) and publishes cross-compiled binaries to
GitHub Releases.
Changes:
- Add tools/extract-release-notes.sh script for CHANGELOG parsing
- Update publish-if-tag template in pdftract-ci.yaml:
- Downloads all 5 build artifacts from build-matrix
- Generates SHA256SUMS checksums
- Extracts release notes from CHANGELOG.md
- Creates GitHub Release via gh CLI
- Supports both stable and pre-release tags (--prerelease flag)
- Uses --clobber for idempotent re-runs
The step uses Chainguard's gh:latest image and authenticates via
github-pdftract-release Secret (GH_TOKEN key). Optional signing
infrastructure is deferred to Release Engineering epic.
Co-Authored-By: Claude Code (glm-4.7) <noreply@anthropic.com>
Add quality-matrix implementation to pdftract-ci with msrv-check step
using rust:1.78-slim to detect usage of newer Rust features.
Changes:
- .ci/argo-workflows/pdftract-ci.yaml: Implement quality-matrix DAG with
msrv-check, clippy-fmt, and cargo-audit templates
- CHANGELOG.md: New file documenting MSRV bump policy (MINOR version
event, warning period, update checklist)
The MSRV gate prevents silent drift that would break downstream consumers
on older toolchains. Any Rust 1.79+ feature (e.g., let-else, core::error::Error)
will fail the msrv-check step, triggering a policy review.
See notes/pdftract-2w02.md for acceptance criteria verification.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Add MSRV (Minimum Supported Rust Version) pinning to 1.78 for
pdftract-core and pdftract-cli. The MSRV gate prevents silent
absorption of newer Rust features that would break downstream
consumers on older toolchains.
Changes:
- CI: Add quality-matrix DAG with msrv-check step (rust:1.78-slim)
- CI: Add clippy-check, fmt-check, cargo-audit, cargo-deny templates
- README: Add MSRV badge (shields.io)
- clippy.toml: Enable msrv=1.78 for MSRV-aware lints
- CONTRIBUTING.md: Document MSRV bump policy (MINOR version event)
The rust-version was already declared in workspace Cargo.toml;
this bead adds the CI enforcement and documentation.
Refs: pdftract-2w02
Changes:
- Use pdftract-test-glibc:1.78 image (has aws/b2 CLI preinstalled)
- Use b2-readonly secret instead of armor-secrets
- Update env var names to ARMOR_ACCESS_KEY_ID/ARMOR_SECRET_ACCESS_KEY
- Remove apt-get install step (tools already in image)
The cer-diff tool was already implemented in a previous commit.
This commit fixes the image and secret references per the bead spec.
References pdftract-2t9 acceptance criteria:
- regression-corpus step runs on every PR (✓ already in workflow)
- Uses pdftract-test-glibc:1.78 image (✓ fixed)
- Uses b2-readonly secret (✓ fixed)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Implement the per-target build steps inside pdftract-ci for all five
release target triples. Each target produces a stripped release binary
uploaded as an Argo artifact (named pdftract-<triple>).
Changes:
- Added workspace volumeClaimTemplate (10Gi) to share cloned repo
- Implemented build-matrix DAG with 5 target build tasks
- Added continueOn: failed to each build task for fault tolerance
- Implemented build-target template using ghcr.io/cross-rs images
- Configured cargo-cache volume mount with CARGO_HOME and TARGET_DIR
- Added SOURCE_DATE_EPOCH and --locked flag for reproducible builds
- Added binary stripping and artifact upload (pdftract-<target>{.exe})
Targets:
- x86_64-unknown-linux-musl
- aarch64-unknown-linux-musl
- x86_64-apple-darwin
- aarch64-apple-darwin
- x86_64-pc-windows-gnu
Acceptance criteria:
- PASS: All five build steps in build-matrix DAG
- PASS: Binaries upload as artifacts with correct pattern
- WARN: Build time <= 8 min (cannot verify without running pipeline)
- WARN: Stripped binary <= 4 MB (cannot verify without running pipeline)
- PASS: Failure isolation with continueOn: failed
Verification note: notes/pdftract-1bn.md
Refs: pdftract-1bn, Phase 0 lines 1001-1009, ADR-009
Implement the build-matrix DAG template in pdftract-ci WorkflowTemplate
with cross-compilation for all five release target triples using
ghcr.io/cross-rs Docker images.
Targets:
- x86_64-unknown-linux-musl
- aarch64-unknown-linux-musl
- x86_64-apple-darwin
- aarch64-apple-darwin
- x86_64-pc-windows-gnu
Each target:
- Builds in parallel via DAG task with continueOn.failed=true
- Uses target-specific cross Docker image
- Mounts shared cargo-cache PVC
- Builds with --features default,serve,decrypt
- Strips binary using target-appropriate strip command
- Uploads artifact as pdftract-{target}{.exe}
Acceptance criteria:
- PASS: All five build steps in build-matrix DAG
- PASS: All five binaries upload as artifacts
- PASS: Failure isolation with continueOn
- WARN: Build time <= 8 min (runtime verification required)
- WARN: Binary size <= 4 MB (runtime verification required)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>