loki-mode 7.129.5 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +81 -5
- package/SKILL.md +66 -5
- package/VERSION +1 -1
- package/autonomy/app-runner.sh +37 -0
- package/autonomy/completion-council.sh +862 -28
- package/autonomy/council-v2.sh +39 -0
- package/autonomy/crash.sh +3 -2
- package/autonomy/grill.sh +42 -0
- package/autonomy/hooks/validate-bash.sh +301 -4
- package/autonomy/lib/cockpit-render.sh +8 -2
- package/autonomy/lib/cr-rematerialize.py +101 -4
- package/autonomy/lib/deadline.py +957 -0
- package/autonomy/lib/dependency-setup.sh +205 -0
- package/autonomy/lib/done-recognition.sh +45 -0
- package/autonomy/lib/efficiency_cost.py +13 -6
- package/autonomy/lib/no_mock_scan.py +793 -0
- package/autonomy/lib/prd-enrich.sh +42 -0
- package/autonomy/lib/proof-analytics-props.py +69 -0
- package/autonomy/lib/proof-generator.py +282 -95
- package/autonomy/lib/proof-template.html +15 -12
- package/autonomy/lib/proof-verify.py +151 -102
- package/autonomy/lib/requirements_contract.py +848 -0
- package/autonomy/lib/sdk-mode.sh +103 -0
- package/autonomy/lib/secret-scan.sh +139 -0
- package/autonomy/lib/spec-expand.sh +208 -0
- package/autonomy/lib/tree_digest.py +266 -0
- package/autonomy/lib/voter-agents.sh +58 -8
- package/autonomy/lib/workspace_diff.py +124 -0
- package/autonomy/loki +189 -17
- package/autonomy/playwright-verify.sh +501 -0
- package/autonomy/prd-checklist.sh +17 -8
- package/autonomy/provider-offer.sh +111 -0
- package/autonomy/run.sh +4417 -676
- package/autonomy/sandbox.sh +42 -0
- package/autonomy/spec-interrogation.sh +148 -5
- package/autonomy/spec.sh +118 -1
- package/autonomy/telemetry.sh +133 -7
- package/autonomy/verify.sh +107 -0
- package/bin/loki +110 -3
- package/completions/_loki +10 -0
- package/completions/loki.bash +1 -1
- package/dashboard/__init__.py +1 -1
- package/dashboard/audit.py +96 -7
- package/dashboard/build_supervisor.py +1619 -0
- package/dashboard/control.py +8 -0
- package/dashboard/prompt_optimizer.py +7 -0
- package/dashboard/server.py +577 -22
- package/dashboard/static/trust.html +1 -1
- package/docs/ARCHITECTURE-OVERVIEW.md +207 -0
- package/docs/AUTONOMI-ECOSYSTEM.md +107 -0
- package/docs/INSTALLATION.md +19 -2
- package/docs/MODEL-EQUIVALENCE-HARNESS-PLAN.md +70 -0
- package/docs/PLANS-INDEX.md +33 -0
- package/docs/PRIVACY.md +29 -1
- package/docs/SIGNED-RECEIPTS.md +102 -0
- package/docs/SONNET5-DEFAULT-PLAN.md +1 -1
- package/docs/V8-ACCEPTANCE-TRIAGE-2026-07-24.md +114 -0
- package/docs/V8-AGENT-SDK-PLAN.md +692 -0
- package/docs/V8-COMPLEXITY-AUDIT-2026-07-24.md +45 -0
- package/docs/V8-MAJOR-RELEASE-PLAN.md +137 -0
- package/docs/V8-OVERNIGHT-PLAN-2026-07-25.md +82 -0
- package/docs/V8-RUNTIME-TRUTH-2026-07-25.md +232 -0
- package/docs/V8-SDK-RESEARCH-RAW.md +129 -0
- package/docs/alternative-installations.md +4 -4
- package/loki-ts/dist/loki.js +674 -285
- package/loki-ts/package.json +2 -0
- package/mcp/__init__.py +1 -1
- package/package.json +7 -6
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/providers/claude.sh +75 -0
- package/providers/codex.sh +85 -13
- package/references/sdk-mode.md +106 -0
- package/skills/model-selection.md +1 -1
- package/skills/quality-gates.md +22 -0
package/loki-ts/package.json
CHANGED
package/mcp/__init__.py
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "loki-mode",
|
|
3
3
|
"mcpName": "io.github.asklokesh/loki-mode",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "8.0.0",
|
|
5
5
|
"description": "Loki Mode by Autonomi. Autonomous spec-to-product system: takes a PRD, GitHub issue, OpenAPI/JSON/YAML, or one-line brief to a deployed app via the RARV-C closure loop with 8 quality gates. Provider-agnostic (Claude Code, OpenAI Codex, Cline, Aider).",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"agent",
|
|
@@ -126,10 +126,11 @@
|
|
|
126
126
|
"linux"
|
|
127
127
|
],
|
|
128
128
|
"optionalDependencies": {
|
|
129
|
-
"@
|
|
130
|
-
"@opentelemetry/
|
|
131
|
-
"@opentelemetry/
|
|
132
|
-
"@opentelemetry/
|
|
129
|
+
"@anthropic-ai/claude-agent-sdk": "0.3.208",
|
|
130
|
+
"@opentelemetry/api": "^1.9.1",
|
|
131
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.221.0",
|
|
132
|
+
"@opentelemetry/sdk-trace-base": "^2.10.0",
|
|
133
|
+
"@opentelemetry/sdk-trace-node": "^2.10.0"
|
|
133
134
|
},
|
|
134
135
|
"overrides": {
|
|
135
136
|
"protobufjs": ">=8.4.2"
|
|
@@ -143,4 +144,4 @@
|
|
|
143
144
|
"dependencies": {
|
|
144
145
|
"@resvg/resvg-wasm": "^2.6.2"
|
|
145
146
|
}
|
|
146
|
-
}
|
|
147
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
|
|
3
3
|
"name": "loki-mode",
|
|
4
4
|
"displayName": "Loki Mode",
|
|
5
|
-
"version": "
|
|
5
|
+
"version": "8.0.0",
|
|
6
6
|
"description": "Autonomous spec-to-product build system with a built-in trust layer (RARV-C closure loop, 8 quality gates, completion council). Ships Loki's spec-hardening, drift-detection, and deterministic PR verification commands plus the Loki MCP server.",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Autonomi",
|
package/providers/claude.sh
CHANGED
|
@@ -281,6 +281,28 @@ Commit hygiene still applies: git checkpoints are LOCAL only. Never push or forc
|
|
|
281
281
|
|
|
282
282
|
This precedence override is narrow. It does NOT relax any safety rule. Every safety prohibition in CLAUDE.md or memory still fully binds: anything genuinely destructive or irreversible remains out of scope unless the task explicitly calls for it. This includes (not limited to) force-pushing, deleting or overwriting the user's data, dropping or truncating databases, publishing or releasing, rotating or exfiltrating secrets, touching production systems, and anything a CLAUDE.md safety rule explicitly forbids. When in doubt about whether an action is destructive, treat it as destructive and do not do it.
|
|
283
283
|
LOKI_AUTONOMY_EOF
|
|
284
|
+
|
|
285
|
+
# First-pass excellence directive (v8): front-load intelligence into
|
|
286
|
+
# iteration 1 so a single informed pass lands the COMPLETE, working solution
|
|
287
|
+
# instead of a rough draft the loop then spends iterations correcting. This
|
|
288
|
+
# is the mechanism behind "a cheap model in one pass matches a strong model":
|
|
289
|
+
# the iteration count is a proxy for how much the first pass missed, so a
|
|
290
|
+
# more directive first prompt is the lever, not more loops. Iteration-1-only
|
|
291
|
+
# (ITERATION_COUNT<=1) and gated on LOKI_FIRST_PASS_EXCELLENCE (default ON;
|
|
292
|
+
# set to 0 to disable). Grounded in the user-research directives: nail the
|
|
293
|
+
# first working preview, WIRE the backend (a form that does nothing is the #1
|
|
294
|
+
# churn), do not defer/stub, escape the AI-slop defaults.
|
|
295
|
+
if [ "${LOKI_FIRST_PASS_EXCELLENCE:-1}" != "0" ] && [ "${ITERATION_COUNT:-1}" -le 1 ] 2>/dev/null; then
|
|
296
|
+
cat <<'LOKI_FIRSTPASS_EOF'
|
|
297
|
+
|
|
298
|
+
[FIRST-PASS EXCELLENCE] Treat THIS pass as your one shot to ship a complete, working, verified solution. Do not produce a rough draft to refine later; the loop exists as a safety net, not a plan. Before you finish this iteration:
|
|
299
|
+
1. BUILD IT FULLY. Implement every requirement end to end. No stubs, no TODOs, no "coming soon", no placeholder or hardcoded/mock data where real logic belongs. If the spec implies a backend (auth, persistence, a form that submits, a list that saves), WIRE IT so it actually works and persists -- a beautiful UI whose buttons do nothing is the single most common failure, not a draft. Every list/table must trace to a real query, never an inline mock array.
|
|
300
|
+
2. SELF-VERIFY BY RUNNING, not by reading. Run the build and the tests yourself; for each acceptance criterion, DRIVE the actual path and observe the result (submit the form, then reload and confirm the record persisted; hit a protected route logged-out and confirm it is rejected). Fix what fails now, in this pass. Do not mark done on "looks right" or a self-claim -- observed behavior is the only proof.
|
|
301
|
+
3. LOCK THE ARCHITECTURE on this pass so later edits are small and additive. Decide the data model, routes, and component structure up front and build to them; never rewrite whole files later to patch a small thing (that is the doom loop that breaks working features).
|
|
302
|
+
4. DESIGN: commit to ONE named aesthetic direction up front (editorial, brutalist, luxury, retro-futuristic, soft/pastel, industrial, etc. -- chosen from the product domain) and hold it on every surface. Use real content (never lorem). AVOID the AI-slop tells that instantly read as machine-generated: NO indigo/blue-to-purple gradient (the #1 tell), NO Inter/Roboto/system-font headlines (pick a real display+body pairing), NO three-equal-rounded-cards-in-a-row skeleton, NO flat 1px gray card borders or colored left-border strips, NO untouched shadcn defaults, NO reflexive dark mode. Cap the palette at ~3 hues (60/30/10), tinted not pure #fff/#000, separate sections by whitespace then a slight background shift before any border. Aim for Linear/Stripe/Duolingo-tier taste: "this does not look AI-generated".
|
|
303
|
+
Deliver the finished, self-verified, genuinely-designed result in THIS pass. Additional iterations should be the exception, not the plan.
|
|
304
|
+
LOKI_FIRSTPASS_EOF
|
|
305
|
+
fi
|
|
284
306
|
}
|
|
285
307
|
|
|
286
308
|
# Invocation function (basic, no tier).
|
|
@@ -380,6 +402,54 @@ loki_apply_max_tier_clamp() {
|
|
|
380
402
|
printf '%s' "$model"
|
|
381
403
|
}
|
|
382
404
|
|
|
405
|
+
# Complexity-aware MODEL routing (net-new; effort routing already exists in
|
|
406
|
+
# loki_effort_for_tier). ENV VAR: LOKI_TIER_ROUTING (DEFAULT "0" = OFF = current
|
|
407
|
+
# flat resolution, zero change to stock runs). When LOKI_TIER_ROUTING=1 the
|
|
408
|
+
# resolved model is nudged by the auto-detected project complexity signal
|
|
409
|
+
# (LOKI_COMPLEXITY: simple|standard|complex):
|
|
410
|
+
# complex + planning -> opus (deeper reasoning for hard architecture)
|
|
411
|
+
# simple + fast -> haiku ONLY when LOKI_ALLOW_HAIKU=true (support gate);
|
|
412
|
+
# else stay put (never route to an unavailable model)
|
|
413
|
+
# standard, or the development/ACT tier -> UNCHANGED.
|
|
414
|
+
# HARD GUARD: the development/ACT tier is NEVER routed below sonnet regardless of
|
|
415
|
+
# complexity (implementation stays >= sonnet). "explicit override wins": we skip
|
|
416
|
+
# the nudge whenever the operator pinned that tier via LOKI_CLAUDE_MODEL_PLANNING
|
|
417
|
+
# / LOKI_MODEL_PLANNING (or the _FAST pair), so a deliberate pin is never
|
|
418
|
+
# overridden. Byte-mirrored by loki_tier_route_model in loki-ts claude_flags.ts.
|
|
419
|
+
loki_tier_route_model() {
|
|
420
|
+
local tier="$1"
|
|
421
|
+
local model="$2"
|
|
422
|
+
# Default OFF: only the explicit "1" opt-in engages routing.
|
|
423
|
+
[ "${LOKI_TIER_ROUTING:-0}" = "1" ] || { printf '%s' "$model"; return; }
|
|
424
|
+
local complexity="${LOKI_COMPLEXITY:-standard}"
|
|
425
|
+
case "$tier" in
|
|
426
|
+
planning)
|
|
427
|
+
# Bump to opus for complex work, but only when the operator did NOT
|
|
428
|
+
# pin planning explicitly (an explicit override always wins, even if
|
|
429
|
+
# they pinned it back to the flat default).
|
|
430
|
+
if [ "$complexity" = "complex" ] \
|
|
431
|
+
&& [ -z "${LOKI_CLAUDE_MODEL_PLANNING:-}" ] \
|
|
432
|
+
&& [ -z "${LOKI_MODEL_PLANNING:-}" ]; then
|
|
433
|
+
model="opus"
|
|
434
|
+
fi
|
|
435
|
+
;;
|
|
436
|
+
fast)
|
|
437
|
+
# Drop to haiku for trivial verify work, gated on haiku availability
|
|
438
|
+
# and on the operator not having pinned fast explicitly.
|
|
439
|
+
if [ "$complexity" = "simple" ] \
|
|
440
|
+
&& [ "${LOKI_ALLOW_HAIKU:-false}" = "true" ] \
|
|
441
|
+
&& [ -z "${LOKI_CLAUDE_MODEL_FAST:-}" ] \
|
|
442
|
+
&& [ -z "${LOKI_MODEL_FAST:-}" ]; then
|
|
443
|
+
model="haiku"
|
|
444
|
+
fi
|
|
445
|
+
;;
|
|
446
|
+
# development/ACT and every other tier: unchanged. HARD GUARD -- never
|
|
447
|
+
# route implementation below sonnet, so this arm deliberately does nothing.
|
|
448
|
+
*) ;;
|
|
449
|
+
esac
|
|
450
|
+
printf '%s' "$model"
|
|
451
|
+
}
|
|
452
|
+
|
|
383
453
|
# Dynamic model resolution (v6.0.0)
|
|
384
454
|
# Resolves a capability tier to a concrete model name at runtime.
|
|
385
455
|
# Respects LOKI_MAX_TIER to cap cost via loki_apply_max_tier_clamp. NOTE the
|
|
@@ -432,6 +502,11 @@ resolve_model_for_tier() {
|
|
|
432
502
|
# `fable)` arm above. Keeping the decision in run.sh is the only place that
|
|
433
503
|
# has ITERATION_COUNT, so the scoping is honest.
|
|
434
504
|
|
|
505
|
+
# Complexity-aware MODEL routing (opt-in). Applied AFTER base resolution and
|
|
506
|
+
# BEFORE the max-tier clamp, so the ceiling still bounds any bump-up. Byte-
|
|
507
|
+
# mirrored by loki_tier_route_model in loki-ts claude_flags.ts.
|
|
508
|
+
model="$(loki_tier_route_model "$tier" "$model")"
|
|
509
|
+
|
|
435
510
|
# Apply the shared LOKI_MAX_TIER ceiling (same clamp the run.sh override path
|
|
436
511
|
# uses, so the cost ceiling is enforced byte-identically on both paths).
|
|
437
512
|
model="$(loki_apply_max_tier_clamp "$model" "$tier")"
|
package/providers/codex.sh
CHANGED
|
@@ -45,16 +45,66 @@ PROVIDER_SKILL_DIR="${HOME}/.agents/skills"
|
|
|
45
45
|
PROVIDER_SKILL_FORMAT="markdown" # Codex v0.98+ loads skills from ~/.agents/skills
|
|
46
46
|
|
|
47
47
|
# Capability Flags
|
|
48
|
+
#
|
|
49
|
+
# SUBAGENTS / TASK_TOOL stay false: Codex has no equivalent of Claude Code's
|
|
50
|
+
# in-session subagent dispatch. These two are reporting-only in this codebase
|
|
51
|
+
# (loader.sh display + the degraded-mode summary); nothing branches on them.
|
|
48
52
|
PROVIDER_HAS_SUBAGENTS=false
|
|
49
|
-
PROVIDER_HAS_PARALLEL=false
|
|
50
53
|
PROVIDER_HAS_TASK_TOOL=false
|
|
51
54
|
PROVIDER_HAS_MCP=true
|
|
52
|
-
|
|
55
|
+
#
|
|
56
|
+
# PARALLEL: enabled 2026-07-27 after MEASURING it, not assuming it.
|
|
57
|
+
#
|
|
58
|
+
# The v0.98-era `false` was an untested assumption. On codex-cli 0.144.6 two
|
|
59
|
+
# concurrent `codex exec` runs in separate git worktrees both completed, exit 0,
|
|
60
|
+
# zero rate-limit errors. This flag gates exactly one behavior -- worktree
|
|
61
|
+
# parallel sessions (run.sh:4832 spawn guard, run.sh:23473 mode downgrade) --
|
|
62
|
+
# and that primitive is only "run the non-interactive CLI in N directories at
|
|
63
|
+
# once". It needs no subagents and no Task tool, which is why those two stay
|
|
64
|
+
# false above while this one does not.
|
|
65
|
+
#
|
|
66
|
+
# Enabling it required making the user-facing text honest first, because
|
|
67
|
+
# "degraded" was being reported as if it always implied "sequential":
|
|
68
|
+
# run.sh:23461 now enumerates the capabilities actually missing (read from
|
|
69
|
+
# these flags) instead of hardcoding "Parallel agents and Task tool", and the
|
|
70
|
+
# live-output banner only claims "Sequential execution only" when
|
|
71
|
+
# PROVIDER_HAS_PARALLEL is genuinely false. PROVIDER_DEGRADED itself is
|
|
72
|
+
# deliberately UNTOUCHED: its other consumers (run.sh:20340 workflow analysis,
|
|
73
|
+
# done-recognition.sh:167) are claude-only guards and one is parity-locked with
|
|
74
|
+
# the Bun route, so widening its meaning would ripple into prompt construction
|
|
75
|
+
# for no gain here.
|
|
76
|
+
#
|
|
77
|
+
# MAX_PARALLEL is 2, not the Claude value. Two is what was actually verified,
|
|
78
|
+
# and Codex's free ChatGPT tier -- the audience this matters for, since Codex is
|
|
79
|
+
# the only zero-cost on-ramp in the category -- is rate-limited well before
|
|
80
|
+
# process concurrency becomes the ceiling. Raise it only with evidence at the
|
|
81
|
+
# higher number.
|
|
82
|
+
PROVIDER_HAS_PARALLEL=true
|
|
83
|
+
PROVIDER_MAX_PARALLEL=2
|
|
53
84
|
|
|
54
85
|
# Model Configuration
|
|
55
|
-
# Codex uses single model with effort parameter
|
|
56
|
-
#
|
|
57
|
-
|
|
86
|
+
# Codex uses a single model with an effort parameter.
|
|
87
|
+
#
|
|
88
|
+
# DEFAULT IS EMPTY ON PURPOSE (2026-07-26). Pinning a model name here broke
|
|
89
|
+
# Codex outright for ChatGPT-account users -- the account tier that matters
|
|
90
|
+
# most, since Codex ships free with every ChatGPT plan and is the only
|
|
91
|
+
# zero-cost on-ramp in the category. Verified against codex-cli 0.144.6:
|
|
92
|
+
#
|
|
93
|
+
# codex exec --model gpt-5.3-codex "..."
|
|
94
|
+
# -> 400 invalid_request_error: "The 'gpt-5.3-codex' model is not
|
|
95
|
+
# supported when using Codex with a ChatGPT account."
|
|
96
|
+
# codex exec "..." (no --model)
|
|
97
|
+
# -> works, 22255 tokens, correct output
|
|
98
|
+
#
|
|
99
|
+
# The old pin ("official model name for Codex CLI v0.98+") was written against
|
|
100
|
+
# v0.98 and never re-verified; the installed CLI is 0.144.6. Replacing it with
|
|
101
|
+
# another hardcoded name would repeat the same mistake with a fresher string --
|
|
102
|
+
# valid model names differ per account tier and change with upstream releases,
|
|
103
|
+
# so THIS FILE CANNOT KNOW THEM. Codex already resolves an account-appropriate
|
|
104
|
+
# default (honoring ~/.codex/config.toml), so the correct behavior is to say
|
|
105
|
+
# nothing and let it choose. An operator who wants a specific model still sets
|
|
106
|
+
# LOKI_CODEX_MODEL or LOKI_MODEL_*, which are passed through below.
|
|
107
|
+
CODEX_DEFAULT_MODEL=""
|
|
58
108
|
|
|
59
109
|
# Known valid Codex model prefixes for validation (BUG-PROV-002 fix)
|
|
60
110
|
# Generic LOKI_MODEL_* may contain Claude model aliases (e.g. "opus", "sonnet",
|
|
@@ -69,7 +119,10 @@ _codex_validate_model() {
|
|
|
69
119
|
return 0
|
|
70
120
|
fi
|
|
71
121
|
done
|
|
72
|
-
# Not a valid Codex model name
|
|
122
|
+
# Not a valid Codex model name (e.g. a Claude alias leaking in via the
|
|
123
|
+
# generic LOKI_MODEL_*) -- fall back to the default, which is now EMPTY,
|
|
124
|
+
# i.e. "pass no --model and let Codex pick". That is deliberately the same
|
|
125
|
+
# safe outcome as an unset model rather than a guessed name.
|
|
73
126
|
echo "$CODEX_DEFAULT_MODEL"
|
|
74
127
|
}
|
|
75
128
|
|
|
@@ -125,16 +178,28 @@ provider_version() {
|
|
|
125
178
|
# Invocation function
|
|
126
179
|
# Note: Codex uses positional prompt, not -p flag
|
|
127
180
|
# Note: Reasoning effort is configured via environment or config, not CLI flag
|
|
128
|
-
# v7.x
|
|
129
|
-
#
|
|
130
|
-
#
|
|
131
|
-
#
|
|
132
|
-
#
|
|
181
|
+
# v7.x pinned the resolved model explicitly via -m/--model so the run.sh cost
|
|
182
|
+
# table matched what actually ran. That is still the behavior WHEN A MODEL IS
|
|
183
|
+
# SET -- but the flag is now OMITTED when the resolved model is empty, because
|
|
184
|
+
# a hardcoded name broke ChatGPT-account users outright (see CODEX_DEFAULT_MODEL
|
|
185
|
+
# above). Omitting it lets Codex resolve an account-appropriate default; the
|
|
186
|
+
# trade-off is that the cost table falls back to its generic estimate, which is
|
|
187
|
+
# strictly better than a run that cannot start at all.
|
|
188
|
+
_codex_model_flag() {
|
|
189
|
+
# Echo nothing when no model is resolved, so the caller's array stays empty.
|
|
190
|
+
[ -n "${1:-}" ] && printf '%s\n%s\n' "--model" "$1"
|
|
191
|
+
return 0
|
|
192
|
+
}
|
|
193
|
+
|
|
133
194
|
provider_invoke() {
|
|
134
195
|
local prompt="$1"
|
|
135
196
|
shift
|
|
197
|
+
local model_flag=()
|
|
198
|
+
while IFS= read -r _mf; do
|
|
199
|
+
[ -n "$_mf" ] && model_flag+=("$_mf")
|
|
200
|
+
done < <(_codex_model_flag "$PROVIDER_MODEL_DEVELOPMENT")
|
|
136
201
|
codex exec --sandbox workspace-write --skip-git-repo-check \
|
|
137
|
-
|
|
202
|
+
"${model_flag[@]+"${model_flag[@]}"}" \
|
|
138
203
|
"$prompt" "$@"
|
|
139
204
|
}
|
|
140
205
|
|
|
@@ -254,12 +319,19 @@ provider_invoke_with_tier() {
|
|
|
254
319
|
# array is empty, and a bare "${arr[@]}" under `set -u` aborts with
|
|
255
320
|
# "unbound variable" on bash 3.2 (stock macOS /bin/bash). ${arr[@]+...}
|
|
256
321
|
# expands to nothing when empty and preserves spaced elements otherwise.
|
|
322
|
+
# Same conditional as provider_invoke: omit --model entirely when none
|
|
323
|
+
# resolved, rather than passing an empty string (which codex rejects).
|
|
324
|
+
local model_flag=()
|
|
325
|
+
while IFS= read -r _mf; do
|
|
326
|
+
[ -n "$_mf" ] && model_flag+=("$_mf")
|
|
327
|
+
done < <(_codex_model_flag "$model")
|
|
328
|
+
|
|
257
329
|
codex \
|
|
258
330
|
"${pre_exec_flags[@]+"${pre_exec_flags[@]}"}" \
|
|
259
331
|
exec \
|
|
260
332
|
--sandbox workspace-write \
|
|
261
333
|
--skip-git-repo-check \
|
|
262
|
-
|
|
334
|
+
"${model_flag[@]+"${model_flag[@]}"}" \
|
|
263
335
|
"${extra_flags[@]+"${extra_flags[@]}"}" \
|
|
264
336
|
"$prompt" "$@"
|
|
265
337
|
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# SDK Mode: one-switch Anthropic SDK activation (v8.1)
|
|
2
|
+
|
|
3
|
+
Loki's engine can run its model calls through the Anthropic SDKs instead of
|
|
4
|
+
spawning the `claude` CLI. This is the enterprise / SaaS deploy path: a container
|
|
5
|
+
or worker runs with just `ANTHROPIC_API_KEY`, no interactive `claude` login and
|
|
6
|
+
no user-managed CLI version drift.
|
|
7
|
+
|
|
8
|
+
Everything here is OPT-IN and DEFAULT-OFF. With nothing set, the engine is
|
|
9
|
+
byte-identical to the bash `claude` route.
|
|
10
|
+
|
|
11
|
+
## The one knob: `LOKI_SDK_MODE`
|
|
12
|
+
|
|
13
|
+
| Value | What turns on | Use when |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| `off` (default) | nothing (byte-identical to v7/v8 bash route) | default |
|
|
16
|
+
| `judges` | the 7 one-shot JUDGE/TEXT sites (done-recognition, council-v2, code-review, completion-council VOTE, voter-agents, grill, prd-enrich). The RARV loop stays OFF. | recommended scale tier: no `claude` binary needed for judging, loop unchanged |
|
|
17
|
+
| `full` | all of `judges` PLUS the RARV main loop (`LOKI_SDK_LOOP`) | pre-flight only this release; requires `bun` (the loop runs on the Bun runner). The loop default-flip is a later release |
|
|
18
|
+
|
|
19
|
+
Alias: `LOKI_SDK=1` == `judges`; `LOKI_SDK=full` == `full`.
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# Scale tier: judges on the SDK, loop on the existing route.
|
|
23
|
+
LOKI_SDK_MODE=judges loki start ./prd.md
|
|
24
|
+
|
|
25
|
+
# Pre-flight the full SDK engine (needs bun).
|
|
26
|
+
LOKI_SDK_MODE=full loki start ./prd.md
|
|
27
|
+
|
|
28
|
+
# See what one switch turned on.
|
|
29
|
+
LOKI_SDK_MODE_DEBUG=1 LOKI_SDK_MODE=judges loki start ./prd.md
|
|
30
|
+
# stderr: loki: SDK mode=judges -> judges on, loop=0
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Rollback: `LOKI_LEGACY_BASH=1`
|
|
34
|
+
|
|
35
|
+
Forces the legacy bash `claude` route for every command, overriding any
|
|
36
|
+
`LOKI_SDK_MODE` / `LOKI_SDK_*` setting. Honored at the `bin/loki` shim AND inside
|
|
37
|
+
the Bun provider resolver, so it wins even if the Bun route is reached another
|
|
38
|
+
way. This is the always-available escape hatch; today the loop is default-off, so
|
|
39
|
+
it is a no-op for the loop and only matters once the loop opts on.
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
LOKI_LEGACY_BASH=1 loki start ./prd.md # legacy bash claude route, SDK off
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Advanced: the per-site flags (rollback appendix)
|
|
46
|
+
|
|
47
|
+
`LOKI_SDK_MODE` is a convenience that sets the default for eight per-site flags.
|
|
48
|
+
Set any of these EXPLICITLY to override the mode for one site (an explicit value,
|
|
49
|
+
even `=0`, always wins over the mode):
|
|
50
|
+
|
|
51
|
+
| Flag | Site |
|
|
52
|
+
|---|---|
|
|
53
|
+
| `LOKI_SDK_DONE_RECOG` | done-recognition judge |
|
|
54
|
+
| `LOKI_SDK_COUNCIL_V2` | council-v2 judge |
|
|
55
|
+
| `LOKI_SDK_CODE_REVIEW` | code-review reviewer |
|
|
56
|
+
| `LOKI_SDK_COUNCIL_VOTE` | completion-council member + contrarian VOTE |
|
|
57
|
+
| `LOKI_SDK_VOTER_AGENTS` | voter-agents council |
|
|
58
|
+
| `LOKI_SDK_GRILL` | grill (free-form text) |
|
|
59
|
+
| `LOKI_SDK_PRD_ENRICH` | prd-enrich (free-form text) |
|
|
60
|
+
| `LOKI_SDK_LOOP` | the RARV main loop (Bun runner) |
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Everything on the SDK EXCEPT code review (keep that on the bash claude route):
|
|
64
|
+
LOKI_SDK_MODE=full LOKI_SDK_CODE_REVIEW=0 loki start ./prd.md
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Guarantees
|
|
68
|
+
|
|
69
|
+
- **Fail-closed.** Any SDK miss (no key, transport error, refusal, malformed
|
|
70
|
+
output, timeout, empty) falls through to the existing `claude` / deterministic
|
|
71
|
+
path. A quality gate or completion council can never fake-PASS or fake-APPROVE
|
|
72
|
+
via an SDK path.
|
|
73
|
+
- **Parity.** The bash and Bun/TypeScript routes resolve the same mode -> flags
|
|
74
|
+
table (bound to a shared test fixture), so the two routes never diverge.
|
|
75
|
+
- **Requires a key.** The SDK route needs `ANTHROPIC_API_KEY` (or a gateway /
|
|
76
|
+
Bedrock / Vertex base URL). Without it, every SDK site fail-closes to the bash
|
|
77
|
+
route. `full` additionally requires `bun` for the loop; on a bun-less host every
|
|
78
|
+
mode degrades to the legacy route.
|
|
79
|
+
|
|
80
|
+
Implementation: `autonomy/lib/sdk-mode.sh` (bash), `loki-ts/src/runner/sdk_mode.ts`
|
|
81
|
+
(TypeScript). Shared parity fixture: `loki-ts/test/fixtures/sdk-mode-table.json`.
|
|
82
|
+
|
|
83
|
+
## Dev-only OAuth auth (`LOKI_SDK_OAUTH_DEV`)
|
|
84
|
+
|
|
85
|
+
For local development you can drive the SDK JUDGE path with your existing `claude`
|
|
86
|
+
login instead of a standalone `ANTHROPIC_API_KEY`. Set `LOKI_SDK_OAUTH_DEV=1` with
|
|
87
|
+
NO `ANTHROPIC_API_KEY` present: the raw-SDK client (`sdk_invoker.ts`) reads the
|
|
88
|
+
freshest claude.ai OAuth access token (macOS Keychain `Claude Code-credentials`
|
|
89
|
+
first, then `${CLAUDE_CONFIG_DIR:-~/.claude}/.credentials.json`) and calls the
|
|
90
|
+
Messages API with a Bearer token plus the required `anthropic-beta:
|
|
91
|
+
oauth-2025-04-20` header.
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
# judges on the SDK, authenticated by your `claude` login (no API key):
|
|
95
|
+
LOKI_SDK_OAUTH_DEV=1 LOKI_SDK_MODE=judges loki start ./prd.md
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
DEV ONLY, and deliberately gated so it can never affect production:
|
|
99
|
+
- Activates only when the flag is set AND `ANTHROPIC_API_KEY` is ABSENT (an API
|
|
100
|
+
key always wins).
|
|
101
|
+
- The token expires ~hourly and is NOT refreshed here; when it lapses mid-run the
|
|
102
|
+
SDK site fail-closes to the deterministic/bash fallback, same as a missing key.
|
|
103
|
+
- Only wired for the JUDGE path (`sdk_invoker.ts`), not the agentic RARV loop.
|
|
104
|
+
|
|
105
|
+
Implementation: `loki-ts/src/runner/oauth_dev.ts`. Gate tests:
|
|
106
|
+
`loki-ts/test/runner/oauth_dev.test.ts`.
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
Since v6.81.0, the main RARV loop uses **one pinned model per session** instead of rotating models per RARV phase. This eliminates per-iteration tier churn and keeps the main loop behavior predictable.
|
|
6
6
|
|
|
7
7
|
- Controlled by `LOKI_SESSION_MODEL` (default: `sonnet`).
|
|
8
|
-
- Accepted values: `opus`, `sonnet`, `haiku`, or a raw tier name (`planning`, `development`, `fast`). The value names a **tier**, not a fixed model: it is mapped to an abstract tier (opus -> planning, sonnet -> development, haiku -> fast) which is then resolved to a concrete model through the provider config (`PROVIDER_MODEL_PLANNING/DEVELOPMENT/FAST`). On stock config the default `sonnet` pin = the **development** tier = `PROVIDER_MODEL_DEVELOPMENT` = **
|
|
8
|
+
- Accepted values: `opus`, `sonnet`, `haiku`, or a raw tier name (`planning`, `development`, `fast`). The value names a **tier**, not a fixed model: it is mapped to an abstract tier (opus -> planning, sonnet -> development, haiku -> fast) which is then resolved to a concrete model through the provider config (`PROVIDER_MODEL_PLANNING/DEVELOPMENT/FAST`). On stock config the default `sonnet` pin = the **development** tier = `PROVIDER_MODEL_DEVELOPMENT` = **sonnet** (since v7.104.0, `CLAUDE_DEFAULT_DEVELOPMENT=sonnet`; planning and fast also default to sonnet on the stock path). This is why `loki plan` quotes Sonnet on the stock default path: the quote names the dispatched model, and every tier resolves to the same sonnet model unless the provider config overrides a tier. A mid-flight `.loki/state/model-override` is different: that alias is fed straight to `--model` (a `sonnet` override dispatches sonnet, no tier route).
|
|
9
9
|
- `get_rarv_tier()` is retained and still used for subagent Task-tool dispatches (planning vs implementation vs fast work), not for the main loop.
|
|
10
10
|
|
|
11
11
|
**Rollback (legacy RARV tier rotation in the main loop):**
|
package/skills/quality-gates.md
CHANGED
|
@@ -264,6 +264,28 @@ LOKI_REVIEW_INCONCLUSIVE_BLOCK=1 # default 1. Treat a code-review round that
|
|
|
264
264
|
# or zero real verdicts) as a BLOCK instead
|
|
265
265
|
# of a silent pass. Set 0 to disable.
|
|
266
266
|
|
|
267
|
+
LOKI_REVIEW_UNAVAILABLE_BLOCK=1 # default 1 (blocks under LOKI_HARD_GATES).
|
|
268
|
+
# When NO reviewer can run at all (no claude
|
|
269
|
+
# binary on PATH AND no reachable SDK judge),
|
|
270
|
+
# code_review would otherwise pass with ZERO
|
|
271
|
+
# review -- a fake-PASS that makes the blind
|
|
272
|
+
# 3-reviewer moat a no-op. Blocks instead. Set
|
|
273
|
+
# 0 for an honest degraded pass (a run that
|
|
274
|
+
# deliberately has no reviewer). The raw-SDK
|
|
275
|
+
# reviewer path (LOKI_SDK_CODE_REVIEW=1 + a key)
|
|
276
|
+
# counts as available, so this only fires with
|
|
277
|
+
# no reviewer at all.
|
|
278
|
+
|
|
279
|
+
LOKI_GATE_TEST_COVERAGE_BLOCK=0 # default 0 (advisory, bash-parity). By default
|
|
280
|
+
# a failing test suite is surfaced and the
|
|
281
|
+
# completion-council evidence gate is the
|
|
282
|
+
# backstop that refuses "done" on red tests.
|
|
283
|
+
# Set 1 to ALSO refuse completion at the runner
|
|
284
|
+
# layer deterministically (fail-closed even if
|
|
285
|
+
# a heuristic council with no evidence gate is
|
|
286
|
+
# in play). Same opt-in shape as the
|
|
287
|
+
# semantic_tests / invariants _BLOCK toggles.
|
|
288
|
+
|
|
267
289
|
LOKI_COMPLETION_TEST_CAPTURE=1 # default 1. The verified-completion gate
|
|
268
290
|
# captures fresh test evidence when
|
|
269
291
|
# test-results.json is absent, instead of
|