Skip to content

v0.9.0 - the brand-intelligence release

Choose a tag to compare

@ferdinandobons ferdinandobons released this 10 Jun 10:41
· 4 commits to main since this release

[0.9.0] - 2026-06-10

The brand-intelligence release: derived indexes that never lie (rich TOC
cache, empty rebuilds), multi-template profiles (extract --blend), the
cross-template drift report (compare-profiles), a guided authoring surface,
a local-corpus fidelity benchmark, and a 31-finding general-review hardening
wave on top.

Fixed

  • General-review wave (multi-agent, 31 confirmed findings). Engine: the
    heading-less generation now collapses a bare multi-paragraph outline TOC's
    FULL span to an empty field (the plain writer used to leave the template's
    demo entries and orphan the end fldChar - a regression of the rich-TOC
    delta); pptx and xlsx extraction now parse the theme a:fontScheme latin
    typefaces instead of hardcoding latin=null (the docx extractor already
    did); schema.validate returns problems instead of raising on a
    hand-edited blend ledger with mixed-type entries; profile JSON/sidecar
    writes are atomic (same-directory temp + os.replace), making the blend's
    byte-identity-on-failure claim true under ENOSPC/kill; OOXML unpack/
    read_part reject decompression bombs (per-part and per-package declared
    inflated-size floors); the corpus runner exits 1 on verify exceptions, not
    just clean failures. Examples: the three builders now consume ONE complete
    12-slot brand clrScheme from _brandlib (docx/pptx/xlsx had drifted apart
    on five supporting slots - caught live by compare-profiles - and the
    shipped pair now reports zero theme drift, pinned by a strengthened CLI
    test that replaced a tautological assertion). Docs: README test count and
    blending/compare teaching, CONVENTIONS gains the engine verb surface and a
    §16 blend/compare vocabulary, the Pages site's broken README anchor and
    stale install command fixed, a real brand word in ROADMAP replaced with a
    placeholder.

  • The refreshed outline TOC cache is now a real Word-shaped TOC (REFLECTIONS
    P3).
    The visible cache of a preserved or authored outline table of contents
    was rewritten as flat plain-text entries: one style for every level, no
    links, no page-number fields. The rewrite now authors deterministic
    bookmarks on the generated headings (_TocBD000001 sequential,
    collision-scanned ids), harvests a per-level paragraph-style map from the
    template's OWN cached entries (trailing-digit TOC style convention,
    indentation-rank fallback, nearest-lower-level chain), and emits each entry
    as hyperlink-to-bookmark + tab + nested dirty PAGEREF, so previews show
    the template's real per-level TOC styling and Word fills page numbers on
    open. The bare-paragraph TOC path converges to the same multi-paragraph
    shape. Fail-closed: a malformed cache falls back to the previous simple
    rewrite atomically; documents without an outline TOC author zero bookmarks
    and stay byte-identical (now pinned by a dedicated TOC-free frozen anchor;
    the historical anchor was deliberately recomputed because the committed
    fixture itself contains an outline TOC, so its cached-TOC bytes necessarily
    changed shape).

  • Template demo entries no longer survive in derived indexes the content did
    not feed.
    A kept caption index (table-of-tables / table-of-figures) whose
    sequence received no captions, and an outline TOC in a heading-less
    generation, used to keep the template's cached demo entries (the "stale
    derived index" defect class, visible in every preview renderer). Both caches
    are now rebuilt EMPTY: the field code survives, dirty, so Word recomputes it
    on open, but fabricated entries never reach the generated document. The
    destructive-action floor is untouched: structure is still never removed
    without corroboration; only the visible cache is honest now.

Added

  • Local-corpus fidelity benchmark (REFLECTIONS P3). New
    scripts/corpus_benchmark.py walks a corpus of REAL templates that lives
    outside the repository (and refuses one inside it), runs
    extract -> verify -> brand-agnostic probe generate -> QA per template in a
    throwaway directory, and writes a dated report.{md,json} next to the
    corpus with the LibreOffice-vs-Word caveat stated in the header. The probe
    input is typed blocks only (no styles, colors, fonts), so the corpus
    measures the engine without ever tuning it; documentation/DEVELOPMENT.md
    documents the layout. CI smokes the runner on the synthetic example
    template.
  • Authoring intelligence for the IntermediateDocument/GridDocument
    (REFLECTIONS P3).
    The least-guarded stage (what the authoring agent puts
    IN the input) now has a guided surface: PROFILE.md gains three
    format-uniform sections rendered by the new shared common/profilemd.py
    (the role table on all three formats - pptx/xlsx previously shipped a
    two-line stub - a "Brand palette roles" table naming the semantic color
    tokens an author may reference, and "Authoring hints" that advertise
    comprehended fragments when present); each skill's SKILL.md gains an
    "Authoring the IntermediateDocument/GridDocument" section with role-first
    composition rules (skeleton order, heading hierarchy the TOC regenerates
    from, captions so derived indexes stay real, native objects on pptx, region
    bounds and formula preservation on xlsx, color discipline, fragments before
    re-derivation). Advisory by construction: nothing here adds engine
    authority, the resolver remains the only author of values.
  • Multi-template profile blending (REFLECTIONS P3, the quality-ceiling
    lift).
    extract --name X --template second.docx --blend folds a SECOND
    same-format template into an existing profile at the VALUE-fact level: it
    fills captured facts the primary left unset, corroborates agreeing facts
    with a bounded deterministic confidence boost, and keeps the primary's value
    on every conflict. Artifact POINTERS (style ids, layouts, anchors,
    numbering) never cross shells: generation still opens the PRIMARY shell and
    the resolver still membership-validates everything against it, so the brand
    guarantee is untouched. Fail-closed all-or-nothing transaction (a rejected
    blend leaves profile.json byte-identical), sha-deduped and idempotent
    (re-blending the same file is a no-op), secondary shells stored
    content-addressed next to the primary with provenance, guarded by the new
    blend_shell_provenance QA check (donor tamper/drift = ERROR). Single-
    template profiles serialize without one new key and both frozen generation
    anchors are unmoved. Same-format only by design; cross-format stays the job
    of compare-profiles.
  • compare-profiles: the cross-template drift report (REFLECTIONS P3).
    New read-only CLI verb that compares the BRAND-level facts of two saved
    profiles: theme colors per slot, theme/captured fonts, semantic palette
    roles, and off-theme usage (a raw hex in one profile that is a theme slot in
    the other - the sharpest "one template is off-theme" signal). Structural
    facts (styles, layouts, anchors) are never compared as drift: they are
    per-shell by design; role coverage is reported as information only. Writes
    nothing; exits 1 on brand-level drift so it can gate brand coherence in CI.
    First live run immediately caught a real inconsistency between the shipped
    docx and pptx example templates (five theme slots disagree) - queued for the
    next example-template refresh.
  • Contributor onramp (REFLECTIONS P1). CONTRIBUTING.md expanded from a
    10-line stub to the full gate (dev setup, the three test lanes, the seven
    non-negotiable rules, PR checklist, sized first contributions);
    scripts/brandkit/README.md created as the engine internals map (module
    layout, the ten verbs' call paths, the two invariants, the recipe for a new
    capture axis); the release checklist written down in
    documentation/DEVELOPMENT.md; three sized "good first issue"s opened.
  • PLUGIN_WORKFLOW drift guard. documentation/PLUGIN_WORKFLOW.md now
    documents the full ten-verb CLI surface and the learning loop
    (generation_report.json -> learn/propose-overrides -> --accept) in the
    end-to-end diagram; tests/test_doc_drift.py fails the build if a CLI verb
    or a commands/ slash command is missing from the document.