Skip to content

Releases: lazymaniac/hologram

v0.17.0

Choose a tag to compare

@github-actions github-actions released this 02 Sep 04:12
b86a3e9

Theme: only what cannot be read somewhere already.

Removed

  • Constructors. A ctor line stated that a type can be constructed, which its
    own header already implies; where its arguments differed from the field list
    it stated a construction contract, but never the project's purpose. It cost
    4.6% of a 16,000-file Java map, 4.0% of a Java example corpus and 3.8% of a
    Spring one — more than all five markers put together — and had no --features
    name because it lived in the always-on signature remainder.
  • The tested marker, and the tested fact class with it. It discriminated
    wildly by corpus — landing on 42% of callable lines in one repository and 1
    line in 312 in another — and two thirds of its cost on a large map was the
    lossless grouping it prevented rather than the marker's own characters. The
    reachability it displayed is still computed and still ranks a tested call path
    above every other chain in the budget; it is simply no longer rendered.
  • Individual test case names. ? tests now states which files hold tests and
    what reusable support they expose, and nothing inside them. Case names were the
    single most expensive thing in the map — 34% of a 16,000-file corpus, 78% of
    this repository's own — for a fact an agent reads in the file the landmark
    already points at. Helper and fixture names stay, because those are what
    another test file consumes without opening anything.

Together these take 39.8% off a 16,000-file Java map (56,336 → 33,915
tokens), 12.9% off a Java example corpus, 14.3% off the javamini fixture and
78.2% off this repository's own map.

v0.16.0

Choose a tag to compare

@github-actions github-actions released this 01 Sep 21:03
13692be

Theme: a name says only what the reader's position does not.

Added

  • --features params. Parameter names were 14–24% of a real map and were
    the one large fact class with no name, because they sat in the always-on
    "identity" remainder alongside the trie and the type headers. They are a fact
    about the code, not the map's structure, so they are selectable now.
    Deselecting keeps arity and drops only the names — place(order,items)
    becomes place(_,_), reusing the placeholder the renderer already emits for
    an argument no extractor could name — and takes about 7% off a map that keeps
    everything else.

Changed

  • Grouped landmarks take the declared extension too. {ItemId,OrderId}.java
    now renders {ItemId,OrderId} under a # hologram ·.java header, like every
    other leaf. They had been exempt so that payload naming files could tell a
    reader the bare node above it was a directory — which cost the hoist most of
    its value exactly where it pays best, on the one-public-class-per-file
    languages whose every landmark is grouped. Worth 3.9% of the javamini
    fixture, 0.7% of a Spring corpus and 0.5% (306 tokens) of a 16,000-file Java
    codebase. The reader's rule is now simply that a node with nodes below it is a
    directory; a directory whose files are all grouped landmarks reads as a file,
    measured at about one node in fifty, and never silently — the reconstructed
    path does not exist while the directory does.
  • Call targets are named relative to the caller. The description ladder
    picked the shortest name that is unambiguous across the whole project, which
    is the right question to ask once and the wrong one to answer on every line:
    a chain inside a/b/Order.java that read > a/b/Order.java:Order.total
    spent 24 characters restating the node the reader was standing in. A target
    now carries only what the caller's own path, file and owner do not already
    say. Worth 7.9% of a monorepo of near-identical services, 2.4% of a Java
    example corpus, and 1.2% — 699 tokens — of a 16,000-file Java codebase. Two
    targets that would shorten to the same text both keep their project-wide
    names, so one name never stands for two.

Fixed

  • Framework-wired code is no longer reported as dead. ×0 means no static
    project reference, and a container's wiring is invisible to static fan-in, so
    Spring stereotypes and @Bean factories, JSR-330 @Named/@Inject,
    @PostConstruct/@PreDestroy lifecycle callbacks, JPA @Entity, and Spring
    AI/MCP @Tool surfaces now join routes, listeners and schedulers as
    entrypoints. On a Spring AI corpus this removed 63 of 113 ×0 markers — a
    @Configuration @EnableWebSecurity class and every @Bean factory had been
    reading as deletable — and made the map 38 tokens smaller in the process.

