Catalog every config axis, its defaults and guards. Use when adding or auditing configuration. Do not use for running gates; use night-market-operations.
Catalog every config axis, its defaults and guards. Use when adding or auditing configuration. Do not use for running gates; use night-market-operations.
Night Market Config Catalog
Every configuration axis in this repo: where it lives, what the
options and defaults are, whether it is production policy or an
experimental opt-in, and what guards it. Flags drift, so every
axis ends with a one-line re-verification command. Run it before
trusting a value stated here.
Terms used once, defined once:
Axis: one independently tunable configuration surface (a
file, a key, or an environment variable).
Guard: the mechanism that notices when the axis breaks or
drifts (a test, a pre-commit hook, a CI job, or a script).
Shadow mode: a hook that evaluates and warns but does not
block. The blocking posture is opt-in.
coverage_threshold = 90 in 19 plugins, 85 in gauntlet (20 files total)
Production
Read by scripts/run-plugin-tests.sh
Pre-commit pins
.pre-commit-config.yaml
Remote pins: pre-commit-hooks v6.0.0, bandit 1.8.6 (last release supporting the 3.9 system interpreter). Ruff runs from a local repo via the uv-managed binary so hook and make format share one version
Guard test asserts LLM timeout stays under the registered hook budget
Caveat on the two .claude/*.json policy files: no Python
script in the repo reads them directly. They are policy inputs
referenced by docs/quality-gates.md and by sanctum command
prose (prepare-pr, pr-review configuration). Treat them as
contract documents for review workflows, not as runtime config
a daemon loads. Direct programmatic consumers: none found at
compile time (candidate: wire one before tightening values).
[tool.ruff.lint] select: E, W, F, I, B, C4, UP, PLC0415,
PLR0913. extend-ignore: E501, B007, B008, B905, E402, and
UP017. UP017 is load-bearing: it keeps timezone.utc instead
of the 3.11+ datetime.UTC alias because hook scripts must
import under the system Python 3.9. Removing it re-breaks
hooks (this has happened three or more times, and an AST test
now holds the line).
[tool.pytest.ini_options]: norecursedirs includes
plugins/*, so plugin tests MUST run per-plugin. Markers:
unit, integration, e2e, slow, network, plugin, skill, hook,
command, bdd, benchmark. --strict-markers is on.
[tool.coverage.report]: fail_under = 85 at root.
[tool.mypy]: python_version = "3.12" with strict-leaning
flags (disallow_untyped_defs, warn_unused_ignores, etc.).
[tool.uv.workspace] members: plugins/abstract,
plugins/leyline, plugins/conserve, plugins/core (a minimal set
for linting, not all 26 plugin dirs).
[tool.bandit] skips: B101, B103, B105, B108, B110, B112,
B310, B311, B404, B603, B607, B608. Each skip has an inline
rationale comment in the file. Keep that pattern when adding
one.
Manifest trio and the two semver namespaces
Each plugin ships three manifests that must stay in sync:
Two distinct semver namespaces appear in metadata.json and are
easy to confuse:
The ecosystem version ("version": "1.9.15"), bumped in
lockstep from marketplace.json by
plugins/sanctum/scripts/update_versions.py <version>.
Capability dependency ranges, for example imbue declares
"dependencies": {"abstract": ">=2.0.0"}. That 2.0.0 is a
capability-contract version, NOT the marketplace version.
Do not "fix" it to 1.9.x during a bump.
Environment variables
Variable
Consumer
Values and default
Effect
Status
VOW_SHADOW_MODE
imbue hooks via plugins/imbue/hooks/shared/vow_utils.py
Shadow default is production; blocking posture experimental
UV_TOOL_DIR
root Makefile (line 9)
Default ./.uv-tools
Where uv installs tools; ruff resolves from $(UV_TOOL_DIR)/ruff/bin first on PATH
Production
SKRILLS_REPO
root Makefile (skrills-build)
Default $HOME/skrills
Source checkout used to cargo-build the skrills binary
Production (skrills itself optional; Python fallbacks exist)
CONSERVATION_MODE
plugins/conserve/hooks/session-start.sh
quick, deep, normal; default normal; unknown values warn and fall back to normal
How much conservation guidance loads at session start
Production
DOUBLE_SHOT_LATTE_LLM
plugins/herald/hooks/double_shot_latte.py
Set "1" to enable
Enables the LLM "second shot" tiebreaker, only on the single ambiguous Stop-hook outcome
Experimental opt-in, default off
DOUBLE_SHOT_LATTE_MODEL
same hook
Default "haiku"
Model used for the second shot
Experimental
DOUBLE_SHOT_LATTE_MAX_CONTINUATIONS
same hook
Integer (read from env; see hook source for cap semantics)
Caps forced continuations
Production guard
CLAUDE_HOOK_JUDGE_MODE
same hook
"true" disables the LLM path
Prevents the judge from invoking itself recursively
Production guard
Experimental and opt-in flags
Both current experiments follow the same pattern: default off,
guard tests, blocking behavior only on explicit opt-in.
egregore completion_integrity
Key: pipeline.completion_integrity, a bool defaulting to
False in the PipelineConfig dataclass at
plugins/egregore/scripts/config.py (line 49 at compile
time).
Stored in the target repo's .egregore/config.json, read by
the summon skill alongside .egregore/manifest.json.
When True: a quality verdict of "fix-required" becomes a
step failure (cannot advance to ship) and merge is held for
human review regardless of auto_merge.
Guards: plugins/egregore/tests/test_config.py covers the
False default, the opt-in roundtrip, and loading from a
hand-written raw JSON file.
herald LLM second shot
The Stop hook itself is production (registered in
plugins/herald/hooks/hooks.json with timeout: 10).
The LLM tiebreaker is gated three ways: DOUBLE_SHOT_LATTE_LLM
must be "1", judge mode must not be active, and the turn
must land on the single ambiguous outcome (every confident
verdict skips the LLM entirely).
LLM_TIMEOUT_SECONDS = 8 is deliberately under the 10-second
registered budget. A value above the budget once made the harness
kill the hook before any verdict (full record:
night-market-failure-archaeology SB7). A guard test now asserts
the ordering. Never raise the LLM timeout without checking the
registered budget first.
Adding a config axis
Checklist for any new flag, threshold, or env var:
Default preserves current behavior (default off, or the
value the system already exhibits).
A guard test asserts the default AND the opt-in path,
including loading from raw serialized config
(model: plugins/egregore/tests/test_config.py).
Env vars validate their input and fall back to the default
on unknown values with a warning
(model: plugins/conserve/hooks/session-start.sh).
Any timeout inside a hook is asserted against the hook's
registered budget in hooks.json.
Add a row to the axis or env var table in this file, with
status (production or experimental) and guard.
Add a one-line re-verification command under Provenance.
If the axis affects gating or review policy, update
docs/quality-gates.md and route the change through
night-market-change-control.
When NOT to use
Running tests, lint, gates, or releases: use
night-market-operations.
Deciding whether a config change is allowed at all, or how to
review it: use night-market-change-control.
Plugin/skill/hook mechanics (what hooks.json fields mean,
how manifests load): use claude-code-plugin-reference.
Recreating the toolchain (uv, Python versions, skrills): use
night-market-build-and-env.
Diagnosing a broken gate or hook: use
night-market-debugging-playbook.
Exit Criteria
Every re-verification command under Provenance exits 0 and
its output matches the value stated in this catalog.
jq -r '.version' .claude-plugin/marketplace.json equals
the version in each plugin's plugin.json, metadata.json,
and openpackage.yml (spot-check at least one plugin).
rg -l "coverage_threshold" plugins/*/pyproject.toml | wc -l
returns 20. Any other count means this catalog is stale
and must be updated before use.
rg -n "completion_integrity: bool = False" plugins/egregore/scripts/config.py
matches. If the default changed, the Experimental section
here is wrong and must be rewritten.
A new config axis added by the current change appears in
the axis or env var table with a guard and a
re-verification one-liner.
Provenance and maintenance
Compiled 2026-07-02 against repo v1.9.15 (branch
discussions-fix-1.9.14). Line numbers and counts are volatile;
re-verify before quoting.
Known drift risks: pre-commit rev: pins (guarded by
scripts/check_pinned_versions.py), the coverage-threshold file
count (20 at compile time), the egregore config.py line number,
and the promotion status of the two experimental flags (see
night-market-completion-integrity-campaign for the promotion
question).