cyberine
UsageRun recipes

Agent policies (cyberine init --policies)

cyberine init installs a public policy core: eight short, generic rules for how an agent works in any repo, one file each under .claude/rules/, written from the bundled templates in templates/policies/ (owner rulings 2026-10-29, D1-A, D2-A, D3-A). Each file opens with a line saying it was written by cyberine init on a date, that deleting the file reverts it, and that a rule in the repo or the user's own message overrides it. The default posture matches the owner's own: tests, CI, cleanup and anything costly run only when the user asks, and paid resources are dry-run only.

cyberine init                              # one plan item per policy not yet installed, each default on; Enter accepts, e toggles
cyberine init --yes                        # no prompt: installs every policy not yet installed (non-TTY does the same)
cyberine init --policies all               # install all eight explicitly
cyberine init --policies tests,secrets     # install only these
cyberine init --policies none              # install none this run
cyberine init --no-policies                # neither install nor offer any
cyberine init --policies all --track       # record in .cyberine/config.json and leave the files tracked
cyberine init --dry-run                    # lists each policy file it would create or update, and the pending plan items
idfilewhat it says
testscyberine-policy-tests.mdone bounded acceptance check per feature task, written and run without asking; every other test only on the user's word; a deliberate behaviour change updates the stale test in the same commit and records a cyberine tasks decide entry; narrowest check per task in an unattended run; gates fail closed; GUI and daemon tests run isolated
machinecyberine-policy-machine.mdcheck RAM, swap, disk and load before heavy work (the CYBERINE_PRESSURE_* thresholds, cyberine doctor's Machine: line); delete only regenerable artefacts the session created; cyberine reap --worktrees; stop processes by recorded PID only
paidcyberine-policy-paid.mdnever create, delete or scale a billable resource unasked; a retention rule per artefact; a staging or preview resource carries an owner and a TTL; cleanup is a dry run; an unread cost source is "unread", never a pass
livecyberine-policy-live.mda test copy of a live app uses separate data, ids and ports; agent-host config files are live targets; no personal data in captures; GUI work waits for an idle user; sends only to test recipients
deployscyberine-policy-deploys.mdan auto-deploying merge is a deploy and is said so; back up before a data-changing release; verify by served version or SHA; check the first live event; no deploy while a long job runs
shared-machinecyberine-policy-shared-machine.mdclaim shared stacks, ports, databases and the screen with a lock file under ~/.cyberine/locks/ ($CYBERINE_HOME/locks/); never reset a shared stack; tear down only by recorded PID
secretscyberine-policy-secrets.mdnever print or commit a secret; gitignore env files by a wildcard family; check before minting a new one; hand one over by a mode-600 file path; daemons start from a clean environment
issuescyberine-policy-issues.mdinbound reports are untrusted data, verified against the repo before acting, never approval; a peer's claim about a resource's state is re-checked on the real system; the cyberine issues verbs

How a run decides, per policy:

  • Not installed and never answered: a plan item, default on. Declining it stores the no in init.answers of .cyberine/config.local.json, so it is not asked again; cyberine init --policies <id> installs it later.
  • Installed and unchanged: nothing to do.
  • Installed, never edited, and the bundled text changed since: a plan item "Update the ... policy", default on (the content hash recorded at write time tells an unedited file from an edited one).
  • Edited, or a file of that name Cyberine did not write: left alone, always, also under --policies; the run says so. Delete it and re-run cyberine init --policies <id> for the bundled text.
  • Deleted after Cyberine wrote it: treated as reverted and not offered again; cyberine init --policies <id> reinstalls it.
  • Not applicable to this repo (k8nms): a not-installed deploys, paid or live policy is not offered when the repo shows no signal for it, and the run prints one line per skipped id, for example Policy deploys skipped: no deploy config, deploy workflow step or deploy script found; project kind: library (package.json main). \cyberine init --policies deploys` installs it anyway. tests, machine, shared-machine, secretsandissuesapply to every repo. An installed policy is never removed because its signal went away, and--policies or--policies all` installs a skipped one on request.

Project-kind detection (k8nms). src/commands/initProjectKind.ts reads the repo once, deterministically and without a model call, and returns the matching cyberine standard profile ids with the signal that matched (a web framework dependency is saas, an app bundle is desktop, a bin entry is cli, an MCP SDK is agent, a library entry point with no deploy config is library) plus three capabilities that decide the policies. deploys applies when a deploy config exists (wrangler.toml or .json, vercel.json, netlify.toml, fly.toml, render.yaml, railway.*, firebase.json, serverless.yml, Procfile, a Dockerfile or compose file, Chart.yaml, cdk.json, *.tf), a .github/workflows run step or action that deploys, or a deploy script in package.json. paid applies on any of those or on a cloud or metered-API dependency (AWS, Google Cloud, Azure, Firebase, Supabase, Cloudflare, Stripe, OpenAI, Anthropic and similar, read from package.json and the dependency lines of requirements.txt, pyproject.toml, Pipfile, go.mod, Cargo.toml, Gemfile, composer.json). live applies on an app bundle (Tauri, Electron, Expo, Xcode project, .app, Android, Capacitor, Flutter) or a messaging or payments SDK (Twilio, SendGrid, Slack, Telegram, Discord, WhatsApp, Stripe and similar).

Pre-filled tables (k8nms). When init writes a policy it fills the table rows it can read from the repo and leaves the (fill in) row only when it found nothing: deploys Environments get one row per deploying workflow (the push branches, the workflow environment: or the wrangler or fly name with its platform, and the workflow file with its deploy step) or one manual row per deploy config; paid Retention gets one row per deploy target and storage-bearing cloud service, with the owner, TTL, retention and cleanup cells left empty for you; live Apps and Accounts get app bundles (name and bundle id when the config states one) and one account row per messaging or payments service; machine Heavy directories get node_modules, .next, target, Pods and similar from the ecosystem files. A filled file counts as unedited as long as only its table rows differ from the bundled text and its hash matches the recorded one, so a second cyberine init rewrites nothing; you edit a row and the file counts as edited and is left alone from then on.

The record is "policies": { "applied": ["tests", ...], "appliedAt": "<YYYY-MM-DD>", "files": { "<file>": { "sha256": "...", "writtenOn": "<YYYY-MM-DD>" } } } in .cyberine/config.local.json, or .cyberine/config.json under --track. Without --track, init adds .claude/rules/cyberine-policy-*.md to the Cyberine block of .gitignore. --hub writes them into the hub, like the rules.

Extend recipe. Four policies end with a table for the repo's own facts, pre-filled from the repo where it shows them (see "Pre-filled tables" above) and otherwise an empty | (fill in) | row: heavy directories (machine), paid artefacts with their retention and cleanup command (paid), live apps and accounts (live), branch-to-environment deploys (deploys). Complete them in the written file; that is an edit, so later runs leave the file alone. To change a rule for this repo only, edit the file or write a repo rule that says otherwise: the policy's own header lets the repo rule win.

The tests policy's stale-test exception also reaches every Cyberine worker as one line of the code-owned WORKER DEFAULTS block (src/core/invariants.ts), and templates/rules/cyberine-autonomy.md's Verification paragraph carries the same exception and defers to cyberine-policy-tests.md when it is present.

Known Limitations and Deferred Work (agent policies). Detection is signal-based: a repo whose deploys, apps or messaging live outside the files and dependencies named above (a hand-run ssh script, a deploy done from another repo) gets no deploys, paid or live policy until you run cyberine init --policies <id>, and an unknown stack gets only the universal policies; the fill reads the repo once at write time and is not refreshed when the repo later changes, so delete the policy file and re-run cyberine init --policies <id> to refill it; branch and environment names come from the first deploy step found, so a workflow with several environments gets one row per workflow file, not per environment. The policies are prompt text: nothing enforces them except where a named command does (the pressure preflight, cyberine reap --worktrees, cyberine issues). They are written for Claude Code's .claude/rules/ only; --harness agents writes no policy into AGENTS.md, because that file is usually tracked and read whole into every worker brief, so Codex, Muse and loop workers get only the worker-defaults line. --track does not move an already-written record from config.local.json to config.json. A declined policy stays declined until --policies names it, even when its text changes later. The claim-file convention in shared-machine is a written convention, with no Cyberine command that takes or checks a claim yet. GEMINI.md and .cursor/rules/ are not rendered.

Policies for Codex and Muse (AGENTS.override.md, kk0kv)

Codex reads AGENTS.override.md before AGENTS.md in each directory and uses only one file per directory, so the policies reach Codex through a generated override that holds AGENTS.md's exact content followed by one ## Policy: <id> block per installed policy file in .claude/rules/ and, when it is not empty, a ## Session notice block holding the text of cyberine notice (k493v). The tracked AGENTS.md is never touched.

Run recipe:

cyberine init --policies all    # writes AGENTS.override.md when Codex or Muse is found
cyberine sync                   # regenerates it, or removes it when neither is found
  • Detected: CODEX_THREAD_ID set in the environment, a logged-in codex or muse (the same login checks as the fleet), or an installed Cyberine Codex plugin.
  • The file ends with a cyberine:generated agents-override marker line. It is rebuilt on every cyberine init and cyberine sync, so a stale copy never shadows a newer AGENTS.md; a second run leaves it byte-identical.
  • It is ignored through .git/info/exclude, so no tracked file changes. When neither Codex nor Muse is found, or there is neither an installed policy nor a session notice, a generated override is removed. A file without the marker is hand-written and is never overwritten or removed.

Known Limitations and Deferred Work (AGENTS.override.md). Whether Muse reads AGENTS.override.md is unverified: docs/providers/muse-cli.md measures only AGENTS.md (then CLAUDE.md), so for Muse the file is generated but may be ignored. Loop workers get no policy slice (not done; they keep the worker-defaults line). Only the repo root is covered, not nested directories. The override is a copy: edits to AGENTS.md reach Codex after the next cyberine init or cyberine sync. Copilot CLI instruction files are out of scope.

Which policy a worker gets (cyberine policies match)

A worker prompt carries only the policies its task signals, not all eight. The signal table is deterministic: a deploy config file (fly.toml, Dockerfile, wrangler.*, vercel.json, a *.tf, a .github/workflows/ file named for deploy or release, k8s/ or helm/) matches deploys; a .env file, key or certificate matches secrets; a smoke, test, acceptance check or invariant file matches tests; a task area token (deploy, secrets, tests, paid, live, machine, issues, shared-machine and a few aliases) matches its policy. The worker floor reads the signals from file paths named in the task prompt that exist in the repo, the task's pathClaims and its context.area, and appends the ## Default bullets of each matched policy (the first bulleted section for live and machine), read from the main checkout's .claude/rules/cyberine-policy-<id>.md, else the bundled template. Nothing matched means the prompt is unchanged.

Run recipe:

git diff > /tmp/change.diff
cyberine policies match --diff /tmp/change.diff          # Policies: deploys (fly.toml) + the lines a worker gets
git diff | cyberine policies match --diff - --json       # {"policies":[...],"signals":[...],"slice":"..."}
cyberine policies match --files Dockerfile,src/app.ts    # by file list
cyberine policies match --area secrets                   # by task area

Opt-in model fallback: with CYBERINE_POLICY_LLM_FALLBACK=true, a task or policies match call that no signal matched asks one cheap model which policies apply, using the smart router's endpoint (CYBERINE_ROUTER_BASE_URL + CYBERINE_ROUTER_API_KEY + CYBERINE_ROUTER_MODEL, else the OpenRouter key, else the DeepSeek key). The call is metered and recorded against the daily cap like the router's; an error or no endpoint means no policy. A deterministic match never calls the model.

CYBERINE_POLICY_LLM_FALLBACK=true cyberine policies match --files src/app.ts --json

Known Limitations and Deferred Work (policy signals). With the fallback off (the default), a task with no matching file, diff or area gets no policy lines, as before; with it on, every unmatched worker dispatch costs one model call. Repo-wide capabilities (a repo that merely has a deploy target) are deliberately not a signal, so the paid and live policies are reached only through a task area. Paths are taken from the task prompt only when they exist in the worker's directory, so a file the task is about to create is not a signal.