Deterministic, policy-driven auto-merge for self-service repos
Canonical repo: GitHub (PlatformRelay/assent). Status: alpha — the GitLab CI path is Core (E2–E8 engine, forge, provider, renderer). Pre-1.0: policy schema and CLI flags may change between releases; see API stability.
assent is a deterministic, policy-driven auto-merge gate for self-service configuration repositories. Drop it into a repo's CI pipeline and it turns merge requests into decisions: approve, comment, request changes, or block — based on rules you write in Kyverno-style declarative YAML with CEL predicates.
Read the docs: platformrelay.github.io/assent — vision, architecture, ADRs, install guide, and usage walkthrough. This README is the front door; the site is the map.
Most changes to config repos (topic definitions, service catalogs, tfvars, tenant onboarding files) are routine: a team edits their own entries within safe bounds. Yet a human still has to review every MR, reconstructing the same context each time — what changed, who owns it, is it destructive, which policy applies. assent encodes that reasoning as policy so the routine 90% merges itself and reviewers spend their attention on the risky 10%.
- Fail-safe decisions — every run emits an auditable
DecisionRecord; ambiguous policy fails closed (ADR-0015). - Semantic diffs — JSON, YAML, and HCL/tfvars parse into field-level adds/modifies/deletes, not line noise (ADR-0003).
- Testable policies — fixture changes in, expected decision out; policies without tests are a lint error (ADR-0014).
flowchart LR
MR["Merge request"] --> CI["GitLab CI job"]
CI --> Assent["assent run"]
Assent --> Forge["GitLab forge API"]
Assent --> Providers["Permission & fact providers"]
Assent --> Policy[".assent/ policies"]
Assent --> Out["Threads · comments · approve · merge"]
Key property: assent is stateless per invocation — every run recomputes the decision from (diff, repo snapshot, facts, policy version). No database, no long-lived service in v1. See system context for the full C4 diagram.
Install from source (install guide):
go install github.com/PlatformRelay/assent/cmd/assent@latest
assent versiongo install compiles without link-time stamping, so the binary it produces reports
assent 0.0.0-dev — even when you pin a tag (@v0.1.0). For a version-stamped
binary take the Homebrew tap or a release archive: goreleaser injects the version
(-X main.version) and the archives are checksum- and signature-verifiable. Both
routes are in docs/usage/install.md.
Lint and test policies locally. Both commands take the repository root — assent
appends .assent itself, so passing .assent/ makes it look for .assent/.assent:
assent lint .
assent test .No repo of your own yet? A clone of this one ships runnable sample policy trees; run the
two commands above from examples/packs/service-catalog (that is the fixture
hack/docs/readme_smoke_test.sh executes this block against).
Developers: gates live in the Taskfile:
task check # fmt + vet + lint + testHonest tiers post-E8 (D-104). Core = shipped and covered by conformance tests; Planned = designed seam, not yet implemented; Locked = deferred epic; Designed = ADR/spec only.
| Area | Status | Notes |
|---|---|---|
| Policy lint / test | Core | assent lint, assent test, schema drift gates |
| GitLab forge | Core | Snapshot, resolve, reconcile, merge CAS |
| Provider builtins | Core | GitLab groups, ownership file, static facts |
| Renderer | Core | Finding threads, summaries, presentation lint |
| GitHub adapter | Planned | E10 — designed seam (D-012) |
| Rego backend | Locked | E11 — CEL/assert path is Core today |
serve (HTTP API) |
Designed | E12 — CLI-only in v1 |
| Remote packs | Locked | E13 — local .assent/ only |
| Topic | Link |
|---|---|
| Documentation site | platformrelay.github.io/assent |
| Install (go, curl, Homebrew) | usage/install.md |
| API & schema stability | API_STABILITY.md |
| Security policy & CI gates | SECURITY.md |
| Vision & personas | docs/vision.md |
| Architecture (C4) | docs/architecture/ |
| Decision log | docs/decisions/decisions.md |
| Path | Purpose |
|---|---|
docs/ |
Product docs (published via MkDocs) |
docs/planning/ |
Contributor planning notes (not in published nav) |
openspec/ |
Spec-driven development specs and change proposals |
cmd/assent/ |
CLI entry point |
internal/ |
Go packages (hexagonal: core + ports + adapters) |
examples/ |
Sample policies and self-service repo layouts |
test/e2e/ |
End-to-end strategy: kind-hosted GitLab / testcontainers |
hack/release/ |
Snapshot builds, install script, release verify harness |
Apache-2.0 — © 2026 Konrad Heimel. Same license family as Kubernetes and Argo CD: permissive, with an explicit patent grant.