v0.15.0

Choose a tag to compare

@github-actions github-actions released this 31 Aug 17:11
09b82b7

Theme: you choose the facts, and the map stops repeating itself.

Added

  • --features selects which fact classes the map carries. A budget decides
    how much of the map fits; it could not say what was eligible in the first
    place.
    Twelve named classes (calls, relations, fields, constants,
    decorators, raises, tested, usage, size, private, tests,
    support) can now be dropped whole, with types making thirteen. Gating
    happens at each render site before the budget catalog, so a deselected class
    never enters the adaptive search and cannot be restored by it. The package
    trie, type headers, and public signatures are the map's identity and stay
    unselectable; --features none leaves exactly those. The selection is stamped
    in the footer and recalled like --lang and --budget, and --interactive
    on build/init prices a selection against the full map before writing it.
  • --features types. Declared return and parameter types are now a
    selectable fact class, closing a gap between the feature catalog and the
    structure floor: L8 already stripped them, but nothing named them. They cost
    1.0% of this repository's map, 2.8% of a TypeScript corpus and 5.1% of a Java
    one — more than seven of the twelve classes that were already selectable.
  • L8, a structure-only floor below the semantic floor. When even L7 cannot fit a
    --budget, Hologram now renders the same facts in project vocabulary alone: return
    and parameter types, decorators and route paths, !throws, ~N//×0 markers,
    {field} lists, and : super / ←impls / sealed: relations all go, leaving the
    source tree, type names, and function names with their parameter names. On this
    repository the floor drops from 714 to 460 tokens. Ranked whole facts still compete
    for slack above it, and the previous "no complete map fits" fallback now runs only
    when L8 overflows too. BudgetStats.skeleton_tokens keeps meaning the L7 semantic
    floor; effective_detail reports L8 or L8-adaptive:n/m.

Changed

  • The extension a map repeats is declared once. A title line such as
    # hologram ·.py states the corpus extension, and the file nodes that carry
    it render bare; a leaf that states an extension has exactly the one it
    states. Worth 1.2–1.5% of a real map (57 tokens on a 4,936-token TypeScript
    corpus, 95 on a 6,220-token Java one) and nothing where it would not pay: a
    stem another node already owns (extract/ beside extract.py), a stem still
    holding a dot (shell.component), and corpora too small or too mixed to earn
    the declaration all keep their extensions. Grouped landmarks
    ({ItemId,OrderId}.java(R{value})) keep theirs too, which is what tells a
    reader the bare node above them is a directory.
  • The test index states landmarks and support, never call targets. The
    > target +N coverage edge is gone: it spent tokens naming one arbitrary
    target and counting the rest, and what a test file exercises is already
    legible from the case names it carries. ? tests now holds exactly test
    classes, test functions and methods, helper classes, helper functions, and
    declared fixtures.
  • Fixtures and shared helper functions are named. A fixture qualifies by
    declaration (@pytest.fixture, @BeforeEach, @Rule, …) because the
    framework injects it by name rather than calling it; a plain function has to
    be used by another test file. Teardown markers earn no name. Both render in
    the existing * group, whose legend clause is now *=helper/fixture.

v0.14.0

Choose a tag to compare

@github-actions github-actions released this 21 Aug 11:01
60b471f

Theme: the map states what it costs.

Added

  • The footer carries the corpus and map token counts.
    · 19,311 LOC · input 215,433 · output 5,999 tokens · state … · budget …
    input is the estimated token count of the scanned sources, output the
    estimated count of the map itself. The block is always loaded, so what it costs
    and what reading the sources instead would cost now travel with it. output is
    measured on text that contains output, so the render iterates the footer to a
    fixed point; where a token boundary makes two candidates alternate, the larger is
    stated — the map never claims to be cheaper than it is.

render_simple gained an optional source_tokens parameter alongside loc,
precomputable by callers and computed locally when omitted. Freshness and settings
readers are unchanged: LOC stays the footer's first field, which is how the
metadata line is located, and legacy metadata-bearing headers still parse.

The new fields cost nine tokens per map, flat.

v0.13.0

