Skip to content

feat(office/pdf_form_filler): deterministic multi-action AcroForm engine (#403) - #441

Merged
rosspeili merged 3 commits into
ARPAHLS:mainfrom
rosspeili:feat/issue-403-pdf-form-filler-engine
Oct 16, 2026
Merged

rosspeili merged 3 commits into
ARPAHLS:mainfrom
rosspeili:feat/issue-403-pdf-form-filler-engine

Conversation

@rosspeili

Copy link
Copy Markdown
Contributor

Description

Refactors office/pdf_form_filler from a single-prompt LLM wrapper into a host-agnostic, deterministic AcroForm engine powered solely by PyMuPDF (fitz), eliminating mandatory Anthropic runtime dependencies and API keys.

Key Changes

  • Multi-Action Dispatcher: Discrete inspect, validate, and fill actions for predictable workflows (skill.py).
  • Dynamic XFA Guard: Fails closed with structured unsupported_xfa_form error when non-AcroForm LiveCycle streams are detected (utils.py).
  • Radio Button Group Normalization: Groups widgets sharing field_name, resolves export values from appearance streams (/AP/N), and extracts spatial text labels (utils.py).
  • Human Confirmation Safety Gate: Mutating files requires explicit confirmed: true; unconfirmed calls return status: "needs_input" and a structured preview diff (skill.py).
  • Vector Page Flattening: Optional flatten: true bakes interactive widgets into permanent native graphics via doc.bake() (utils.py).
  • Backward Compatibility: Preserved legacy one-shot prompt flow with deprecation warning (skill.py).

Type of Change

  • Skill Upgrade — changes to an existing skill under skills/

Checklist (all PRs)

  • Linked GitHub issue (Closes #403)
  • Scope matches the issue — no unrelated refactors
  • Contribution complies with Legal notice and code ownership
  • python -m black --check . and flake8 pass locally (0 warnings)
  • pytest skills/ (552 passed) and pytest tests/ (571 passed) pass locally (1,123 tests total)
  • CHANGELOG.md updated under [Unreleased] -> Changed
  • scripts/sync_extras.py --check passes cleanly
  • Ran pytest tests/test_registry_docs.py and pytest tests/test_card_ui_schema.py

New or updated skill

Bundle and metadata

  • Bundle at skills/office/pdf_form_filler/
  • manifest.yaml: Bumped to 0.2.0, action parameter schemas added, runtime deps reduced to pymupdf
  • requirements and pyproject.toml optional extras synced via scripts/sync_extras.py

Effect, Directive, Assurance

  • Deterministic skill.py (host-agnostic multi-action engine)
  • instructions.md documents the 3-step deterministic protocol (inspect -> validate -> fill)
  • card.json presentation schema aligned with output keys
  • test_skill.py includes 23 unit, simulation, and edge case tests
  • SkillLoader.load_skill("office/pdf_form_filler") verified across loader import routes

Documentation and catalog

  • docs/skills/office/pdf_form_filler.md updated with v0.2.0 capabilities, usage snippet, and history entry
  • Category hub (docs/skills/office/README.md) and root catalog (docs/skills/README.md) rows updated
  • docs/usage/install_extras.md extras tables synced with pyproject.toml

Constitution and safety (skills only)

  • Confirmation Safety Gate: Document writes on disk strictly require explicit confirmed: true. Unconfirmed calls emit needs_input and never alter the file.
  • Fail-Closed XFA Guard: LiveCycle dynamic forms return unsupported_xfa_form to prevent corrupted outputs.
  • Permanent Vector Flattening: Optional flatten: true bakes interactive widgets into immutable native page graphics.

Related Issues

Closes #403

…ine (ARPAHLS#403)

Refactor office/pdf_form_filler into a host-agnostic, deterministic AcroForm inspection, validation, and filling engine with multi-action dispatch (inspect, validate, fill).

Key upgrades:
- Remove hardcoded runtime Anthropic dependency and mandatory API key from BaseSkill initialization in favor of pure PyMuPDF AcroForm manipulation.
- Implement dynamic XFA form detection guard (unsupported_xfa_form) to prevent corrupt mutations on LiveCycle forms.
- Normalize radio button groups by grouping widgets sharing field_name, resolving on_state appearance dictionaries, and extracting spatial labels.
- Enforce human confirmation safety gate requiring confirmed: true on fill before mutating files on disk, returning structured preview on needs_input.
- Add optional vector page flattening (flatten: true via doc.bake()) to convert interactive widgets into immutable native vector/text graphics.
- Provide backward-compatible shim for legacy one-shot prompt callers.
- Sync catalog documentation, category hubs, pyproject extras, and CHANGELOG.

Closes ARPAHLS#403
…sion to 0.1.2 (ARPAHLS#403)

Align version to v0.1.2 as Slice 1 of RFC ARPAHLS#402 v0.2.0 epic. Provide stub anthropic module so test patches and empty forms succeed in CI environments lacking anthropic SDK packages.
@rosspeili
rosspeili merged commit f5942a8 into ARPAHLS:main Oct 16, 2026
7 checks passed
@rosspeili
rosspeili deleted the feat/issue-403-pdf-form-filler-engine branch October 16, 2026 16:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant