Skip to Content
Numinance
CLI

numi init

Scaffold a .numinance policy tree for a Python repository, with every flag, real runs and exit codes, and the files it writes.

View as .mdUpdated
Pre-alpha

Available in the open build and the engine build. Writes documents; resolves nothing.

numi init writes a starter .numinance/ tree whose autonomy level is PR only: the agent may open pull requests and may never merge. It names a CI system only because you pass --ci.

When to use

You have a Python repository on GitHub and want a first set of kind documents that pass schema validation. Python and GitHub are the only language and source-control provider the template supports today.

Synopsis

numi init --ci github-actions|jenkins|both [--org-dir DIR] [--package-manager uv|pip|poetry]
          [--python-version 3.N] [--verifiers LIST] [--language python] [--scm github]
          [--tickets file] [--force] [path]

path is the repository and defaults to ..

Flags

FlagMeaning
--ci SYSTEMgithub-actions, jenkins or both. Required. Absent is a usage error, because a default would wire a system the repository may not have.
--org-dir DIRAlso write the org-scoped documents into this organization policy repository.
--package-manager NAMEuv, pip or poetry. Default: detected from uv.lock, poetry.lock, pyproject.toml ([tool.poetry], [tool.uv]) or requirements.txt, in that order; uv when nothing is found. Two conflicting hints are a usage error until the flag decides.
--python-version 3.NDefault: the first line of .python-version when it is a plain 3.N or 3.N.P, else 3.12.
--verifiers LISTComma-separated subset of unit-tests, lint, typecheck (pytest, ruff, mypy of the verifier provider). Default: all three.
--language pythonOptional. Python is the only accepted value and the default.
--scm githubOptional. GitHub is the only accepted value and the default.
--tickets fileOptional. file is the only accepted value. Writes no ticketing binding; adds one README line saying tickets come from the ticket file a run is given.
--forceOverwrite the files init writes in an existing .numinance. Other files are never touched.

Run it

The examples below were run with the open build against empty scratch directories. Paths shown are the ones init prints.

Package manager and verifiers

numi init: repository "."
chose: package manager poetry (flag)
chose: python 3.12 (default)
chose: verifiers lint typecheck (flag)
chose: ci github-actions (flag)
chose: language python (default)
chose: scm github (default)
chose: tickets none (default)
wrote ".numinance/policy/sdlc-profile.yaml"
wrote ".numinance/policy/autonomy.yaml"
wrote ".numinance/policy/stage-registry.yaml"
wrote ".numinance/policy/playbook-bugfix-bounded.yaml"
wrote ".numinance/policy/toolchain-python.yaml"
wrote ".numinance/README.md"
autonomy: PR only (ladder level AUTONOMY_LEVEL_PR, no merge)
note: without --org-dir the stage registry is not selected and floors are the engine's shipped floors (PR; HIGH at SUGGEST)
next: numi validate "."
✓ verifiednumi init --ci github-actions --package-manager poetry --verifiers lint,typecheck .· numinance-spec @ 3c74d59 · 2026-11-09· 0

Each chose: line names the source of the value: flag, default, or detected from <file>. Leaving unit-tests out removes the note about it; see the caution below.

Why the supported set is lint,typecheck

The unit-tests verifier is pytest, which runs candidate code. In the live verifier provider it is unavailable until a nested sandbox exists, so its layer and verdict come out inconclusive, never a pass. Until then the supported set is --verifiers lint,typecheck.

CI both, without an organization directory

numi init: repository "."
chose: package manager uv (default, no hint in the directory)
chose: python 3.12 (default)
chose: verifiers unit-tests lint typecheck (default)
chose: ci github-actions and jenkins (flag)
chose: language python (default)
chose: scm github (default)
chose: tickets none (default)
wrote ".numinance/policy/sdlc-profile.yaml"
wrote ".numinance/policy/autonomy.yaml"
wrote ".numinance/policy/stage-registry.yaml"
wrote ".numinance/policy/playbook-bugfix-bounded.yaml"
wrote ".numinance/policy/toolchain-python.yaml"
wrote ".numinance/ci-jenkins.yaml"
wrote ".numinance/README.md"
autonomy: PR only (ladder level AUTONOMY_LEVEL_PR, no merge)
note: no Jenkins provider exists yet; the Jenkins binding names a placeholder provider id
note: one ciexecutor binding takes effect per scope: github-actions; the Jenkins binding is in .numinance/ci-jenkins.yaml and is ignored
note: unit-tests (pytest) runs candidate code and is UNAVAILABLE in the live verifier provider until its nested sandbox exists
note: without --org-dir the stage registry is not selected and floors are the engine's shipped floors (PR; HIGH at SUGGEST)
next: numi validate "."
✓ verifiednumi init --ci both . (in an empty directory)· numinance-spec @ 3c74d59 · 2026-11-09· 0