Choose a tag to compare

@github-actions github-actions released this 21 Aug 10:42
dcbc9e0

Theme: the floor is business logic only.

Changed

  • The semantic floor drops the test index entirely. At the deepest budget level
    the ? tests section is absent — header, file landmarks, helper names, and
    test-to-business edges alike. Test file landmarks used to be unconditional floor
    content, so the tightest budgets paid for test orientation before business API.
  • Test file landmarks are now individually restorable facts (test-files), ranked
    and admitted like any other optional fact above the floor. Admitting a suite/case
    label or a coverage edge also admits the landmark line it renders on, so a restored
    name never arrives without the file it belongs to.

Nothing changes for unlimited maps or for budgets that comfortably fit the index; the
difference appears only when a budget binds. On this repository the floor drops from
759 to 701 estimated tokens; corpora with hundreds of test files recover far more,
since the index is proportional to the test tree.

hologram stats reports the new test-files category alongside the existing ones —
the schema grows additively.

v0.12.0

Choose a tag to compare

@github-actions github-actions released this 20 Aug 20:22
f512a3c

Theme: the test index costs what it is worth.

Changed

  • ? tests renders through the same path-compressed trie as the source section.
    Test files used to carry their whole relative path on every line, so a deep package
    tree restated one prefix hundreds of times. Directories are now stated once and the
    file landmark sits under them.
  • Wrapped case names no longer pad to the length of their path. Continuation lines
    indent one level instead of aligning under an eighty-character prefix, which on a
    deep tree made the section half whitespace.

Both are representation changes: file landmarks, suite names, case names, helper
names, and test-to-business edges are byte-for-byte what they were, and the source
section is unchanged. On a 114k-LOC Java corpus with 293 test files the ? tests
section drops 56% (140,913 to 61,788 characters) and the whole map goes from about
60,600 to about 40,900 estimated tokens. Repos whose tests sit in one shallow
directory see little change.

v0.11.0

Choose a tag to compare

@github-actions github-actions released this 16 Aug 15:44
9c85bbb

Theme: more business-logic signal per always-loaded token.

Added

  • Semantic whole-fact budgeting v2. Optional facts now compete globally above a
    compact pushed floor. Tested and cross-file call paths, test-to-business edges,
    high-fan-in APIs, and breadth across source files outrank local private leaves.
    Method-call facts retain their owning method as a dependency, and every admission is
    still checked by rendering the complete digest against the hard digest ceiling.
  • Managed-context accounting. CLI output, stats/stats --json, and benchmark
    rows distinguish digest, wrapper, coaching, and total managed-block estimates. This
    keeps the historical digest budget contract while exposing the full context cost an
    agent actually receives.
  • Inspectable selection reasons. Budget statistics add deterministic retained and
    dropped reason counts while preserving existing fields additively.

Changed

  • Production landmarks now resolve to exact files. Conventional one-type files retain
    lossless cross-file shape grouping ({A,B}.java(...)), while multi-entity modules
    use explicit file nodes.
  • Repeated names are factored in signatures, fields, relationships, re-exports, and
    call targets only when the notation is shorter. A private inventory entry is omitted
    only when the same exact target remains visible in a selected call chain.
  • Tests retain one actionable landmark per file plus compact coverage/helper hints.
    Every recognized test function/method name and suite is shown by default to
    discourage duplicate coverage. Names are factored losslessly, same-named methods in
    different suites gain their suite owner, and every additional nonredundant label
    remains individually droppable when a tight budget needs to preserve business logic
    first. Root tools and benchmark code gets separate compact orientation instead of
    competing with business internals.
  • Volatile LOC, freshness state, filters, targets, and budget metadata moved to the
    final digest line. Existing header-form maps remain readable, while unchanged
    semantic prefixes can now be reused by prompt caches.
  • The fixed embedding note and budget omission warning are shorter and make no claim
    that an optional fact survived selection.

