# Implementation Friction Log

Date: 2026-02-10
Context: Building a living documentation example project under `examples/` that demonstrates fullbleed CLI + engine with curated fonts and Bootstrap features.

## Friction Items

1. No bulk asset install command.
- Impact: Installing 30+ fonts requires many repeated `fullbleed assets install` calls.
- Workaround used: Add project-local helper script to install curated asset set.

2. No first-class "asset set manifest" command.
- Impact: Cannot declare and install a named set (`docs-font-pack`) in one CLI invocation.
- Workaround used: Maintain `data/font_catalog.json` and drive install via Python script.

3. `assets lock --add` currently handles builtins, not remote catalog packages.
- Impact: Lock population for remote fonts is not obvious from docs flow.
- Workaround used: write `assets.lock.json` explicitly from the installer helper after computing hashes.

4. `init` scaffold output still reflects older vendor assumptions.
- Impact: Generated comments/examples do not emphasize `vendor/css` + `vendor/fonts` layout.
- Workaround used: create an explicit example with updated structure and scripts.

5. Existing `examples/` tree is dense and mixed-purpose.
- Impact: Finding a clean canonical docs example path is less ergonomic.
- Workaround used: create one clearly named, self-contained example directory.

6. Registry metadata gap: `jetbrains-mono` had no `filename`.
- Impact: font-catalog generation and install planning broke at runtime.
- Workaround used: patch `REMOTE_ASSETS` metadata and regenerate the catalog.

7. CLI version drift in local environment.
- Impact: globally installed `fullbleed` lacked newer global flags (for example `--emit-manifest`), causing pipeline command failures.
- Workaround used: add compatibility detection in the docs pipeline and downgrade optional flags when unsupported.

8. Legacy vendor layout from older CLI builds (`vendor/<file>` instead of `vendor/css|fonts/<file>`).
- Impact: docs project expects typed vendor subdirectories, but install outputs can vary by CLI version.
- Workaround used: normalize installed asset paths in `scripts/install_assets.py` and migrate legacy `LICENSE.txt` into typed subdirs.

9. Shell/editor encoding differences (UTF-8 BOM).
- Impact: strict JSON reads failed for data files written via some shell defaults.
- Workaround used: parse project JSON with `utf-8-sig` in docs generators.

10. Root `.gitignore` ignored `/examples` entirely.
- Impact: new documentation example content was not visible to git by default.
- Workaround used: add a narrow unignore rule for `examples/living_docs_atlas/**` while keeping other examples ignored.

11. Mixed CLI versions in local environment produced different JSON contracts (`verify.bytes_written` tuple vs int).
- Impact: docs pipeline output shape varied depending on which `fullbleed` binary was found first.
- Workaround used: add compatibility handling in scripts and include explicit compatibility metadata in pipeline summary.

12. `assets install` can auto-edit `report.py` when project markers are present.
- Impact: docs example `report.py` was mutated unexpectedly during install flows.
- Workaround used: run install subprocesses from a neutral cwd (`vendor/`) and manage `assets.lock.json` explicitly in the helper script.

13. No built-in per-font specimen generator with multilingual defaults.
- Impact: proving language/script coverage required custom boilerplate and repeated hand-written templates.
- Workaround used: add project-local specimen generation in `scripts/build_inputs.py` plus `data/language_samples.json` and dedicated templates.

14. Older global CLI binaries can still fail specific remote installs (`jetbrains-mono`) despite patched local metadata.
- Impact: full asset provisioning for docs could fail nondeterministically depending on PATH order.
- Workaround used: add a catalog URL fallback path in `scripts/install_assets.py` to install font + license directly when CLI install fails.

15. Complex atlas layout initially blocked expected pagination in real render.
- Impact: the registry table appeared as a single-page output in the full document, making repeated table headers impossible to validate.
- Workaround used: replace atlas with a pagination-safe template/CSS profile; keep `thead { display: table-header-group; }` and verify by extracting text from generated PDFs.

16. Mixed-source CLI tree (`python/fullbleed_cli` for packaging, `fullbleed_cli/src/fullbleed_cli` for tests) can drift.
- Impact: behavior can differ between wheel-installed CLI and test-imported CLI unless files are kept in sync.
- Workaround used: mirror critical changes in both trees and add assertions in tests for capabilities/fail-on/repro payload fields.

