Skip to content

Guardana Control 0.12.0

Choose a tag to compare

@github-actions github-actions released this 16 Oct 10:46
· 100 commits to main since this release
Immutable release. Only release title and notes can be modified.

The experimental enforcement API gets an experimental Python client,
guardana_control.enforce. Once this release is published, the release
workflow uploads it to PyPI as guardana-control by trusted publishing
(ADR-0053).
It asks a plane for a decision before your tool acts and reports how the call
ended. It cooperates and is not a security boundary, and it passes the same
conformance cases and answer vectors as the Go reference. Each change now
reaches main through a pull request that must pass CI's make quality
(ADR-0052). Among
the fixes from a code audit: on Linux the enforcement receiver no longer
removes a socket a live receiver may hold, supervision reports a deadline not
checked when an event of the run has no timestamp, and react reads the clock
for each stop as it writes it. The project is still alpha, and the 0.x
series makes no compatibility promise between minor versions.

Added

  • A Python client of the experimental enforcement API, under
    clients/python/ and imported as guardana_control.enforce
    (ADR-0053).
    One synchronous call asks the plane, runs your tool only with the bytes it
    authorized, and closes with one complete or one abort. It imports the
    standard library alone and needs Python 3.11 or later. It cooperates and is
    not a boundary: its calls are decided, not enforced.
  • Answer vectors in testdata/enforce/answers/vectors.jsonl: a status and a
    body with what a client must do with it. Each is read, refused, or
    may_refuse, where the Go reference reads a form outside the one the
    receiver writes and another client may refuse it. The Go reference, a second
    Go client and the Python client run them, and they seed the decoder's fuzz
    target. docs/contracts.md says which form a client may rely on.
  • One more client case, tool-reports-nothing: a tool that returns without a
    status is completed UNKNOWN.
  • make check-python, part of make quality: the client's tests on two
    pinned CPython versions, its linter and type checker, and a build of its
    wheel. make bootstrap installs uv and both interpreters.
  • The release workflow builds the Python client's wheel and source archive
    and attests them before any other tool of the release job runs. After the
    GitHub release is published, a separate job in the pypi environment waits
    for a maintainer's approval, then uploads exactly the files the build listed
    to PyPI by trusted publishing, with no stored token, and reads the index
    back. The dry run uploads a development release to TestPyPI the same way,
    from main.

Changed

  • A change reaches main as one squash-merged pull request whose gate is
    CI's make quality, a maintainer's own included; only a release commit is
    still gated cold on a maintainer's machine and pushed directly. Until 1.0 a
    release follows every one to three changes
    (ADR-0052).
  • The race tests run every night with every processor busy, on Linux and on
    macOS, so a test that depends on the clock fails there and not in a release
    gate. A red night opens an issue.
  • The README, the site's title and the repository's description call the
    project an AI agent supervision framework; the README opens with what runs
    today and puts the 1.0 goal after it.
  • scripts/pre-push.sh asks for a gate stamp for commits sent to main and
    for the commit a v* tag names, and for nothing else: a branch push needs
    none. A main the remote does not hold yet counts every commit. The hook
    has a negative control, make pre-push-probe, in make quality.

Fixed

  • The enforcement receiver removes a socket left at its path only when a
    connection to it is refused. A timeout, a full backlog on Linux or a
    permission error refuses the start with ErrSocketInUse and leaves the
    socket of a receiver that may still be live. On macOS a live receiver
    whose backlog is full refuses connections too, so a second plane started
    then can still take its path.
  • supervise reports DEADLINE_EXCEEDED not checked when an event of the
    run has no time and the timed events stay within deadline_seconds; it
    was reported checked on a span that may have been longer. A breach on the
    timed events still fires; under a 0.2 procedure the rule is then checked
    for the tree, and a run whose events have no time gets no finding.
  • react reads the clock for each stop it writes. A pass that ran longer
    than a rule's lifetime wrote a stop that had already expired, counted the
    finding as stopped, and never stopped the run for it again.
  • examples/evidence-report -state holds a finding or a policy reload linked
    after a request's end to the request's enforcement mode, as the one-shot
    report does: an undeclared or other mode is lifecycle_unknown. Its
    state.json is now 1.1 and keeps each ended request's mode; a 1.0
    state is still read, and an annotation after the end of a request it holds
    is unknown, since its mode was not kept.
  • The gateway's configuration reader keeps a double-quoted value whole when
    it holds an escaped quote: "a\" #b" was cut at the # as a comment and
    the file refused.

Image: ghcr.io/guardana/control-gateway@sha256:97da888b2a22efd130fd60dd2de2d5484e5ff1978ee4820461cb006926a14d4a