Validation

  • On Hologram's own test-heavy repository, retaining all 633 recognized case/suite
    names raises the deterministic full estimate from v0.10's 3,621 to about 8,260
    digest tokens and from 3,769 to about 8,370 managed-context tokens. This is an
    explicit duplicate-avoidance tradeoff; the compact floor still falls from about
    1,444 to about 760, and explicit budgets can drop every additional test-name label
    independently while keeping file landmarks. Full-grammar fixture estimates remain
    below v0.10 managed-context baselines. These are representation measurements, not a
    claim of improved model outcomes; the earlier matched evaluation predates this
    test-inventory change.

v0.10.0

Choose a tag to compare

@github-actions github-actions released this 15 Aug 08:08

Theme: make token choices and effectiveness experiments inspectable.

Added

  • Adaptive whole-fact budgeting. After the least-degraded complete L0–L7
    map fits, Hologram deterministically restores individual facts from the next
    quality boundary. Every trial measures the complete output, facts remain
    indivisible, the entrypoint skeleton stays mandatory, and a fixed trial
    bound keeps hook latency predictable. Adaptive headers use A<level> and
    structured stats identify the exact selection.
  • hologram stats [--json] reports the budget policy version, selected,
    full, and skeleton token estimates, fit/utilization against the deterministic
    characters-per-four estimator, effective detail,
    and retained/dropped fact bundles without modifying a context file.
  • Structured review findings. hologram review --json emits stable finding
    IDs plus check, kind, subject, path, and detail. The Python API can compare a
    baseline and final review as seen, attempted, or resolved; normal human
    review output remains unchanged. API drift now preserves overload sets and
    covers public kind, signature, field, relationship, mapped decorator/route,
    throw, constructor, and constant-value changes.
  • Resumable benchmark blocks. Schema-v3 results identify the immutable
    experiment, treatment/control pair, cell, task, judge configuration, corpus, tool, and
    runner mode. --resume skips only when every planned cell in a task/repetition
    block is terminal, evidence-intact, and from the same wave/model; otherwise it
    reruns the whole block. Failed attempts remain append-only evidence. Referenced
    stdout and stderr artifacts are fsynced, sized, hashed, and verified before a
    block can satisfy resume.

Changed

  • Benchmark condition order is seeded and counterbalanced. Reports compare
    every selected treatment (A, AC, or AR) with B on matched
    task/repetition pairs, list incomplete pairs, summarize numeric fields
    with median ± MAD, and keep fresh, cache-created, and cache-read input tokens
    separate. Structural accept_cmd evidence is labelled as such; tasks can
    carry manual_only and versioned judge metadata.
  • Eligible AR rows capture sanitized finding IDs during the existing
    post-commit review pass, compare their deduplicated union with the final
    working tree, and report resolved, persisting, and new-final counts. This is
    an identity-based final-state measure, not a correctness or attempted-action
    claim; finding content and IDs never enter the aggregate report.
  • Real benchmark sessions require --allow-unsafe-host, an explicit
    acknowledgement that the agent runner is not a filesystem, credential,
    process, or network sandbox. Dry and real cells cannot share resume IDs.
  • Acceptance commands declare disjoint pass/fail exit codes; undeclared exits
    are judge infrastructure errors. Provider terminal events must satisfy the
    metrics protocol, dry runs execute no acceptance shell, unknown task fields
    fail before spending, and repeated global or same-condition infrastructure
    failures open a circuit breaker.

Security

  • Release preparation audits index blobs and non-ignored working-tree files
    separately, plus built archives, against private-only paths and an optional
    external denylist.
    Release-artifact publication remains hard-disabled until repository-history remediation
    and a clean-clone privacy audit are complete.

Validation

  • Adaptive selection, structured review schemas, exact resume compatibility,
    atomic result persistence, matched reporting, parser completeness, and the
    release privacy gate have synthetic/public-only regression coverage. This
    release makes no unmeasured claim that a prompt or hook timing improves agent
    behavior.

v0.9.0

Choose a tag to compare

@github-actions github-actions released this 14 Aug 13:35

Theme: clever token budgeting. --budget maps are unchanged at L0 — this
release only changes what happens under pressure. Unbudgeted maps are
byte-identical to 0.8.0 (verified on three corpora, modulo the state
stamp).

