Skip to content

Releases

v0.9.1

Choose a tag to compare

@github-actions github-actions released this 05 Nov 19:42

Fixed

  • A replica that starts while another runs the migrations waits for
    it,
    up to 5 minutes, where it refused to start on the migration it
    found in progress.

  • A huge Retry-After from the key service is a long wait, no longer
    one that wrapped to negative, and a date in it is waited for.

  • A request id is passed to the authorizer only when it is printable and
    at most 128 bytes.
    A request without one, or with another, gets a
    fresh one.

Release evidence

v0.9.0

Choose a tag to compare

@github-actions github-actions released this 05 Nov 15:12

Added

  • A release can deploy itself. The release workflow has a deploy job
    between the build and the publish, which applies deploy/prod with both
    images pinned by digest, waits for the three Deployments and runs
    tools/smoke/release.sh against the live origin. It runs only where the
    repository variable LECTIO_RELEASE_DEPLOY is set, so a fork publishes
    every artifact and deploys nothing. deploy/prod holds the maintainer's
    production manifests and deploy/prod-bootstrap the identity the job
    deploys with. Neither is part of the install path or of the
    deploy-<tag>.tar.gz archive of a release.

Changed

  • Releases are built, signed and published by the shared release stages
    in latere-ai/ci.
    The signatures on both images and on the signed
    checksums.txt now name those stages, run for this repository.
    SECURITY.md gives the commands that check a release, and the ones for
    releases up to v0.8.2; the release workflow runs the checks against
    every release it publishes.

Release evidence

v0.8.2

Choose a tag to compare

@github-actions github-actions released this 21 Oct 14:52

Fixed

  • Built with Go 1.27.3, which fixes GO-2026-6809, a flaw in the
    standard library's certificate verification that this code can reach.

v0.8.1

Choose a tag to compare

@github-actions github-actions released this 20 Oct 17:05

Fixed

  • lectiod exports its telemetry. With OTEL_EXPORTER_OTLP_ENDPOINT
    set, the API and the worker start the OpenTelemetry export: a span and
    the request metrics (http.server.request.duration and the body sizes)
    for every request of the API but /healthz, the spans of the outbound
    calls to a model endpoint, a converter and a source URL, the log, and the
    Go runtime's metrics. Before, those calls went through a tracing transport
    with no exporter behind it, so a deployment that set the endpoint
    exported nothing. The log keeps its JSON format, and each record now
    carries service, version and replica.

v0.8.0

Choose a tag to compare

@github-actions github-actions released this 18 Oct 15:08

Added

  • Every answer names the release that wrote it. The API sets the
    response header Lectio-Version on everything it answers on
    LECTIO_ADDR, errors, /v1/openapi.yaml and /healthz included: the
    version lectiod version prints and the internal /version reports,
    such as v0.8.0, or dev for a build that was not stamped. A caller
    comparing results across releases reads which one answered from the
    answer itself, which during a rolling update is the only place that
    says. A proxy that should not reveal the release removes the header.

v0.7.1

Choose a tag to compare

@github-actions github-actions released this 17 Oct 17:40

Fixed

  • Thirteen descriptions in the API contract read in full. Inside a flow mapping an unquoted description ended at its first comma, and the rest of the sentence became a stray key: the width of a page read "Points for paged formats", and fields and sets named a key for the tail of their extractor's sentence. They are quoted, and a test holds the contract to having no such remainder.

v0.7.0

Choose a tag to compare

@github-actions github-actions released this 13 Oct 23:50
  • Added: DELETE /sets/{set}/parses/{parse} takes a parse out of a set
    and leaves the parse. Its extraction under the set's name stays on the
    parse with its values, as an extraction of no set; the set no longer
    counts or lists it, and a change of the set no longer asks it. A later
    join takes it back in without a model call while it was asked with the
    set's definition. It is conflict while that extraction has not ended,
    and asks set.update.
  • Added: an extraction names the set that asked it, set, and the
    version of the set's definition it was asked with, set_version, on
    every read. Both are absent on an extraction no set asked, and once its
    set is deleted or its parse leaves it.
  • Added: the answer of PUT /sets/{set}/parses/{parse} carries asked,
    true when the join asked the extraction, as its status 202 says.
  • Migration 000009 adds one function and changes no table.
  • Added: readers changed while the server runs. PUT /readers/{name}
    stores a reader, its body the spec of a Reader document in JSON;
    DELETE /readers/{name} removes one; PUT /policy sets the order the
    readers are tried in, in the place of the configured Policy, and
    DELETE /policy puts that back; GET /readers/{name} and
    GET /policy read them. Every process of the durable server reads
    with the change within LECTIO_READERS_POLL (10 seconds), with no
    restart, and the process that made it at once. A stored reader reaches
    one of LECTIO_READER_ENDPOINTS, by default the endpoints the
    configured readers reach; the stub adapter is refused, and a
    configured reader is never changed. A reader the order names, one a
    set's definition names, and one with work that has not ended are not
    removed.
  • Added: the actions reader.update and reader.delete. The owner
    policy allows them to LECTIO_ADMIN_SUBJECTS alone. An authorizer
    that does not know them refuses these routes and nothing else.
  • Added: GET /readers says of each reader where it came from
    (source), its adapter, its model, and whether it describes
    and extracts.
  • Added: reader on an allow, the default reader of a caller. A
    submit, a figure run, an extraction and a set's definition that name
    none are read with it, as if they named it, where it does what is
    asked; one the server does not have is reader_not_found.
  • Added: a key ask names models, the models the readers in force
    reach, and a worker holds a key per group and per that list.
  • Changed: a task that waits at a place of a chain that a new
    configuration makes shorter waits at the chain's last place, where it
    waited for a place nobody reads.
  • Migration 000010 adds the tables readers and reader_policy and
    replaces lectio_configure; it touches no table in use.