ci-jenkins.yaml sits outside policy/, so it carries no authority. The Jenkins binding names a placeholder provider; no Jenkins provider exists, and validate does not check that a provider is installed. A green validate therefore never means Jenkins works.

CI both, with an organization directory

numi init: repository "."
chose: package manager uv (default, no hint in the directory)
chose: python 3.12 (default)
chose: verifiers unit-tests lint typecheck (default)
chose: ci github-actions and jenkins (flag)
chose: language python (default)
chose: scm github (default)
chose: tickets none (default)
wrote ".numinance/policy/sdlc-profile.yaml"
wrote ".numinance/README.md"
organization policy repository "<scratch>/org"
wrote ".numinance/policy/sdlc-profile.yaml"
wrote ".numinance/policy/autonomy.yaml"
wrote ".numinance/policy/stage-registry.yaml"
wrote ".numinance/policy/playbook-bugfix-bounded.yaml"
wrote ".numinance/policy/toolchain-python.yaml"
wrote ".numinance/policy/ci-jenkins.yaml"
wrote ".numinance/README.md"
autonomy: PR only (ladder level AUTONOMY_LEVEL_PR, no merge)
note: no Jenkins provider exists yet; the Jenkins binding names a placeholder provider id
note: one ciexecutor binding takes effect per scope: github-actions; the Jenkins binding is an org grant in .numinance/policy/ci-jenkins.yaml of the organization policy repository and is not bound: the repository profile binds github-actions, and rebinding it to the placeholder is your explicit edit that validate does not check
note: unit-tests (pytest) runs candidate code and is UNAVAILABLE in the live verifier provider until its nested sandbox exists
next: numi validate "."
✓ verifiednumi init --ci both --org-dir ../org . (organization policy repository in a sibling directory)· numinance-spec @ 3c74d59 · 2026-11-09· 0

(<scratch> replaces the absolute scratch path that was printed.)

Why the split matters: only the org scope selects the stage registry and grants playbook, toolchain and adapter-binding names to repositories. A repository that asks for a name the org did not grant has it recorded as ignored: "outside the org-granted set" and not applied. With --org-dir, the repository keeps only its own profile; everything shared moves to the org tree. Without it, the registry is defined but not selected.

Overwrite with --force

numi init: repository "."
chose: package manager poetry (detected from pyproject.toml [tool.poetry])
chose: python 3.12 (default)
chose: verifiers unit-tests lint typecheck (default)
chose: ci github-actions (flag)
...
wrote ".numinance/README.md"
autonomy: PR only (ladder level AUTONOMY_LEVEL_PR, no merge)
✓ verifiednumi init --ci github-actions --force . (in a directory whose pyproject.toml has a [tool.poetry] table, over an earlier init)· numinance-spec @ 3c74d59 · 2026-11-09· 0

(Middle lines elided; they match the first example.) --force replaces only the files init writes.

Errors and exit codes

Exit codes of init: 0 OK, 1 internal, 2 usage, 3 invalid, 4 not found, 5 conflict.

numi init: .numinance already has files; pass --force to overwrite the files init writes (other files are never touched)
✓ verifiedSecond run without --force· numinance-spec @ 3c74d59 · 2026-11-09· 5
numi init: directory "<scratch>/nope" not found
✓ verifiednumi init --ci jenkins on a missing directory· numinance-spec @ 3c74d59 · 2026-11-09· 4
numi init: "<scratch>/f" is not a directory that can be opened
✓ verifiednumi init --ci jenkins on a regular file· numinance-spec @ 3c74d59 · 2026-11-09· 3
numi init: --org-dir is the repository itself (same directory by another spelling); the organization policy repository is a different directory
✓ verifiednumi init --ci both --org-dir . .· numinance-spec @ 3c74d59 · 2026-11-09· 3
numi init: conflicting package manager hints (uv.lock, poetry.lock); pass --package-manager
✓ verifieduv.lock and poetry.lock both present, no --package-manager· numinance-spec @ 3c74d59 · 2026-11-09· 2
numi init: --scm gitlab: only github has a provider
✓ verifiednumi init --ci both --scm gitlab· numinance-spec @ 3c74d59 · 2026-11-09· 2

