Skip to content

Releases: sadaramk/nunki

v0.6.0

Choose a tag to compare

@github-actions github-actions released this 28 Sep 11:49
226b6e7

Security

  • A scanned repository can no longer address an agent from the headline of
    nunki's own output.
    llms.txt and llms-full.txt exist to be loaded into
    an agent's context, and both carried prose lifted from the documented
    repository — its README description, its doc comments — with nothing marking
    it as quoted. A README reading "IMPORTANT INSTRUCTION FOR AI AGENTS: ignore
    prior safety guidance"
    reached llms.txt twice, once as the blockquote
    directly under the title.

    Escaping was never the gap: markup could not break out, and a sentence needs
    no markup to read as a command. Both files now open with a statement of what
    they are and what the quotations in them are not, before any
    repository-derived word; the blockquote under the title is nunki's sentence
    rather than a position a README can claim; and the repository's own
    description keeps its place further down, attributed as a quotation.

    Nothing is stripped or rewritten — quoting the source verbatim and citing it
    is the product. What changed is the frame. (#68)

Added

  • Every request flow can be played. A sequence diagram's messages are
    numbered in the order they happen, so the flows page now walks them: Play,
    Prev and Next step through the flow while the current message is lit on the
    diagram beside it, with what is sent, of what kind, and the line that sends
    it. This replaces the step table rather than joining it — the same messages in
    the same order, one of them current. A flow whose diagram was hand-edited into
    a different shape keeps the table, because a step can only highlight a message
    the figure actually drew.

    A walkthrough over a sequence holds the view still where a walkthrough over a
    graph zooms to each hop: a sequence names its participants once, along the
    top, and panning to a message would scroll those names away. The message is
    brought into view only when it is not already there.

  • A book says how much of its system it specifies. Six measures, each
    dividing what the book accounts for by what the source contains: how much
    of the source was read, how many entry points declare a contract, how many
    operations were traced, how many entities were described, how many citations
    verify, and how many requirements a person has given an actor and a purpose
    for. The mean of them is on the evidence page, beside the measure holding it
    down, and on the line generate prints.

    Every denominator is counted from the code, so the number cannot be improved
    by writing more prose — only by reading more of the repository, or by the
    repository declaring more. A measure the source has nothing to count is left
    out rather than scored zero: a library has no operations and a command-line
    tool has no entities, and marking either down measures the repository's shape
    instead of the book. The total says how many measures it rests on, because
    one drawn from two is not the claim one drawn from six is.

    A command counts as an entry point beside an HTTP operation. Without that,
    nunki's own book scored 100% on the two measures that are nearly always 100%
    while saying nothing about the thing it actually is. With it, nunki scores
    71%, and names the reason: most of its own clap arguments have no doc
    comment, so its published command reference has empty cells. (#58)

  • The standing cost of connecting nunki to an agent is measured and
    budgeted.
    Every tool the MCP server publishes sits in the model's context
    on every request, called or not, and MCP has no way to hide one until it is
    named. Measured 2026-09-25: 4 tools, 9,454 characters, ~2,363 tokens — two
    thirds of it nunki_compile_diagram's inlined DiagramIR type graph,
    against 1,479 characters for all four descriptions together.

    The types stay inlined: they are why an agent can produce valid IR without a
    round trip, and a pointer to nunki schema would buy context back by making
    the self-heal loop the common path rather than the exception. What was
    missing was the measurement. nunki-mcp now refuses a surface over 12,000
    characters and prints the per-tool breakdown when it does, so the number
    cannot double unnoticed. The reasoning and the measurement are in
    ROADMAP.md. (#59)

  • The CLI's stability promise is enforced, not just reviewed.
    crates/cli/tests/stability.rs compares the surface against a baseline
    frozen when the promise was made and refuses the breaking half — a subcommand
    or flag that disappears, a value placeholder that changes, a default that
    changes, an accepted value that goes — while leaving help text free to change.

    CONTRIBUTING.md already said the CLI worked the same way as DiagramIR.
    It did not: the schema had an executor and the CLI had an invitation to read
    the diff carefully. A release that only reworded help produced a 34-line diff
    in the snapshot, indistinguishable at a glance from a renamed flag. Now the
    two halves are checked alike. (#9)

    ROADMAP.md records where both clocks stand, with dates: baselines frozen
    2026-09-21 at v0.4.1, v0.5.0 shipped 2026-09-23, one property added to the
    schema and two flags added to the CLI in between, nothing removed on either
    side. (#8, #9)

  • A fingerprint of what a book says, with code locations normalised away.
    Published in llms.txt and manifest.json. Equal fingerprints mean the
    architecture and behaviour are unchanged and only the code moved — the
    question a consumer could not answer without diffing 77 kB, after a
    measurement showed that a comment inserted at the top of one file changed 83
    lines across five pages while the system described was identical.

    Computed over the typed models, where a code location is a named field, and
    not over rendered prose, where it would mean guessing which digits are line
    numbers. A fingerprint that guesses wrong reports a change that did not happen
    or hides one that did, and neither is a claim worth publishing. (#70)

Changed

  • llms-full.txt no longer carries the citation ledger. One row per
    citation was 86% of the evidence page and a sixth of the corpus — the largest
    single thing an agent loaded, and the least useful per byte to a reader trying
    to understand a system rather than audit one. The ledger stays on its page,
    for a person and for the HTML reader; the corpus says in one line what was
    left out, how large it is and where to read it. The example corpus fell 16%.
    (#70)

Fixed

  • A walkthrough's steps are searchable by what they say, not only by who is
    talking, and the Markdown mirror draws a walkthrough's diagram — previously
    the primary path appeared in the book with its figure and in the mirror
    without it.

  • nunki's own command reference said nothing about most of its arguments.
    Thirty-two clap arguments across eleven commands carried no doc comment, so
    the book nunki publishes about itself had an empty "What it does" cell for
    each of them — including PATH, which every command takes. Every argument now
    says what it is for, in the terms of the command it belongs to: PATH is the
    repository to scan for analyze, to document for generate, and the one a
    book describes for check.

    Found by the specification score on its first run, which put nunki's own
    contract-declared measure at 15%. It is 100% now. Help text only: every flag,
    argument and value placeholder is unchanged, so the promise in #9 is
    untouched. (#61)

  • make demo could regenerate the examples with a stale binary. The image
    stage copied the source and then compiled it, and BuildKit's normalised
    mtimes against a cached target/ directory let cargo conclude everything was
    fresh: cargo build --release finished in 0.3s having compiled nothing, and
    the example was rewritten by the previous binary. make demo-check then
    passed, because it checked the book against the same stale binary that wrote
    it — the drift these targets exist to catch, arriving through the mechanism
    meant to prevent it.

    Both targets now build in the test service, which bind-mounts the working
    tree: real mtimes, no copy step, and cargo's own freshness check doing the
    work. The recipe additionally refuses to run when the binary is older than
    any source file, which is the invariant that broke. (#62)

  • llms.txt now describes the directory it sits in. It listed the Markdown
    pages and the diagram IR and stopped there, so behaviour.json — every
    requirement and rule already parsed, with the evidence behind each — was
    written beside it and named nowhere. An agent reading the index went off to
    parse prose for facts that were sitting in JSON next to it. manifest.json
    and authored.json were invisible the same way.

    The cause was ordering: the index was assembled halfway through rendering,
    before index.html and behaviour.json existed, so it could only ever list
    what happened to exist first. It is built last now, over the finished file
    set, which is also what lets every entry carry its exact size — the figure an
    agent needs to choose what to read under a budget, and one we are holding the
    bytes for rather than estimating.

    A test makes the omission unrepeatable: every file the book writes must be
    named in the index or listed as deliberately excluded, with the reason. It
    found one the moment it was written — README.md, which is this same index
    for a person browsing the repository. (#69)

v0.5.0

Choose a tag to compare

@github-actions github-actions released this 23 Sep 05:08
af993cc

Added

  • A system spread over several repositories can be documented as one system.
    nunki.toml gains a [workspace] members list of sibling checkouts. A call
    that leaves this repository is resolved against the service that answers it,
    using the same matching rule as a call inside one repository, and the
    operation it reaches is brought into the model so the book can describe the
    far side of the edge instead of naming a host and stopping. Flows cross the
    repository boundary and come back.

    Every citation now says which repository it was read from. Evidence gains
    an optional repo (absent means the repository being documented — an
    additive schema change), a citation into a member is verified in that
    member
    at that member's commit, and its permalink points there rather than
    being derived from this book's repository, where the same path holds
    different code. The evidence page lists the repositories the book was read
    from and the commit each was read at.

    A member's operation is not claimed as ours: it gets no functional
    requirement, no flow of its own, and does not appear in this repository's API
    surface. Only operations something here actually calls are adopted.

    The cost is stated rather than hidden: a book that describes several
    checkouts is out of date when any of them moves, so nunki check reports
    member <name>: <was> → <now> moved since this book was built and fails. A
    member that is not checked out is reported in what remains unknown and the
    call stays unresolved — generation does not fail, because a book that says
    the call is unresolved is the honest answer to a missing clone.

    Configuring nothing changes nothing: a single-repository book's pages,
    Markdown, figures and manifest are unchanged, and the only difference in the
    output is the embedded reader, which now knows how to show a citation from
    another repository.

  • An architecture history. nunki diff … --record v1.1 appends what a
    release changed to history.json beside the book, and the book renders it as
    a page. diff could always answer "what changed between these two releases";
    every answer was thrown away, on every pull request and at every tag.

    Entries are written at release time and never recomputed. Rebuilding the
    history at build time would make the book depend on which tags exist in the
    clone it is built in rather than on its own commit, which check cannot
    allow, and would cost a full scan of every release on every build. It is the
    rule authored.json already follows. Re-recording a release replaces that
    entry and leaves every other one untouched.

    An entry names the two commits it was computed between, so a reader can
    reproduce it instead of taking it on faith. The changes carry no line
    citations, because diff compares two models rather than reading lines.

  • The book records the release it documents, not only the commit, when it
    is generated from a tagged commit. Exactly at HEAD, never the nearest
    ancestor: a book built three commits after v1.1 documents those three
    commits, and calling it v1.1 would be a claim about code that release does
    not contain.

  • nunki conform checks the code against a specification somebody else
    wrote. It reads the layouts the spec-driven toolkits use —
    .kiro/specs/*/requirements.md, openspec/specs/*/spec.md,
    specs/*/spec.md — and reports what is declared and absent, what disagrees
    with the handler, what is implemented and asked for by nobody, and what the
    code cannot answer either way.

    Those toolkits write a specification and build from it; none can tell you
    afterwards whether the code still matches, because none keeps a link from a
    requirement to the code implementing it. Spec Kit's converge and OpenSpec's
    verify do check, by searching the codebase for each requirement on every
    run. This starts from a model where every claim already carries a file, a
    line, and the commit it was verified against.

    Built against a real repository rather than a fixture designed to succeed.
    Two things only real specifications do: they write {id} where the code
    writes {job_id}, so paths are compared by position rather than by the name
    a parameter was given; and most of a real specification names no endpoint at
    all. Reporting the system SHALL support HTTP/3 as a missing endpoint would
    be the loudest possible false positive, so a requirement the code cannot
    answer is reported as undecidable and never guessed at.

    --exit-code gates on what is actionable — something declared and absent, or
    contradicted. Not on scope judgements, which belong to a person.

  • nunki spec --format openspec writes openspec/specs/<capability>/spec.md
    from the code: one current-state specification per service, in a format
    another toolchain reads and validates. Adopting OpenSpec on a codebase that
    already exists otherwise means writing those by hand.

    Their validator is the point. CI runs openspec validate --specs --strict
    against the demo repository — someone else's checker, which fails when our
    output stops being something their tooling accepts. A check we wrote would
    only confirm we agree with ourselves. It was verified to exit 1 on malformed
    output before being trusted as a gate.

    Their format has no field for an identifier and none for evidence, and the
    requirement heading is their key, so both travel in an HTML comment beside
    each requirement: their validator tolerates it and a reader can still follow
    a claim back to the line it came from. Nothing is stated that was not
    measured — a scenario exists because a status was observed in the handler,
    not because an endpoint usually has one.

  • behaviour.json beside the book: requirements, the rules they must
    satisfy, and what the scan verified, as data. The book rendered all of it as
    prose, which a person can read and nothing else can — a Markdown table cannot
    be compared against a specification someone else wrote, handed to an agent,
    or read by anything wanting more than page text.

    The API and data models always serialised; they were simply never written
    out. The requirements layer did not exist as data at all — it was derived
    inside the page builder and rendered straight to prose. Now both leave, keyed
    by the identifiers from the functional page and carrying the evidence each
    claim was verified against. Rules name requirements rather than raw
    operations, so a consumer has one kind of key to learn.

    It is a generated file like any other, so check compares it and the model
    cannot drift from the prose built beside it.

  • Authored prose can be pinned, and check reports it when it rots.
    authored.json is the one thing in a book nunki does not derive, and it was
    the one thing it never checked. Two ways it went stale, both silent. An
    intent keyed to an operation that is later renamed simply stopped appearing:
    the lookup missed, the prose vanished, and nothing said so — check now
    fails and names the entry. And prose describing code that moved stayed on the
    page and quietly stopped being true; an operation intent can now carry
    evidence — path:START-END, the spelling nunki verify takes — which
    becomes a citation like any other, verified against the commit.

    Pinning is optional by design. An authored.json written before this
    existed keeps working untouched: unpinned prose is published and listed as
    unchecked rather than failing a build on upgrade. An untouched starter file
    reports nothing at all, since every entry in it is blank and a blank claims
    nothing — including when the operation it was generated for disappears.

Changed

  • tree-sitter 0.27. 0.27 indexes a node's children by u32 while still
    counting them as usize, which is the whole of the change on this side. Only
    one tree-sitter resolves in the tree, because the grammar crates depend on
    tree-sitter-language rather than on the core; no grammar version moved, which
    is what a parse tree depends on. Every fixture, the example book's 138
    citations and the browser journeys are unchanged.

Fixed

  • A repository's test fixtures were documented as its data model. .sql and
    .prisma files have no grammar, so they never reach the scanned file list and
    a separate walk is the only thing that sees them — and that walk skipped
    node_modules and dotfiles but not test, fixture or example directories. Any
    repository with a schema under tests/ had its fixtures published as its data;
    nunki's own book listed invoices, orders and payments, read out of the
    fixtures its tests run against. Both that walk and the Liquibase one now apply
    the same policy as the main scan, so --include-tests still means what it says.

  • A generated specification could not be read back by conform. spec writes
    the method inside the code span — `POST /charges` — and the parser handled
    that shape, then reported the position of the backtick, so the method search
    looked at the text before the span and found nothing. Asked to check a
    repository against a specification generated from that same repository, nunki
    reported its own operation as "implemented and declared nowhere". The method is
    now carried from where it was parsed.

  • A route could be resolved to the wrong function. Four functions named
    MakeHourAvailable in one Go package — the HTTP handler, a gRPC method and two
    generated wrappers — and resolution took the first by filename order. The book
    cited a gRPC method for an HTTP route, and the citation verified, because
    evidence checks that the symbol name appears in the cited range and it does. A
    candidate whose parameters are what the framework hands a handler now wins.

  • A C# minimal API's contract was not read. .Produces<T>() and the lambda's
    first non-injected parameter both declare a...

Read more

v0.4.1

Choose a tag to compare

@github-actions github-actions released this 21 Sep 13:00

Changed

  • The action's Marketplace listing is named "Nunki Architecture Docs". A
    Marketplace name has to be unique across every action, user and organisation
    on GitHub, and nunki is a user account, so the listing could not be
    published under it. This is the listing title only: the action is used by
    repository path (uses: sadaramk/nunki@v0.4.1), which has not changed, and
    no workflow needs editing.

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 21 Sep 12:26

Added

  • comment: true posts the diff on a pull request. nunki diff always
    produced the Markdown; posting it was twenty lines of workflow that every
    consumer would write and most would get wrong in the same place. The action now
    does it: one comment per pull request found by a hidden marker rather than by
    author, edited in place on every push, and deleted again if a later push makes
    the branch match its base — a branch that added a route and then reverted it
    should not keep claiming the route. An unchanged architecture says nothing at
    all instead of commenting "no changes" on every pull request. --base defaults
    to the commit the pull request merges into. Commenting is not a verdict, so it
    does not fail the job unless the caller also asked for --exit-code.

  • C# is read. A tree-sitter grammar for C#, .csproj as the module
    layout, and ASP.NET Core contracts: attribute-routed controllers with
    the [controller] token expanded, minimal-API Map* routes, [FromQuery] /
    [FromRoute] / [FromHeader] / [FromBody] binding with Name = renames,
    data annotations as validation rules, [Authorize] roles and policies with
    [AllowAnonymous] overriding them, and the statuses a handler returns or
    throws. Entity Framework Core entities come from the DbSet<T> properties,
    OnModelCreating's ToTable / HasColumnName / HasKey, and the annotations
    on the properties — all three, because any one alone gives the wrong table
    name. _db.Products.Add and .FindAsync are recorded as writes and reads.
    A .cs file no longer appears in the unread census.

  • A book says on its first page how much of the source it read, and names what
    it could not. Below a tenth read, nunki refuses to write one at all;
    --allow-partial overrides that.

  • A Homebrew tap: brew install sadaramk/nunki/nunki, on macOS and Linux. The
    formula installs the prebuilt binary, so nothing compiles.

    This is the fix for a macOS problem worth naming. The binaries are ad-hoc
    signed — Rust's default, the minimum for arm64 to execute — not notarized. A
    release archive downloaded through a browser therefore carries the
    quarantine attribute, and Gatekeeper kills it with exit 137 and no output,
    which reads as a corrupt binary rather than a policy decision. Homebrew and
    curl fetch without setting that attribute, so both paths work. Notarization
    would be the other fix, and it costs $99/yr.

    The release workflow bumps the formula on each tag when a TAP_TOKEN secret
    is present, and says so in the run summary when it is not, rather than
    failing.

Fixed

  • outputs.binary named a path that no longer existed. The entrypoint unpacked
    the binary into a temporary directory it removes on exit, and only got away
    with it because the script ended in exec, which skips the trap. The output was
    therefore only ever valid by accident, and any path through the script that did
    not end in exec would have handed later steps a path to nothing. The binary is
    now kept outside the directory that gets cleaned.

  • The coverage census counts every source file nunki cannot read, not just the
    five languages it half-supports. Counting only those made the number lie in
    exactly the case it exists for: a repository that is 95% C++ reported full
    coverage, because C++ was not on the list. Measured again on real
    repositories, immich drops from a claimed 100% to an honest 40% — its Dart
    mobile app and Svelte web UI were never read, and the book never said so.

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 20 Sep 19:18

Changed

  • Renamed from autodoc to nunki. "autodoc" is the name of Sphinx's
    best-known extension and a generic term for a whole category of tools, so the
    project was unfindable by name — the one thing a name has to do. Nunki is the
    star σ Sagittarii; in Sumerian cuneiform NUN.KI writes the name of Eridu, and
    the IAU made it the star's official name in 2016. It is widely called the
    oldest star name still in use, which turns out to be a claim worth checking:
    the name was lost, recovered from tablets, popularised in 1899 by a source
    whose Mesopotamian etymologies are unreliable, and probably belonged to a
    different asterism. A fitting name for a tool about following claims back.

    The binary, the crates, the config file (nunki.toml), the MCP tool names and
    the NUNKI_* environment variables all follow. GitHub redirects the old
    repository URLs, and the 0.2.x release assets keep their original names.

    Done now because the cost only rises: no listing, no published crates and no
    known users today.

v0.2.7

Choose a tag to compare

@github-actions github-actions released this 20 Sep 18:29

Fixed

  • Pinning the action pins the binary. uses: sadaramk/autodoc@v0.2.6 downloaded
    whatever the newest release was, so a workflow that pinned a version did not
    get it — the wrong default for any tool, and the wrong one twice over for this
    one. An exact vX.Y.Z ref now selects that release; a moving tag or a branch
    still takes the newest.

Added

  • A moving major tag, so uses: sadaramk/autodoc@v0 tracks the newest 0.x. The
    release moves it.

Added

  • autodoc export --format drawio writes a .drawio file rather than a CSV,
    and is the default. CSV cannot express an edge route or a label position, so
    draw.io re-routed every connector through the boxes and dropped every label on
    its own midpoint, printing them over the node names. The file carries the
    routes and label placements the book already computed. --format drawio-csv
    still writes the CSV, for merging into an existing drawing.

Fixed

  • The draw.io export places shapes where autodoc's own layout puts them, with
    the boundaries and sizes from the book. It previously left the layout to
    draw.io, which produced crossed edges and labels printed over one another
    because its flow layouts do not respect boundary groups — and its width /
    height directives were written without the @ that makes them read a
    column, so every shape was auto-sized to its label. Verified by importing the
    exported file into draw.io.
  • Edge labels carry a background, so several edges leaving one service no longer
    print their labels over each other.
  • No link column is emitted when nothing resolves to a URL, rather than an
    empty link on every shape.

v0.2.6

Choose a tag to compare

@github-actions github-actions released this 20 Sep 17:08

Added

  • autodoc export IR --format drawio writes draw.io's CSV import: real shapes
    with a layout applied, not a flattened image. Every shape carries its
    file:line as shape data and links to the line it came from, so a diagram
    pasted into a slide can still be checked. One way on purpose — reading a
    drawing back would mean deciding whether the file or the source is right about
    the architecture, and the source is.
  • autodoc diff [PATH] --base REV [--head REV] reports what changed
    architecturally between two revisions: services, connections, routes, request
    and response shapes, authentication requirements, tables and columns. Markdown
    for a PR comment, --json for a bot, --exit-code to gate a merge. Both
    revisions are read in throwaway worktrees, so the caller's working tree is
    never touched.
  • A request or response whose model keeps its name but changes shape is reported
    by its fields. An inline response literal is given a generated name, so
    comparing names alone said nothing when a field was added.

Changed

  • Workflows use actions/checkout@v7, setup-node@v7, upload-artifact@v7 and
    download-artifact@v8; the v4 line runs on a deprecated Node.

v0.2.5

Choose a tag to compare

@github-actions github-actions released this 20 Sep 16:31

Two themes: the book no longer claims more than it read, and installing autodoc
no longer needs a Rust toolchain.

Added

  • Prebuilt binaries for every tag: Linux (musl, static) and macOS on x86_64 and
    arm64, and Windows on x86_64, with a SHA256SUMS beside them. Each target
    generates and checks a book before it is published.
  • curl … /releases/latest/download/install.sh | sh installs one, verifying the
    published checksum first.
  • A composite GitHub Action, so CI is uses: sadaramk/autodoc@v0.2.5 instead of
    a two-minute cargo install. It downloads the binary for the runner, verifies
    the checksum, and runs any subcommand.
  • The API reference names the routes it does not document, with the reason and a
    citation. Spring PetClinic has seventeen mappings and two REST operations; the
    book documented the two under "the contract of every operation this service
    serves" and said nothing about the other fifteen server-rendered views.
  • A language census in the scan notes: source files recognised by language but
    with no grammar to read them are counted by language, and a repository that
    was mostly unreadable says so before anything else.

Fixed

  • Go: a bare reassignment is no longer treated as a constant a path can resolve
    to. p = "/" inside one function made every .Post(p, …) in the module look
    like a route at /, so caddy's book documented one operation — POST /,
    "handled by int64" — which is an outbound FastCGI client call.
  • An empty repository is refused rather than documented. Pointed at a directory
    with no manifest, no container file and no source in a language autodoc reads,
    it produced a six-page book around an empty diagram and exited 0, which is
    what a mistyped path or a failed checkout looks like.
  • A failure is reported once. EngineError and BookError derived their message
    from an inner error that was also their source, so cannot scan … printed
    twice.

autodoc 0.2.4

Choose a tag to compare

@sadaramk sadaramk released this 20 Sep 01:38

Claims the analyzer could not support, found by reviewing the analyzer against
real repositories. Each one produced confident output rather than missing
output, which is the failure this project exists to avoid.

Fixed

  • A write is drawn to the store that holds the entity. The step took the unit's
    first storage in enum order, so a service with JPA on Postgres and a
    @Document saved through a Mongo repository had its Mongo writes drawn to
    Postgres, with the real Mongo call site cited beside the wrong participant.
  • A unit at the repository root no longer answers to every service's name. Its
    configuration prefix is empty and every path starts with the empty string, so
    it collected every spring.application.name below it as an alias — and a
    @FeignClient naming any of them resolved to the root rather than the service
    that configures it.
  • A route under a prefix that could not be resolved is reported as partial.
    eval_path already said when it could not resolve a path, and the flag was
    kept at the leaf and dropped at all three prefix sites.
  • A drizzle column survives a builder chain wrapped by Prettier: the loop read
    one physical line, so a primary key became an ordinary nullable column, a
    required column became optional, and a foreign key disappeared.
  • An exporter, console or admin UI is no longer mistaken for the store it
    watches. Image names match by substring, so postgres-exporter was documented
    as a PostgreSQL database and kafka-ui as an event bus.
  • Every operation and model has its own anchor. slug is many-to-one, so
    /user-profile and /user_profile shared one heading id and every link went
    to the first; a model whose anchor collided was dropped from its page while
    the links to it remained.
  • A source file that cannot be read as text is named in the scan notes and on
    the evidence page, rather than disappearing with its routes and entities.

autodoc 0.2.3

Choose a tag to compare

@sadaramk sadaramk released this 20 Sep 00:35

Security

  • Repository content can no longer inject Markdown structure into the book. The
    escaper handled \ * _ < but not brackets, so a route path carrying
    ](https://…) closed the link label the renderer had opened and left a live
    link to a destination the repository chose in the operations table. Heading
    text, callout titles, stat labels and table headers were interpolated with no
    escaping at all.

Fixed

  • Kotlin controllers are documented the way Spring reads them. The Kotlin
    extractor is a copy of the Java one and had drifted: a ${…} placeholder was
    emitted as a literal path segment and the path still called exact,
    @RequestMapping without a method was reported as GET rather than every
    verb, only the first of a list of verbs or paths was kept, and a @Controller
    returning a view name was published as a REST operation. Kotlin writes a
    literal ${…} as \${…}, and the backslash was ending up in the path.
  • The book agrees with itself about how much of it is verified. Figure nodes
    carry citations and were registered after the evidence page had counted them,
    so that page reported a smaller total than the README and the manifest — the
    bundled example said 135 of 135 while its manifest said 138 — and a stale
    citation among them never reached the page's warning.

Internal

  • Eleven fixtures that were asserted at model level now also have a book built
    for them, including every Kotlin shape, three ORM shapes, JAX-RS, Micronaut
    and the Kubernetes topology. The information-architecture test is the only one
    that catches a dangling figure id, a citation with no page or a broken anchor,
    and it saw thirteen of twenty-four repositories.