Return to the declick overview
declick 0.3.0 control matrix
Every control below is in the shipped runtime. The verification column is the command that demonstrates it, run against an adapter you build yourself. Controls that need configuration do nothing until the named environment variables are set, and they sit in their own table so the unconditional set can be reviewed alone. This page prints to five pages on A4 and on Letter.
version 0.3.0node >=24license MITruntime dependencies 0
$ declick version --json
{"ok":true,"data":{"version":"0.3.0","node":"24.15.0"},"meta":{"count":1,"truncated":false}}
declick version --jsonexit 0Controls active with no configuration
Ten controls, each with the mechanism, the observable result, and the command that shows it. Nothing in this table depends on a network service, a policy file, or a subscription. Exit codes are stable across all nine engines, so a pipeline can treat exit 3 as blocked and exit 4 as missing credentials without knowing which engine produced the adapter.
| ID | Control | Mechanism | Observable | Verify with |
|---|---|---|---|---|
C-01 |
credential origin scoping | key released only to the origin the adapter was built against | exit 4 naming the scoped origin | DECLICK_<NAME>_BASE_URL=https://other.example declick run <name> <verb> |
C-02 |
secret masking | header and query values replaced by env names in --curl and --verbose |
api_key: <NAME_API_KEY> |
declick run <name> <verb> --curl |
C-03 |
manifest stores key names only | values read from process.env then ~/.creds/vault.env at run time |
no value in ~/.declick/<name>/manifest.json |
declick manifest <name> |
C-04 |
launcher shadow refusal | add refuses a name that resolves on PATH unless --force |
exit 1 naming the existing binary | declick add app:Calculator --name calc |
C-05 |
unknown-flag rejection | flags checked against the manifest before the request is built | exit 1 with did-you-mean | declick run <name> <verb> --nope |
C-06 |
manifest text validation | spec-sourced text must be one line, no backticks, no leading #, bounded length; describe sanitizes on output | exit 1 from lint | declick lint <name> |
C-07 |
audit log on by default | one line per invocation to ~/.declick/audit.jsonl |
newest-first listing | declick audit |
C-08 |
ui token | random per-start X-Declick-Token required on every mutating POST |
401 without it | declick ui --port 4899 --json |
C-09 |
ui Host and Origin check | requests from another origin refused; authoring 403 without --allow-authoring |
403 | curl -X POST -H 'Origin: http://evil' -H 'Content-Type: application/json' -d '{}' http://127.0.0.1:4870/api/add |
C-10 |
desktop arming and STOP file | acting calls refused unless armed and no STOP file | exit 3 | declick desk status |
Controls requiring configuration
| ID | Control | Mechanism | Observable | Verify with |
|---|---|---|---|---|
C-11 |
guard on every mutating call | DASHCLAW_API_KEY, DASHCLAW_URL |
decision in meta.governance |
declick run <name> <mutating verb> |
C-12 |
strict fail-closed | same variables | exit 3 on unreachable, timeout, or non-decision; DECLICK_GUARD=open restores warn |
DASHCLAW_API_KEY=test-key DASHCLAW_URL=http://127.0.0.1:9 declick run <name> <mutating verb> |
C-13 |
arg redaction before transmission | same variables | secret-shaped args become <redacted>, others truncated at 64 chars |
declick run <name> <mutating verb> --verbose |
C-14 |
authoring sandbox | Claude Code CLI on PATH; DECLICK_AUTHOR_TIMEOUT_MS |
allowlisted environment, no ANTHROPIC_API_KEY, bounded at 300000 ms |
declick add app:<title> --goal "..." --verb v |
Every command in the verify column is a real command from commands --json or the README; placeholders in angle brackets are the reader's own adapter.
Exit codes, envelope fields, and files on disk
Three reference lists. Exit codes: 0 ok, 1 error, 2 not found, 3 blocked, 4 auth needed. Every adapter envelope carries meta.governance with enabled, decision and reason, meta.dryRun true on a preview, and meta.credentials when a key was read or crossed an origin. On disk, declick writes ~/.declick/<name>/manifest.json, ~/.declick/<name>/recipes/, ~/.declick/<name>/proposals/, ~/.declick/<name>/last-error.json, ~/.declick/bin/ for launchers, ~/.declick/audit.jsonl for the log, and ~/.claude/skills/<name>/SKILL.md for agent discovery. It never overwrites a SKILL.md it did not write.
Exit codes
- exit 0
- ok
- exit 1
- error
- exit 2
- not found
- exit 3
- blocked
- exit 4
- auth needed
Envelope fields
- meta.governance
- enabled, decision and reason, on every adapter envelope.
- meta.dryRun
- true on a preview.
- meta.credentials
- present when a key was read or crossed an origin. From this session's capture:
{"name":"PETSTORE_API_KEY","from":"env"}. The documented four-field form{name, from, scopedTo, sentTo}appears whenDECLICK_ENV_ALLOWreleases a key across origins.
Files on disk
- ~/.declick/<name>/manifest.json
- the compiled manifest
- ~/.declick/<name>/recipes/
- the recipes for the adapter
- ~/.declick/<name>/proposals/
- proposals from authoring
- ~/.declick/<name>/last-error.json
- the last error
- ~/.declick/bin/
- launchers
- ~/.declick/audit.jsonl
- the log
- ~/.claude/skills/<name>/SKILL.md
- agent discovery. declick never overwrites a SKILL.md it did not write.