A usage error also prints the usage block. Omitting --ci is exit 2 with numi init: --ci is required: github-actions, jenkins or both. --language go and --tickets jira are exit 2 with a one-line reason (only python has a toolchain template, no ticketing provider exists yet; use file). Exit 3 also covers a .numinance directory, policy/ or a document that is a symbolic link or not a regular file.

What it writes

.numinance/policy/ is the protected location: a document there carries authority, so protect it with branch protection and CODEOWNERS.

FileKindContent
policy/sdlc-profile.yamlSDLCProfile (repo)playbooks, toolchains, adapters.scm (dev.numinance.scm-github) and the one adapters.ciexecutor
policy/autonomy.yamlAutonomyPolicydefaults.level: AUTONOMY_LEVEL_PR
policy/stage-registry.yamlStageRegistry pr-onlytriage, plan gate, implement, a static verify stage, one CI verify stage per CI system, and a human pr-gate. No stage maps to Merging
policy/playbook-bugfix-bounded.yamlPlaybookThree steps, one per identity kind: fix, review, pr-status. No step merges
policy/toolchain-python.yamlLanguageToolchainLanguage, version, package_manager and the verifiers with provider dev.numinance.verifier-python
ci-jenkins.yamlAdapterSelectorOnly for --ci both without --org-dir; outside policy/, so no authority
README.mdWhat the tree is

Excerpt of the repository profile from the first run above, as written:

.numinance/policy/sdlc-profile.yaml (excerpt)
apiVersion: numinance.dev/v1
kind: SDLCProfile
metadata: {name: python-repo, scope: SCOPE_REPO}
spec:
  playbooks: [bugfix-bounded]
  toolchains: [python-3.12]
  adapters:
    scm: {provider: dev.numinance.scm-github, instance: main}
    ciexecutor: {provider: dev.numinance.ci-github-actions, instance: ci}

The playbook's repair bound is max_repair_attempts: 2: finite attempts, then escalation. See Playbooks.

PR only, and floors

The ladder level is AUTONOMY_LEVEL_PR: the agent opens pull requests and never merges. PR_ONLY is a breaker state of the engine, not a ladder level. Floors are a ceiling and only the org scope (and control packs) may set them, so a floors block in a repository is refused by the loader and the resolver. With --org-dir the org tree gets an AutonomyPolicy whose floors cap every change at PR and keep HIGH risk at SUGGEST. Without it the engine applies its shipped floor, which is the same cap. Raising autonomy is a human decision made later; see autonomy policy.

Check the output

revision: "working tree (uncommitted changes included)"
ok       repo ".numinance/policy/autonomy.yaml" AutonomyPolicy "pr-only"
ok       repo ".numinance/policy/playbook-bugfix-bounded.yaml" Playbook "bugfix-bounded"
ok       repo ".numinance/policy/sdlc-profile.yaml" SDLCProfile "python-repo"
ok       repo ".numinance/policy/stage-registry.yaml" StageRegistry "pr-only"
ok       repo ".numinance/policy/toolchain-python.yaml" LanguageToolchain "python-3.12"
numi validate: profile resolution needs the Numinance engine build
✓ verifiednumi validate . (open build) after init· numinance-spec @ 3c74d59 · 2026-11-09· 7

Exit 7 is the open build telling you profile resolution did not run. numi validate --files .numinance exits 0 after the schema check only. Profile resolution reads a committed revision in the engine build. See validate.

How files are written

Files are written through os.Root (no path leaves the directory), refusing links, mode 0644 for files and 0755 for directories, each through a temporary name and a rename. What a failed run created is removed again. Without --force a document is created by hard link so a file that appeared after the check is never replaced; on a file system without hard links the writer falls back to rename and that small window remains. A leftover *.numi-init.tmp is a conflict (exit 5).

Next steps

On this page