Added

  • Makefile supportMakefile/makefile/GNUmakefile/*.mk render
    as one node with each target as a command carrying its caller-settable
    variables: deploy(ENV,MANIFEST) means the recipe consumes $(ENV)
    (overridable ?= or undefined) and $(MANIFEST); variables the file
    pins with =/:= are internal and excluded. .PHONY and friends,
    pattern rules, and define bodies are skipped; _name targets are
    private. No parser dependency — a line scanner, like Helm.

Changed

  • The degradation ladder is repaired and deepened to a skeleton floor.
    The old ladder was lumpy (one level dropped −1,921 tokens on the
    reference corpus while another dropped −116), partly broken (the private
    wipe left per-class - name lines at every level), and shallow (floor
    −17%; an 8k budget was unreachable). The new ladder (measured per-level
    on the reference corpus): L1 coverage edges (−5%), L2 helper signatures
    (−8%), L3 all private inventories (−8%, bug fixed), L4 chains of
    untested functions (−6%, replaces the no-op), L5 methods of types with
    zero real fan-in (−3%, replaces the name-keyed heuristic), L6 all chains
    (−4%), L7 the skeleton — no method lines, const values gone, type
    headers with fields and top-level signatures stay (−21%). Floor on the
    reference corpus: 7,138 tokens, −54% from the full map. Every level
    is monotone; facts degrade in usefulness order; the legend only explains
    what survived; nothing is ever cut mid-fact.
  • Const values survive to the skeleton, and degraded maps disclose
    their losses.
    The first gate round dropped const values at L1 — the
    smallest saving (−0.3%) — and produced the worst failure: agents
    confidently answered value questions off a map that silently omitted
    the values. Now scalars ride to L7, and every degraded map carries a
    header disclosure naming the dropped fact classes with an instruction
    to read the source instead of guessing — measured to flip wrong
    zero-read route answers into correct one-read answers.
  • The budget ladder no longer re-reads every source file per level
    (level-invariant work — LOC count, call resolution, helper detection —
    is computed once).

Dev

  • Benchmark task files accept a top-level budget, applied to the
    map-bearing conditions' build.

Gates (measured before merge)

  • Determinism, monotonicity, floor reachability: pass (numbers above).
  • Refactor invariance: unbudgeted digests identical to v0.8.0 on the
    reference corpus, this repo, and the polyglot fixtures.
  • Navigation at the skeleton floor: see benchmark/README.md.

v0.8.0

Choose a tag to compare

@github-actions github-actions released this 14 Aug 12:05

Theme: cheaper without being smaller. Every change was built behind a
measured merge gate (see benchmark/README.md); one feature — pre-commit
review timing — was built, measured, and reverted for showing no
behavioral gain.

Changed

  • Token diet, same facts — three same-fact-twice redundancies removed
    (reference corpus −3.7%, self −0.7%, zero information loss):
    constructors whose argument list restates the type header's field list
    (PricingEngine(basePrices) under PricingEngine(C{basePrices})) are
    suppressed, including the grouped Self(fields) form — any constructor
    carrying notes, ✓, sizes, throws, calls, or typed args stays; dunder
    methods (__init__, __repr__) leave the private inventories;
    the test index folds a file whose only test class matches its name
    (PricingEngineTest>applyDelta+2, no braces) and states a shared file
    extension once in the header (? tests ·.java).
  • The · deps block is gone. It was a coarser restatement of the call
    chains, degenerated on shallow repos, and outlived richer facts under
    --budget. Gate evidence: all navigation/architecture answers stayed
    correct at 1 turn without it.
  • Coaching sentence now says what to do with review findings (reuse
    the named original, consolidate re-covered tests) instead of just naming
    the command.

Measured and reverted

  • Pre-commit review timing. Review was moved to a pre-commit hook so
    findings would land before the commit; the gate round showed the
    reviewer firing identically — and, at low effort, agents acting on the
    findings exactly as often as post-commit: never. The post-commit form
    ships unchanged; the new acted_on_findings bench metric stays for 0.9.

Dev

  • Benchmark: acted_on_findings transcript metric (review report →
    later edit of a file the findings named → later commit).