apply
Implement tasks from an OpenSpec change (Experimental)
Use the Bash tool to prepare the workspace (in PROJECT_ROOT):
> /plugin marketplace add heurema/signum > /plugin install signum@signum
How it fires
How this command gets triggered: by you, by Claude, or both.
/60-setupContext preview
What this command does when you run it.
Use the Bash tool to prepare the workspace (in PROJECT_ROOT):
Use the Bash tool to prepare the workspace (in PROJECT_ROOT):
cd "$PROJECT_ROOT" || exit 1 mkdir -p .signum/contracts touch .gitignore grep -q '^\.signum/$' .gitignore || echo '.signum/' >> .gitignore # Check external CLI availability CODEX_INSTALLED=$(which codex > /dev/null 2>&1 && echo "yes" || echo "no") GEMINI_INSTALLED=$(which gemini > /dev/null 2>&1 && echo "yes" || echo "no") EXTERNAL_COUNT=0 [ "$CODEX_INSTALLED" = "yes" ] && EXTERNAL_COUNT=$((EXTERNAL_COUNT + 1)) [ "$GEMINI_INSTALLED" = "yes" ] && EXTERNAL_COUNT=$((EXTERNAL_COUNT + 1)) echo "External providers: codex=$CODEX_INSTALLED gemini=$GEMINI_INSTALLED ($EXTERNAL_COUNT/2)" if [ "$EXTERNAL_COUNT" -eq 0 ]; then echo "NOTE: No external review CLIs installed. Single-model mode:" echo " - low risk: AUTO_OK possible (Claude review sufficient)" echo " - medium risk: AUTO_OK possible (graceful degradation)" echo " - high risk: AUTO_OK requires manual review (multi-model required)" echo " Install codex/gemini for full multi-model audit." fi
Resolve external CLI model overrides from `~/.claude/emporium-providers.local.md`. This file uses YAML frontmatter to configure models for codex and gemini invocations.
Use the Bash tool to define the `_resolve_model` helper and resolve models for this session:
_resolve_model() {
local task="$1" provider="$2"
local config="${EMPORIUM_PROVIDERS_CONFIG:-$HOME/.claude/emporium-providers.local.md}"
[ -f "$config" ] || return 0
python3 -c "
import sys, re, os
config_path = os.environ.get('EMPORIUM_PROVIDERS_CONFIG', os.path.expanduser('~/.claude/emporium-providers.local.md'))
try:
with open(config_path) as f:
text = f.read()
except Exception:
sys.exit(0)
# Extract YAML frontmatter
m = re.match(r'^---\s*\n(.*?)\n---', text, re.DOTALL)
if not m:
sys.exit(0)
fm = m.group(1)
# Minimal YAML parser (stdlib only, no PyYAML dependency)
def parse_yaml_flat(lines):
\"\"\"Parse simple nested YAML into dot-separated key dict.\"\"\"
result = {}
stack = [] # (indent_level, key_prefix)
for line in lines:
stripped = line.rstrip()
if not stripped or stripped.startswith('#'):
continue
indent = len(line) - len(line.lstrip())
# pop stack to find parent
while stack and stack[-1][0] >= indent:
stack.pop()
prefix = stack[-1][1] + '.' if stack else ''
if ':' in stripped:
key, _, val = stripped.partition(':')
key = key.strip()
val = val.strip().strip('\"').strip(\"'\")
full_key = prefix + key
if val:
result[full_key] = val
stack.append((indent, full_key))
return result
data = parse_yaml_flat(fm.split('\n'))
task = '$task'
provider = '$provider'
# Resolution order: routing.task.provider -> routing.default.provider -> defaults.provider.model
model = ''
for lookup in [f'routing.{task}.{provider}', f'routing.default.{provider}', f'defaults.{provider}.model']:
if lookup in data:
model = data[lookup]
break
# Validate model name
if model and not re.match(r'^[A-Za-z0-9._:-]+\$', model):
model = ''
print(model)
" 2>/dev/null
}
SIGNUM_CODEX_MODEL=$(_resolve_model "review" "codex")
SIGNUM_GEMINI_MODEL=$(_resolve_model "review" "gemini")
SIGNUM_CODEX_PROFILE="${SIGNUM_CODEX_PROFILE:-}"
echo "codex_model=${SIGNUM_CODEX_MODEL:-(cli default)} gemini_model=${SIGNUM_GEMINI_MODEL:-(cli default)} codex_profile=${SIGNUM_CODEX_PROFILE:-(none)}"Save `SIGNUM_CODEX_MODEL` and `SIGNUM_GEMINI_MODEL` for use in all subsequent codex/gemini invocations. If either is empty, do NOT pass `--model` — let the CLI use its built-in default.
Use the `PROJECT_ROOT` determined during Project Resolution. Verify we are in the correct directory:
Check for a resumable working set using `contracts/index.json` first. Root `.signum/contract.json` is only a legacy fallback during the migration:
source lib/contract-dir.sh
RESUME_INFO=$(describe_active_contract_state)
RESUME_STATE=$(printf '%s' "$RESUME_INFO" | jq -r '.state')
RESUME_CONTRACT_ID=$(printf '%s' "$RESUME_INFO" | jq -r '.contractId // empty')
RESUME_STATUS=$(printf '%s' "$RESUME_INFO" | jq -r '.status // empty')
if [ "$RESUME_STATE" = "NONE" ] && [ -f .signum/contract.json ] && [ ! -L .signum/contract.json ]; then
if [ -f .signum/execution_context.json ] && [ ! -L .signum/execution_context.json ]; then
RESUME_STATE="LEGACY_RESUMABLE"
else
RESUME_STATE="LEGACY_CONTRACT_ONLY"
fi
fi
jq -n \
--arg state "$RESUME_STATE" \
--arg contractId "$RESUME_CONTRACT_ID" \
--arg status "$RESUME_STATUS" \
'{
state: $state,
contractId: (if $contractId == "" then null else $contractId end),
status: (if $status == "" then null else $status end)
}'If the user chooses to resume a legacy root-based working set, migrate it into the canonical active contract directory before continuing:
source lib/contract-dir.sh LEGACY_CONTRACT_ID=$(jq -r '.contractId // empty' .signum/contract.json 2>/dev/null || true) if [ -z "$LEGACY_CONTRACT_ID" ] || [ "$LEGACY_CONTRACT_ID" = "null" ]; then LEGACY
Signum is a contract-first proof gate for agentic software changes: it turns a task into a reviewed contract, executes against that contract, audits the result, and packages evidence that humans and CI can inspect.
Repo: heurema/signum
Implement tasks from an OpenSpec change (Experimental)
Archive a completed change in the experimental workflow
Enter explore mode - think through ideas, investigate problems, clarify requirements
Propose a new change - create it and generate all artifacts in one step