- Go 98.9%
- Shell 0.8%
- Python 0.2%
- Makefile 0.1%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .agents/skills/repo-umbra | ||
| .forgejo/workflows | ||
| .github | ||
| .ward | ||
| assets | ||
| cli | ||
| cmd | ||
| docs | ||
| examples | ||
| http | ||
| internal/specgencli | ||
| pkg | ||
| scripts | ||
| .agentic-os.toml | ||
| .gitattributes | ||
| .gitignore | ||
| .golangci.yaml | ||
| .pre-commit-config.yaml | ||
| _typos.toml | ||
| AGENTS.md | ||
| CLAUDE.md | ||
| CODE_OF_CONDUCT.md | ||
| CONTRIBUTING.md | ||
| go.mod | ||
| go.sum | ||
| godoc-current.txt | ||
| LICENSE | ||
| Makefile | ||
| mkdocs-requirements.txt | ||
| mkdocs.yml | ||
| pyproject.toml | ||
| README.md | ||
| SECURITY.md | ||
| staticcheck.conf | ||
umbra
config driven occlusion framework
Occlusion is the idea. umbra sits between semi-trusted automation and the host
system, and what you did not declare does not get through. The boundary lives in
a KDL guardfile rather than in code, so it is one artifact a reviewer reads in a
sitting. umbra ships no denylist and knows nothing about your tools: policy is
yours, and umbra enforces it across two surfaces, cli/ around subprocess exec
and http/ around outbound requests.
It validates argv before execve, checks a scope token per verb, refuses
repo-shaped verbs on a dirty tree, gates egress through a per-invocation CONNECT
proxy, and appends every call to a rotating JSONL audit log. A public exit-code
taxonomy separates a policy refusal from a tool failure. Full documentation in
docs/index.md.
umbra is not a sandbox. It performs no execution isolation, and that is deliberate rather than unfinished. Validating argv, gating egress, and auditing every call does nothing to contain a process that is already running. Isolation is a container's job, and umbra is the gate in front of it.
Two ways in
Generate the CLI. specgen reads KDL policy plus committed locks out of a
.specgen/ directory and builds a standalone guarded CLI with no hand-written
Go. --skills-out also renders a native agent skill and a lazy command index.
Import the primitives. Every package stands alone if you are adding a boundary to an existing urfave/cli v3 app. Nothing consumer-shaped leaks into the API.
GOPRIVATE=forgejo.coilysiren.me go get forgejo.coilysiren.me/coilyco-flight-deck/umbra
Install specgen
brew tap coilyco-flight-deck/tap https://forgejo.coilysiren.me/coilyco-flight-deck/homebrew-tap
brew install coilyco-flight-deck/tap/specgen
scoop bucket add coilyco-flight-deck https://forgejo.coilysiren.me/coilyco-flight-deck/scoop-bucket
scoop install coilyco-flight-deck/specgen
Tagged releases also publish raw binaries and SHA256SUMS for Linux, macOS, and
Windows on amd64 and arm64. specgen --version reports both the driver and the
umbra ref lock freezes by default. It shells out to the Go toolchain to resolve
locks and build, so Go has to be present.
Try it
examples/ holds one runnable app per primitive, and
docs/getting-started.md walks the first run. The shortest:
go run ./examples/policy unsafe 'foo; rm -rf /'
Status and development
v0.x. Minor API breaks land on main with a note in the commit body and no
deprecation cycle, so pin a commit in your go.mod until v1.0.0. The API locks
once a second consumer lands. Forgejo is canonical and the GitHub mirror is
verified. umbra is deliberately unguarded, being the framework rather than a
consumer of one, so its dev verbs run through the Makefile:
make build test lint vet, and make docs-serve for the rendered docs.
See also
- AGENTS.md - agent-facing operating rules.
- a new issue - bugs and requests, under the Code of Conduct and SECURITY.md.
- mcp-beaver - the sibling that renders a guardfile into a guarded MCP server.
MIT. See LICENSE.
