This top-level AGENTS.md is the repository navigation and policy layer.
- Keep this file focused on shared constraints, navigation, and recurring operating guidance.
- Push local implementation detail downward into child
AGENTS.mdfiles when a directory starts carrying its own stable rules. - Do not duplicate large bodies of module-specific instruction here once a child
AGENTS.mdexists. - Treat this file as the default contract for the whole repository unless a
deeper
AGENTS.mdoverrides a narrower scope. - Keep
.task/out of git by default. Use it only for long-running work and update it as live task state, not as archival prose.
Core product stance:
runsealis not just an operations toolkit. It is an operations methodology plus a derived tool system: the main value is deciding which operational complexity belongs in wrappers, atomic tools, repo/local artifacts, or external scripts, then keeping those layers explicit.runsealexists to reduce environment-dependency complexity in real cross-platform operations work: too many environment variables, too many machine-specific assumptions, and too much operational glue falling into uncontrolled Python or shell dependency stacks.- Explicit profile. No hidden orchestration.
- Prefer Deno
.tswrappers for structured cross-platform operator flows, thin.shwrappers only for Unix bootstrap glue, and explicit atomic@toolcapabilities for reusable domain operations. - Treat Deno as an explicit single-binary runtime prerequisite when the profile
declares a
[deno]policy. Do not hide runtime setup or prompt for missing permissions at wrapper execution time. - Keep the Rust core thin and concrete.
- Support only
env,symlink, fixed-prefixargv, explicit:wrapperresolution, Deno.tswrapper execution, platform script wrappers, and read-only@internalintrospection unless a new product decision explicitly expands the surface. - Use
clapfor CLI parsing. Do not hand-roll argument parsing. - Preserve command lifecycle semantics: load profile, register symlinks, export env, run command, clean up symlinks.
- Keep command namespaces explicit:
<cmd>is external,:<cmd>is a profile wrapper,@<cmd>is runseal internal.
Runtime path rules:
- Treat
RUNSEAL_HOMEas the runseal configuration root. - Treat
RUNSEAL_PROFILE_HOMEas the profile directory, defaulting to<RUNSEAL_HOME>/profiles. - Resolve one concrete
RUNSEAL_PROFILE_PATHduring app initialization.
Tooling rules:
- Treat
runsealandflavoras installed developer infrastructure, at the same level asgit,gh, andcargo; this repository does not bootstrap them.
Direct child directories with their own AGENTS.md:
- None yet.
Direct child directories that are likely future candidates for a child
AGENTS.md once their local rules become stable:
app/: Rust application code, tests, and core runtime behavior..runseal/: repo-local wrappers and operator-facing workflow glue..github/: CI, release automation, and workflow support scripts.docs/: durable operator or contributor documentation, if this area starts carrying rules distinct from code.
When a direct child directory gains its own stable constraints, add an
AGENTS.md there and link it from this section.
There are no child AGENTS.md targets yet, so this index currently points to
the repository-owned canonical files directly.
app/src/bin/runseal.rs: CLI entrypoint.app/src/core/config.rs: app configuration and profile discovery.app/src/core/profile.rs: profile format loading and normalization.app/src/core/runtime.rs: command execution lifecycle.app/src/core/injections/:envandsymlinkimplementations.app/src/core/tool/: built-in atomic@toolsurface.app/tests/: integration tests and focused behavioral coverage..runseal/wrappers/: repo-local:wrapperentrypoints. Prefer.tswrappers for structured operations and.shonly for thin Unix bootstrap.runseal.toml: repo-local operator profile.manage.shandmanage.ps1: public install and uninstall managers.
Once child AGENTS.md files exist, this section should prefer links to those
local guides over repeating their detail here.
Normal workflow:
- Work on a dedicated feature branch for every substantive change.
- Keep changes scoped to the current product boundary.
- Prefer
git commitas the default validation trigger; the repo-installed pre-commit hook runsrunseal :guard. - Use standalone lint, format, or test commands only for focused diagnosis or repair after the repo guard reports a failure.
- Use repo wrappers for recurring operator flows when they already encode the intended path.
Branch safety:
- The generated pre-commit hook rejects direct commits on
main; create a feature branch before committing. - Treat
--no-verifyas an explicit exception only. If used, record why in the surrounding handoff or final note.
Default validation path:
git commitUse runseal :guard only when an explicit manual guard run is needed before a
commit or while diagnosing hook failures.
Common repo workflow commands:
runseal :init
runseal :cloudflare
runseal :land
runseal :release --channel beta --ref <branch> --watchManager install/update path:
./manage.sh install --channel betaRelease and distribution rules:
- Release and manager downloads use R2 metadata and artifacts as the source of truth.
- Public install and uninstall entrypoints are
manage.shandmanage.ps1. - Release and smoke flows should reference those root files.
- Cloudflare manager redirects are exact-path rules for
runseal.perish.uk/manage.shandrunseal.perish.uk/manage.ps1, pointing toreleases.runseal.perish.uk/manage.shandreleases.runseal.perish.uk/manage.ps1.
Profile discovery order:
--profile <path>- From
<cwd>upward to filesystem root, at each directory:runseal.tomlrunseal.yamlrunseal.ymlrunseal.json
<RUNSEAL_PROFILE_HOME>/default.toml<RUNSEAL_PROFILE_HOME>/default.yaml<RUNSEAL_PROFILE_HOME>/default.yml<RUNSEAL_PROFILE_HOME>/default.json
Format priority is TOML, YAML, then JSON within each searched directory. Successful profile and wrapper paths are normalized absolute paths.
This repository is building explicit runtime glue, not a hidden orchestrator. New behavior should be added only when it fits one of these shapes cleanly:
- a Deno
.tswrapper for repo-local structured operational flow - an explicit atomic
@tool - a thin platform script for bootstrap or platform-specific shell integration
runseal should not be treated as a grab-bag operations toolkit where every
pain point becomes another command. Its value is methodological first:
- decide what should be flow control in a
.tswrapper - decide what should be an atomic
@tool - decide what should be a visible repo or local artifact under
.runseal/or.local/ - decide what should remain an external script because it carries the wrong kind of complexity
The concrete tools matter, but they are derived from that layering model rather than the other way around.
This boundary comes from the actual problem runseal is trying to solve:
clear operational workflows should not need to depend on heavyweight language
runtimes or repository-local script stacks just to survive environment drift,
cross-platform differences, and routine operator setup friction.
The goal is not "no runtime dependencies ever". The goal is to absorb the right kind of complexity with explicit prerequisites:
- clear, finite, cross-platform operational flow control should fit in Deno wrappers plus runseal profile/context glue
- reusable domain operations should become
@tool - shell-specific cleverness, open-ended scripting power, and accidental dependency sprawl should not
That is why the product boundary is Deno-first wrappers plus explicit atomic tools, rather than a general scripting platform or a partial shell clone.
When the logic is repo-local operational flow: argument parsing, policy, defaults, validation, polling, JSON/HTTP handling, and sequencing around existing CLIs or runseal tools.
When native CLI coverage is insufficient for an atomic, reusable operation and the result still fits the explicit atomic-tool model.
When the behavior cannot be described cleanly as a repo-local Deno flow or a clear atomic tool, keep it in Python, Ruby, JavaScript, Zig, shell, or another external script.
Usually no.
For operations work, persistent or semi-persistent structured text should
normally live as explicit repo material under .runseal/ or .local/, not as
inline heredoc-style wrapper content. That includes things like:
- config templates
- YAML or JSON fragments
- kube-related files
- long request bodies
- other operator-facing text payloads
The wrapper should usually do the smaller, clearer job:
- validate preconditions
- choose the right file or template
- assemble paths and arguments
- set environment for the invoked command
- execute the operational flow
This is an intentional product boundary. runseal is meant to reduce
environment and runtime dependency complexity in operations workflows, not to
turn wrappers into a general inline text-construction language. If a multi-line
artifact is important enough to exist, prefer making it a visible repo or local
artifact first.
Yes. Treat .runseal/wrappers/*.ts as first-class wrappers executed by runseal
through the selected profile's [deno] policy.
.task/- accidental broad surface expansions that were not backed by an explicit product decision
Prefer small focused commits.