17. Local compiled extension artifacts can break wheel builds (`python/fullbleed/_fullbleed*.pyd` duplicate in include path).
- Impact: `maturin build` fails with duplicate wheel file collisions.
- Workaround used: keep `python/fullbleed/` source-only for packaging builds (move local `.pyd` out of include path) and document this in launch risk controls.

18. Windows global script install path can fail during wheel reinstall in a mixed Python setup.
- Impact: `pip install --force-reinstall` may fail on `fullbleed.exe.deleteme` rename under system `Scripts/`.
- Workaround used: verify with `python -m pip install --user --force-reinstall` in user space for smoke testing.

19. Wheel CLI feature drift against source CLI surfaced during PDF/X-4 smoke tests.
- Impact: installed wheel command accepted `--pdf-profile pdfx4` but rejected newer flags (`--output-intent-*`, `--watermark-semantics`), reducing standards-control in user installs.
- Workaround used: smoke-test with currently supported wheel flags, validate XMP `pdfxid:part=\"4\"` marker in output, and mark packaging sync as launch blocker.
- Status: resolved in freshly rebuilt wheel (`target/wheels/fullbleed-0.1.0-cp311-cp311-win_amd64.whl`) where these flags are present.

20. Watermark layer vocabulary is stricter than common CLI expectation.
- Impact: `--watermark-layer underlay` fails; only `background|overlay` are accepted.
- Workaround used: use `--watermark-layer background` for under-content placement; document accepted enum explicitly in examples/help.
- Status: resolved in CLI by accepting legacy `underlay` alias and normalizing it to `background`.

21. PDF/X-4 strict path has two hard prerequisites that are easy to miss.
- Impact: render fails when output intent metadata is provided without `--output-intent-icc`, and fails again if document falls back to non-embedded base fonts (for example Helvetica).
- Workaround used: provide `--output-intent-icc` plus an embeddable font asset (`--asset @noto-sans` + CSS `font-family`).
- Status: partially improved in CLI with earlier validation for missing `--output-intent-icc` and actionable hint text when pdfx4 fails on non-embedded fonts.

22. Compiler input manifest does not currently record watermark configuration.
- Impact: `--emit-manifest` output omits `watermark_*` fields, so machine consumers cannot fully reconstruct/review watermark intent from manifest alone.
- Workaround used: rely on CLI args/log capture externally; keep this as a machine-contract hardening item.
- Status: resolved; manifest now includes a `watermark` object (`text|html|image|layer|semantics|opacity|rotation|enabled`).

23. CLI source-vs-installed command ambiguity can skew audit results.
- Impact: `python -m fullbleed_cli.cli` may resolve to installed site-packages instead of local source tree, producing mismatched command surfaces during validation.
- Workaround used: run source audits with `PYTHONPATH=python` and wheel audits in isolated venvs.

24. Cache prune test has timing-sensitive flake behavior.
- Impact: `test_cache_dir_and_prune` intermittently observed empty dry-run result (`max_age_days=0`) during full-suite execution despite passing on immediate rerun.
- Workaround used: rerun isolation to confirm behavior and classify as stability risk for CI gating.

25. USPS IMB font licensing is not yet machine-verifiable in current asset workflow.
- Impact: IMB fonts present in `examples/` cannot be safely promoted to auto-installable registry assets without explicit policy/legal sign-off.
- Workaround used: keep IMB as manual user-supplied assets and prioritize OFL barcode families for automated install path.

26. Naive agents may choose global-cache asset install path instead of project vendoring.
- Impact: when run outside a project root, `assets install` defaults to cache and agents can infer vendoring is not first-class.
- Workaround used: accept builtin refs with or without `@` (for example `bootstrap` and `@bootstrap`) and emit explicit non-project install hint to run `fullbleed init` for default per-project vendoring; added JSON install scope metadata and README clarification.

27. Hardcoded cache path + synthetic mock file can produce false-positive "bootstrap installed" signals.
- Impact: a script using `%LOCALAPPDATA%/fullbleed/cache/pkgs/...` loaded a 26-byte mock CSS fixture (`/* bootstrap 5.3.3 mock */`) instead of real Bootstrap (`cache/packages/...`), resulting in mostly unstyled output while appearing to succeed.
- Workaround used: use `fullbleed assets install <pkg> --json` and consume `installed_to` instead of constructing cache paths; verify bootstrap content (for example contains `--bs-body-font-family`) or run `assets verify` before render.
