v0 source realm
Package maintainer models an AI agent stewarding a versioned on-chain package — without ever letting it deploy on its...
View source
Agent Maintainer — an AI maintainer for an on-chain package that still can't ship on its own
"Give the AI commit access" is where most agent-automation stories quietly become horror stories. The useful version is narrower and much safer: let the agent drive the process — the tedious, valuable, around-the-clock parts — while an explicit policy still gates the one irreversible step, the ship.
This realm is that split, made concrete for a versioned on-chain package.
What the agent may do
- open a version proposal committing to a package artifact hash,
- collect independent reviews,
- record CI test attestations,
- write release notes, keep a compatibility matrix,
- deprecate a version when a vulnerability lands.
What it cannot do
Deploy on its own say-so. Approve is gated by a machine-checked policy, and
it panics with the first unmet condition rather than quietly proceeding:
tests pass
AND ≥ MinReviewers (2) independent reviews
AND every review scores ≥ MinScore (80)
AND the challenge window has elapsed (height > ChallengeUntil)
The render turns that policy into a live checklist:
## Policy checklist
- ✅ tests pass
- ✅ ≥2 independent reviews (have 2)
- ❌ every review ≥80 ← one reviewer scored 70
- ✅ challenge window elapsed
The flow
1id := maintainer.Propose(cross(cur), "v3", "artifact#H3", 100) // 100-block challenge window
2maintainer.AttestTests(cross(cur), id, true) // CI attests
3
4maintainer.AddReview(cross(cur), id, 85, "ok") // reviewer 1 (not the proposer)
5maintainer.AddReview(cross(cur), id, 95, "great")// reviewer 2
6
7// ...after the challenge window passes...
8maintainer.Approve(cross(cur), id) // promotes to a release, or panics with the reason
9
10maintainer.LatestVersion() // "v3"
11maintainer.Deprecate(cross(cur), "v3", "CVE-xyz")
12maintainer.IsDeprecated("v3") // true
Two independence rules keep the reviews honest: the proposer can't review its own proposal, and each address reviews at most once.
Note the realm records the approved release — the actual package publish
(addpkg) is a separate, deliberately human/authority step. The agent
produces a green checklist; it never holds the deploy key.
Browse the release matrix + open proposals at the realm root; each proposal's
policy checklist and reviews are at :<id>.
1gno test .
Where it goes next
- Wire
Approveto actually authorize a downstream deploy via a capability (see the capwallet demo) instead of a trusted caller — then even "approved" can't over-spend or over-deploy. - Route contested proposals to a jury instead of a simple score gate.
- Add a maintainer budget so the agent's activity itself is bounded.
Each of those is a different demo in this series clicking into place — which is the real thesis: agent trust is not one primitive, it's a stack of small, composable ones.
Part of moul/gno-contracts — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage.
Dependency graph:

⚠️ Disclaimer: provided as-is, without warranty; not security-audited. Full disclaimer: DISCLAIMER.
Package maintainer models an AI agent stewarding a versioned on-chain package — without ever letting it deploy on its own authority.
The agent can do the tedious, valuable parts: open a version proposal, collect reviews, record CI test attestations, write release notes, deprecate a vulnerable version, keep a compatibility matrix. What it cannot do is ship. Approval is gated by an explicit, machine-checked policy:
Example
1tests pass AND ≥ MinReviewers independent reviews AND
2every review scores ≥ MinScore AND the challenge window has elapsed
This is the difference between "an agent with commit access" and "an agent that drives a process a human (or a DAO, or a policy) still gates." The realm records *approved* releases; the actual package publish is a separate, deliberately human/authority step.
1
9
func AddReview
crossing ActionAddReview records a reviewer's score. Reviewers must be independent of the proposer, and each address reviews at most once.
func Approve
crossing ActionApprove promotes a proposal to a release iff every policy condition holds. It panics with the first unmet condition — the policy is the gate, not a suggestion.
func AttestTests
crossing ActionAttestTests records whether CI's test suite passed for the proposal.
func Deprecate
crossing ActionDeprecate flags a released version (e.g. a vulnerability was found).
func IsDeprecated
ActionIsDeprecated reports whether a released version is deprecated.
func LatestVersion
ActionLatestVersion returns the most recently released version, or "".
func Propose
crossing ActionPropose opens a version proposal with a challenge window of the given number of blocks (during which reviews accrue and approval is blocked).
func Render
Render shows the release matrix + open proposals, or one proposal at :<id>.
func GetProposal
ActionGetProposal returns a copy of a proposal.
3
type Proposal
struct 1type Proposal struct {
2 ID uint64
3 Version string
4 ArtifactHash string // commitment to the package source
5 Proposer address
6 Reviews []Review
7 TestsPass bool
8 TestsAttestor address
9 OpenedAt int64
10 ChallengeUntil int64 // approval blocked until height passes this
11 Approved bool
12 ApprovedAt int64
13}Proposal is a candidate new version working its way toward approval.
type Release
structRelease is an approved (and possibly later deprecated) version.
type Review
structReview is one reviewer's score for a proposal.
4
- chain stdlib
- chain/runtime stdlib
- gno.land/p/nt/ufmt/v0 package
- strings stdlib