v0.6.1

Choose a tag to compare

@github-actions github-actions released this 11 Oct 12:49
  • Changed: the summary of PUT /sets/{set}/parses/{parse} in the
    contract reads "Add a parse", short enough for a reference's
    navigation, which lists it under its tag, sets.

v0.6.0

Choose a tag to compare

@github-actions github-actions released this 11 Oct 11:34
  • Added: sets. A set is a name and the definition of an extraction,
    made before any file is read (POST /sets), and asked of each parse
    that joins it (PUT /sets/{set}/parses/{parse}). A parse whose
    extraction of the name was already filled with the set's definition
    joins without a model call. PUT /sets/{set} changes the definition
    and asks every parse of the set again, and is refused with conflict
    while one of its extractions is queued or running; the definition the
    set already holds, sent again, asks nothing.
    GET /sets/{set}/parses reads a set's table, every parse with its
    extraction, in one request. Deleting a set leaves its parses and their
    extractions. A set holds at most 10,000 parses.
  • Added: the Set kind and the actions set.create, set.read,
    set.list, set.update and set.delete. An authorizer that does not
    know them refuses the set routes and nothing else; the allows of
    set.create and set.update are read for owner and readers.
  • Added: the error code set_not_found.
  • Changed: an extraction a set asked is asked again by name
    (PUT /parses/{parse}/fields/{name}) with the set's request alone,
    compared as a JSON value; another request is conflict.
  • Migration 000008 adds the sets table and two columns to fields. It
    takes the lock of fields as 000007 does, and its down file keeps the
    extractions a set asked as extractions of no set.

Security

  • Built with Go 1.27.2 and golang.org/x/net v0.60.0, which fix GO-2026-6611, GO-2026-6612, GO-2026-6613 and GO-2026-6617.

v0.5.1

Choose a tag to compare

@github-actions github-actions released this 06 Oct 22:30
  • Fixed: a uniqueItems check of a list too costly to hash is answered
    as not checked before any item is hashed, so the answer takes no
    longer than reading the list. v0.5.0 hashed such a list first, which
    a list of a megabyte made take seconds on a slow machine.

v0.5.0 - 2026-10-06

Its tag was cut and its release pipeline stopped before it published, so its changes are released here.

  • Changed: a uniqueItems check of a list of more than 20 items is
    priced by the comparisons the validator makes, which are the pairs of
    items whose hashes are equal, and no longer as if every item met every
    other. A list of distinct objects is checked up to 65,535 small
    items, where it was refused past about 500; items built to hash alike
    are still priced past the bound and not checked.

  • Added: GET /readers marks a reader that reads a page from the text
    its file carries and calls no model with text_layer: true, so a
    console can keep it out of a picker of models while the routing
    policy still tries it first.

  • Fixed: an extraction no longer reads page furniture. Blocks of kind
    page_header, page_footer and page_number are left out of the
    text a model is given and out of what a citation may name, so a
    running header is not taken for the document's title.

  • Added: PUT /parses/{parse}/fields/{name} asks an extraction again
    under its name, with another schema or with the same one after it
    failed. Only an extraction that has ended is asked again; one that is
    pending is 409 conflict. It is reset to pending with the new
    request and nothing of its last result, the result it replaced is
    removed, and its task is queued as a new extraction's. A name the
    parse has no extraction of is asked as a new one. Migration
    000007_ask_again adds a count of askings to an extraction. Pods of
    v0.4.0 that are running keep working beside it; one that starts after
    it does not come up, so roll every role.