singularity doctor
Run the runtime's read-only connectivity and capability preflight. It starts no autonomous cycle and writes no being state.
Invocation
singularity doctor \
--agent-id <id> \
--role <role> \
--environment <environment> \
--host <host> \
--workload-id <id> \
--workload-public-key <64-lowercase-hex> \
--executable-digest <64-lowercase-hex> \
--code-digest <64-lowercase-hex> \
--policy-digest <64-lowercase-hex> \
--policy-sequence <integer> \
--starting-balance <declared-usd> \
--instance-price <declared-usd-per-hour> \
--cycle-interval-secs <declared-seconds> \
--las-release-manifest <absolute-file> \
--las-release-manifest-signature <absolute-file> \
--las-release-trust-store <absolute-file> \
--las-release-watermark <absolute-path>Required inputs
The command requires these options, or their named environment-variable equivalents:
--agent-id(SINGULARITY_AGENT_ID),--role(SINGULARITY_ROLE),--environment(SINGULARITY_ENVIRONMENT),--host(SINGULARITY_HOST), and--workload-id(SINGULARITY_WORKLOAD_ID). Each is a 1–128 byte immutable identifier using only ASCII letters, digits,-,_,., or:.--workload-public-key,--executable-digest,--code-digest, and--policy-digest. Each value is exactly 64 lowercase hexadecimal characters.--policy-sequence <integer>.--starting-balance <declared-usd>(SINGULARITY_STARTING_BALANCE_USD),--instance-price <declared-usd-per-hour>(SINGULARITY_INSTANCE_USD_PER_HOUR), and--cycle-interval-secs <declared-seconds>(SINGULARITY_CYCLE_INTERVAL_SECS). No initial balance, free host, or cycle pause is assumed. A missing declaration exits 2 before state creation or service access. A free host must explicitly state a zero price.--las-release-manifest,--las-release-manifest-signature, and--las-release-trust-store. Each must name an absolute regular file.--las-release-watermarkmust be absolute.- Brama signing material, on Brama's route: either
--brama-secret-file <owner-only-file>/BRAMA_HMAC_SECRET_FILE, orWISENT_APP_AGENT_AUTH_SECRETwhen no file is supplied. - Brama caller authorization, on Brama's route:
--brama-bearer-file <owner-only-file>/BRAMA_BEARER_TOKEN_FILEis required separately. An HMAC identity signature does not replace the bearer. An endpoint Stado resolves in Brama's place needs neither.
Runtime options
- Persona: required
--agent-name <name>and--agent-ticker <ticker>(SINGULARITY_AGENT_NAME,SINGULARITY_AGENT_TICKER; no persona is assumed),--agent-type general, and--specialty general. - State and loop:
--stimulus <text>, optional--import-file <singularity-mind-import-v1.json>, the required balance, host-price and cycle-pause declarations above, required--state-dir <dir>and--workspace <dir>(SINGULARITY_STATE_DIR,SINGULARITY_WORKSPACE; no directory is assumed), and--resume. The starting balance applies to a new being; resume keeps its saved budget. A spawned child receives the parent's resolved initial allowance, host price and cycle pause, including values supplied through CLI flags; these are accounting declarations, not transfers of funds. A cycle runs until the model answers without calling a tool; there is no round limit, and every round is charged at Brama's catalog price for the model that served it. Onrunandonce, the complete import is validated before a new state is created and persisted before the first model call. - Model service: optional
--brama-url <url>(BRAMA_BASE_URL). Unnamed, the being never dials Brama itself: it takes the routestado capabilities resolve inference --consumer singularityhands out, Brama's or the OpenAI-compatible endpoint declared in its place, which serves its own declared model, is sent the key of its key role and no Brama credential or signature, and takes its prices fromSINGULARITY_MODEL_CATALOG_FILE; when nothing answers, the launch is refused naming every alternative and its cause.--brama-model <model|any|any-vision-capable|task:name>(BRAMA_MODEL; no model is assumed) is required on Brama's route. Optional--max-tokens <n>(BRAMA_MAX_TOKENS; omitted, the model's own output limit from the catalog applies and cost admission quotes against it), and optional--temperature <t>(BRAMA_TEMPERATURE; omitted, none is sent and the provider's default applies). Token prices are not configured: each round is charged at the catalog price of the model that served it. - Las: required
--las-command <program>,--las-entrypoint <file>and--las-only <csv>(LAS_COMMAND,LAS_MCP_ENTRYPOINT,LAS_ONLY; no program, checkout location or surface set is assumed, and an empty--las-onlyserves every surface Las offers),--las-skip <csv>, and--required-surfaces skarbiec,finance. - Most and transport:
--most-url <url>(MOST_BASE_URL), required whenever a Most credential is configured through optional--most-token-file <owner-only-file>or the bootstrap handoff, and otherwise refused asa Most credential is configured but MOST_BASE_URL (--most-url) is not. A spawned child being receives the parent's Brama address and model on Brama's route (neither when an endpoint answers in Brama's place, so it resolves as its parent did) and Most address. Model, Most and MCP calls wait for their own answer or explicit cancellation.
Managed bootstrap and Las children retain an absolute HOME owned by the current Unix principal and not writable by another principal. Their executable search starts with $HOME/.local/bin and $HOME/.stado/bin, followed by the fixed operating-system and package-manager directories. A missing or unsafe home is refused, not replaced with another account's home. On Brama's route, ecosystem execution passes its configured Brama bearer, signing secret and agent identity into Jeden explicitly; with an endpoint in Brama's place it passes the agent identity only, and Jeden resolves its own route through Stado. Request state is isolated under the ecosystem owner's directory.
Every flag above also has the environment-variable spelling exposed by singularity <command> --help. The global --text, anywhere on the line, prints every report once, import, onboarding --import-file and doctor produce as indented key: value lines instead of JSON, from the same data.
Checks, output, and state effect
The command checks the model service's GET /health (Brama, or the endpoint Stado resolves in its place), reads GET /v1/models, and requires the configured exact model to be present. The selectors any, any-vision-capable, and task:* do not require an exact catalogue match. When --most-token-file is supplied, it checks that Most has at least one send-capable backend. It then spawns Las and requires at least one <surface>__ tool for every name in --required-surfaces.
Success prints pretty JSON shaped as {"ok":true,"model":...,"model_service":{"provider":...,"url":...},"most":...,"las_tools":...}. most is null when no token file is configured. The being state directory and activity journal are untouched; Las is stopped before return.
Doctor-specific refusals
- An exact configured model the model service does not serve is refused as
configuration: configured model <model> is not served by <provider> at <url>; it serves <models>. - A configured Most service with an empty or
nonebackend report is refused asmost: Most has no send-capable backend. - A missing required Las surface is refused as
mcp: required Las surface unavailable: <surface>. - Las refusing startup, MCP initialization, tool listing, or shutdown is an upstream failure and exits 3.
Configuration refusals
Before contacting a surface or writing being state, the runtime refuses with the exact relevant message when:
- stimulus contains NUL:
configuration: stimulus must contain no NUL; the runtime imposes no byte ceiling; - the workspace cannot be resolved or is not a directory:
configuration: workspace: <error>orconfiguration: workspace must be a directory; - a starting balance or price is negative:
configuration: prices and balance cannot be negative; - a stated temperature is not finite or is negative:
configuration: temperature must be finite and not negative(the upper end is the provider's, which refuses a value outside its range with its own message); - the Las entrypoint is not a file:
configuration: LAS entrypoint not found: <path>; - a release manifest, signature, or trust-store path is not absolute or not a regular file:
configuration: <label> must be an absolute regular file; - the watermark path is relative:
configuration: LAS release watermark must be an absolute path; - an immutable identity component is invalid:
configuration: <label> is not a valid immutable identifier; - a public key or digest is malformed:
configuration: <label> must be 64 lowercase hexadecimal characters; - neither Brama secret source exists:
secret file: BRAMA_HMAC_SECRET_FILE or WISENT_APP_AGENT_AUTH_SECRET is required; - a secret path is not a regular file, is group/world accessible, or is empty:
secret file: not a regular file: <path>,secret file: <path> must not be group/world accessible; observed mode <mode>; chmod go-rwx it, orsecret file: <path> is empty.
Clap refuses a missing required option before runtime code executes. Configuration and secret refusals exit 2; upstream Brama, Las/MCP, or Most failures exit 3; state or I/O failures exit 4; tool, runtime, or JSON failures exit 5.