Repository navigation
Guardana Control 0.12.0
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
experimentalenforcement API, under
clients/python/and imported asguardana_control.enforce
(ADR-0053).
One synchronous call asks the plane, runs your tool only with the bytes it
authorized, and closes with onecompleteor oneabort. It imports the
standard library alone and needs Python 3.11 or later. It cooperates and is
not a boundary: its calls aredecided, not enforced. - Answer vectors in
testdata/enforce/answers/vectors.jsonl: a status and a
body with what a client must do with it. Each isread,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.mdsays which form a client may rely on. - One more client case,
tool-reports-nothing: a tool that returns without a
status is completedUNKNOWN. make check-python, part ofmake quality: the client's tests on two
pinned CPython versions, its linter and type checker, and a build of its
wheel.make bootstrapinstallsuvand 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 thepypienvironment 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,
frommain.
Changed
- A change reaches
mainas one squash-merged pull request whose gate is
CI'smake 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.shasks for a gate stamp for commits sent tomainand
for the commit av*tag names, and for nothing else: a branch push needs
none. Amainthe remote does not hold yet counts every commit. The hook
has a negative control,make pre-push-probe, inmake 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 withErrSocketInUseand 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. supervisereportsDEADLINE_EXCEEDEDnot checked when an event of the
run has no time and the timed events stay withindeadline_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.reactreads 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 -stateholds 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 islifecycle_unknown. Its
state.jsonis now1.1and keeps each ended request's mode; a1.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