chore(agent): commit the machine tier and the doctrine text the checkout was already running
Landing blocker for #61 and #63: the deployment checkout is 12 commits behind and `merge --ff-only` refuses while tracked paths are dirty. Discard is not available here (workspace policy: no `checkout`/`stash` on shared state), so the dirt is committed. - `agent/APPEND_SYSTEM.md`: the point-of-use / one-work-log / PR-link doctrine, already byte-identical to `origin/main` (`cmp` against the trunk blob: no difference). No new prose — the commit exists so the trunk merge can proceed. - `agent/config.yml` and `agent/managed-skills/**`: the machine-live tier the heartbeat owns (AGENTS.md § Live-sync tiers). `ALLOW_SECRETS=1` was used, deliberately and after auditing the staged diff by hand: the only credential-shaped strings in it are two copies of `AKIA0000000000000EXAMPLE` — the inert all-zero AWS example id — and they appear inside the two skill pages that teach that exact placeholder shape. This checkout is still running the pre-#61 hook; the merged gate (value-scoped placeholder filter, `71601f7`) exempts this value, so the refusal dies with this landing. No `--no-verify` was used: the gate ran and its verdict is recorded here. Refs #61
This commit is contained in:
1 parent
004962ffce
commit
8af40c402b
79 files changed
+2771
-332
No files matched your search
@@ -0,0 +1,35 @@
|
||||
---
|
||||
name: real-pdf-acroform-census
|
||||
description: "Census a real-world PDF before running it through a flat→AcroForm pipeline: check for hidden widget layers, prove fill/flatten, avoid the pdfinfo ghost."
|
||||
---
|
||||
|
||||
Census recipe for a real-world PDF arriving at a flat-form pipeline (e.g. franksign's sidecar that injects AcroForm widgets). Run BEFORE assuming the document is flat.
|
||||
|
||||
## Sequence
|
||||
|
||||
1. **Metadata**: `pdfinfo file.pdf` — note `Form:` line, producer (`macOS ... Quartz PDFContext` = Preview/Preview-era export), page size.
|
||||
2. **Text layer**: `pdftotext -layout file.pdf -` — underscore rules (`____`) look "flat".
|
||||
3. **Widget census (the decisive probe)** — never trust the looks:
|
||||
```bash
|
||||
podman run --rm --entrypoint python -v ~/Downloads:/in:z <sidecar-image>:local -c "
|
||||
import pymupdf
|
||||
d = pymupdf.open('/in/file.pdf')
|
||||
for p in d.pages():
|
||||
for w in p.widgets():
|
||||
print(w.field_name, w.field_type_string, [round(v) for v in w.rect])
|
||||
print('annots:', sum(1 for p in d.pages() for _ in p.annots()))
|
||||
```
|
||||
Traps: a custom ENTRYPOINT script swallows `python` as argv — override with `--entrypoint python`. Mount a directory, not a single file (MuPDF atomic-save EBUSY).
|
||||
4. **Fill live-fire**: pass the file through the fill step as-is with placeholder values; verify with `pdftotext -layout` that values land on the rules.
|
||||
5. **Flatten audit**: re-run the widget census on the output (expect 0) — do NOT read `pdfinfo`.
|
||||
|
||||
## Laws learned
|
||||
|
||||
- macOS Preview/Quartz exports (and most print-to-PDF paths) **already embed AcroForm widgets** under transparent rects over their drawn underscore rules. Field names are human-meaningful (`date_today`, ...). Injecting widgets over them duplicates/shadows fields — the design-time injection stage must be skipped when a widget layer exists (widget-first detection).
|
||||
- pdf-lib `flatten()` removes every **widget** but leaves the AcroForm **field dictionary**: `pdfinfo` keeps printing `Form: AcroForm` on a fully flattened file. Widget enumeration (MuPDF) is the only truth; pdfinfo is the ghost.
|
||||
- Underscore rules in the text layer are drawings, not fields; the text layer alone cannot tell flat from widget-bearing.
|
||||
|
||||
## Verdicts
|
||||
|
||||
- Widgets present → fill as-is; detection spec = widget layer (names, types, rects; flip top-left→bottom-left origin if the pipeline spec uses bottom-left).
|
||||
- Zero widgets → true flat form; needs position detection (underscore runs + nearest preceding label) before injection.
|
||||
Reference in new issue
Block a user