loki-mode 7.26.0 → 7.28.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 +15 -13
- package/SKILL.md +11 -2
- package/VERSION +1 -1
- package/autonomy/completion-council.sh +310 -6
- package/autonomy/context-tracker.py +32 -7
- package/autonomy/grill.sh +321 -0
- package/autonomy/lib/trust_metrics.py +636 -0
- package/autonomy/loki +142 -0
- package/autonomy/prd-checklist.sh +248 -14
- package/autonomy/run.sh +283 -32
- package/autonomy/spec.sh +646 -0
- package/autonomy/verify.sh +1130 -0
- package/dashboard/__init__.py +1 -1
- package/dashboard/static/index.html +1 -1
- package/docs/COMPARISON.md +9 -9
- package/docs/COMPETITIVE-ANALYSIS.md +18 -37
- package/docs/INSTALLATION.md +1 -1
- package/docs/auto-claude-comparison.md +9 -6
- package/docs/certification/01-core-concepts/lesson.md +3 -3
- package/docs/competitive/emergence-others-analysis.md +1 -1
- package/docs/competitive/replit-lovable-analysis.md +1 -1
- package/docs/cursor-comparison.md +1 -1
- package/docs/prd-purple-lab-platform.md +1 -1
- package/docs/show-hn-post.md +2 -2
- package/loki-ts/dist/loki.js +2 -2
- package/mcp/__init__.py +1 -1
- package/package.json +2 -1
- package/providers/codex.sh +3 -2
- package/references/agent-types.md +9 -9
- package/references/agents.md +8 -8
- package/references/business-ops.md +1 -1
- package/references/competitive-analysis.md +1 -1
- package/skills/agents.md +3 -3
- package/skills/providers.md +3 -3
- package/skills/quality-gates.md +46 -0
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# autonomy/grill.sh - Loki spec interrogation (loki grill).
|
|
3
|
+
#
|
|
4
|
+
# Net-new capability (internal/SDD-PANEL-A.md ranks it HIGHEST: no Claude Code
|
|
5
|
+
# equivalent, no Loki equivalent). It exposes the Devil's-Advocate /
|
|
6
|
+
# anti-sycophancy posture that today fires only INSIDE the build loop
|
|
7
|
+
# (run.sh:7807) as a standalone PRE-build interrogation of a spec.
|
|
8
|
+
#
|
|
9
|
+
# What it does: invokes the provider ONCE (claude -p, the same single-shot
|
|
10
|
+
# pattern used for in-loop adversarial review and the haiku USAGE regen at
|
|
11
|
+
# run.sh:9832) with a Devil's-Advocate prompt that produces the 10-15 hardest
|
|
12
|
+
# questions exposing ambiguities, missing acceptance criteria, unstated
|
|
13
|
+
# assumptions, and security/scale blind spots. Output is a structured markdown
|
|
14
|
+
# report at .loki/grill/report.md. With --apply it appends a "Grill findings"
|
|
15
|
+
# section to the spec itself.
|
|
16
|
+
#
|
|
17
|
+
# Honest about provider dependency: requires the provider CLI; clean error when
|
|
18
|
+
# absent (no fabricated questions, no silent success).
|
|
19
|
+
#
|
|
20
|
+
# Spec source resolution (first match wins, same as loki spec):
|
|
21
|
+
# 1. explicit path argument
|
|
22
|
+
# 2. prd.md
|
|
23
|
+
# 3. .loki/generated-prd.md
|
|
24
|
+
# 4. PRD.md
|
|
25
|
+
# 5. docs/prd.md
|
|
26
|
+
#
|
|
27
|
+
# Exit codes:
|
|
28
|
+
# 0 report written
|
|
29
|
+
# 2 usage / spec-not-found error
|
|
30
|
+
# 3 provider unavailable or interrogation failed (never silent)
|
|
31
|
+
|
|
32
|
+
set -uo pipefail
|
|
33
|
+
|
|
34
|
+
GRILL_EXIT_OK=0
|
|
35
|
+
GRILL_EXIT_USAGE=2
|
|
36
|
+
GRILL_EXIT_ERROR=3
|
|
37
|
+
|
|
38
|
+
GRILL_DIR_DEFAULT=".loki/grill"
|
|
39
|
+
GRILL_REPORT_NAME="report.md"
|
|
40
|
+
|
|
41
|
+
_grill_log() { printf '[grill] %s\n' "$*" >&2; }
|
|
42
|
+
_grill_err() { printf '[grill][error] %s\n' "$*" >&2; }
|
|
43
|
+
|
|
44
|
+
# ---------------------------------------------------------------------------
|
|
45
|
+
# Resolve the spec source path. Echoes the path on success, empty on failure.
|
|
46
|
+
# Default order favors a hand-written prd.md over a generated one for grilling,
|
|
47
|
+
# since grilling is a pre-build hardening step on the human's intent.
|
|
48
|
+
# ---------------------------------------------------------------------------
|
|
49
|
+
grill_resolve_source() {
|
|
50
|
+
local explicit="${1:-}"
|
|
51
|
+
if [ -n "$explicit" ]; then
|
|
52
|
+
if [ -f "$explicit" ]; then
|
|
53
|
+
printf '%s\n' "$explicit"
|
|
54
|
+
return 0
|
|
55
|
+
fi
|
|
56
|
+
return 1
|
|
57
|
+
fi
|
|
58
|
+
local candidate
|
|
59
|
+
for candidate in \
|
|
60
|
+
"prd.md" \
|
|
61
|
+
".loki/generated-prd.md" \
|
|
62
|
+
"PRD.md" \
|
|
63
|
+
"docs/prd.md"; do
|
|
64
|
+
if [ -f "$candidate" ]; then
|
|
65
|
+
printf '%s\n' "$candidate"
|
|
66
|
+
return 0
|
|
67
|
+
fi
|
|
68
|
+
done
|
|
69
|
+
return 1
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
# ---------------------------------------------------------------------------
|
|
73
|
+
# Build the Devil's-Advocate interrogation prompt for a given spec body.
|
|
74
|
+
# ---------------------------------------------------------------------------
|
|
75
|
+
grill_build_prompt() {
|
|
76
|
+
local spec_path="$1"
|
|
77
|
+
local spec_body="$2"
|
|
78
|
+
cat <<EOF
|
|
79
|
+
You are a Devil's Advocate spec reviewer. Your job is to interrogate the
|
|
80
|
+
following specification and surface its weaknesses BEFORE any code is written.
|
|
81
|
+
Do not praise it. Do not summarize it. Do not propose an implementation.
|
|
82
|
+
|
|
83
|
+
Produce the 10 to 15 HARDEST questions that expose:
|
|
84
|
+
- ambiguities and underspecified behavior
|
|
85
|
+
- missing or untestable acceptance criteria
|
|
86
|
+
- unstated assumptions and implicit requirements
|
|
87
|
+
- security blind spots (authn/authz, input validation, secrets, data exposure)
|
|
88
|
+
- scale and reliability blind spots (concurrency, failure modes, limits)
|
|
89
|
+
- edge cases the spec does not address
|
|
90
|
+
|
|
91
|
+
Output STRICT markdown in exactly this shape and nothing else:
|
|
92
|
+
|
|
93
|
+
## Grill findings
|
|
94
|
+
|
|
95
|
+
### Ambiguities and missing acceptance criteria
|
|
96
|
+
1. <hard question>
|
|
97
|
+
2. <hard question>
|
|
98
|
+
|
|
99
|
+
### Unstated assumptions
|
|
100
|
+
1. <hard question>
|
|
101
|
+
|
|
102
|
+
### Security blind spots
|
|
103
|
+
1. <hard question>
|
|
104
|
+
|
|
105
|
+
### Scale and reliability blind spots
|
|
106
|
+
1. <hard question>
|
|
107
|
+
|
|
108
|
+
Each question must be specific to THIS spec (quote or reference the relevant
|
|
109
|
+
part), answerable, and uncomfortable. Total questions across all sections: 10
|
|
110
|
+
to 15. If a category has no real issue, write "None identified." under it
|
|
111
|
+
rather than padding.
|
|
112
|
+
|
|
113
|
+
=== SPEC: $spec_path ===
|
|
114
|
+
$spec_body
|
|
115
|
+
=== END SPEC ===
|
|
116
|
+
EOF
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
# ---------------------------------------------------------------------------
|
|
120
|
+
# Invoke the provider once and capture the interrogation report.
|
|
121
|
+
# Echoes the report markdown on success; returns nonzero on failure.
|
|
122
|
+
# ---------------------------------------------------------------------------
|
|
123
|
+
# LOW-6: validate the provider (the same checks that produce rc=3) WITHOUT
|
|
124
|
+
# invoking it, so grill_main can fail cleanly BEFORE logging "interrogating ...
|
|
125
|
+
# via <provider>". Returns 0 if the provider is supported and its CLI is present;
|
|
126
|
+
# otherwise prints the same error grill_invoke_provider would and returns rc=3.
|
|
127
|
+
grill_check_provider() {
|
|
128
|
+
local provider="${LOKI_PROVIDER:-claude}"
|
|
129
|
+
case "$provider" in
|
|
130
|
+
claude)
|
|
131
|
+
if ! command -v claude >/dev/null 2>&1; then
|
|
132
|
+
_grill_err "Claude Code CLI not found. Install: https://docs.anthropic.com/en/docs/claude-code"
|
|
133
|
+
return $GRILL_EXIT_ERROR
|
|
134
|
+
fi
|
|
135
|
+
;;
|
|
136
|
+
codex)
|
|
137
|
+
if ! command -v codex >/dev/null 2>&1; then
|
|
138
|
+
_grill_err "Codex CLI not found."
|
|
139
|
+
return $GRILL_EXIT_ERROR
|
|
140
|
+
fi
|
|
141
|
+
;;
|
|
142
|
+
*)
|
|
143
|
+
_grill_err "grill currently supports the claude and codex providers (got: $provider)"
|
|
144
|
+
return $GRILL_EXIT_ERROR
|
|
145
|
+
;;
|
|
146
|
+
esac
|
|
147
|
+
return 0
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
grill_invoke_provider() {
|
|
151
|
+
local prompt="$1"
|
|
152
|
+
local provider="${LOKI_PROVIDER:-claude}"
|
|
153
|
+
|
|
154
|
+
case "$provider" in
|
|
155
|
+
claude)
|
|
156
|
+
if ! command -v claude >/dev/null 2>&1; then
|
|
157
|
+
_grill_err "Claude Code CLI not found. Install: https://docs.anthropic.com/en/docs/claude-code"
|
|
158
|
+
return $GRILL_EXIT_ERROR
|
|
159
|
+
fi
|
|
160
|
+
local out
|
|
161
|
+
# Single-shot, non-interactive. Same pattern as the in-loop
|
|
162
|
+
# adversarial reviewer (run.sh:7807) and USAGE regen (run.sh:9832).
|
|
163
|
+
out="$(printf '%s' "$prompt" \
|
|
164
|
+
| timeout "${LOKI_GRILL_TIMEOUT:-180}" claude --dangerously-skip-permissions --model "${LOKI_GRILL_MODEL:-sonnet}" -p - 2>/dev/null)"
|
|
165
|
+
if [ -z "$out" ]; then
|
|
166
|
+
_grill_err "provider returned no output (timeout or invocation error)"
|
|
167
|
+
return $GRILL_EXIT_ERROR
|
|
168
|
+
fi
|
|
169
|
+
printf '%s\n' "$out"
|
|
170
|
+
return 0
|
|
171
|
+
;;
|
|
172
|
+
codex)
|
|
173
|
+
if ! command -v codex >/dev/null 2>&1; then
|
|
174
|
+
_grill_err "Codex CLI not found."
|
|
175
|
+
return $GRILL_EXIT_ERROR
|
|
176
|
+
fi
|
|
177
|
+
local out
|
|
178
|
+
out="$(printf '%s' "$prompt" | timeout "${LOKI_GRILL_TIMEOUT:-180}" codex exec --full-auto - 2>/dev/null)"
|
|
179
|
+
if [ -z "$out" ]; then
|
|
180
|
+
_grill_err "provider returned no output"
|
|
181
|
+
return $GRILL_EXIT_ERROR
|
|
182
|
+
fi
|
|
183
|
+
printf '%s\n' "$out"
|
|
184
|
+
return 0
|
|
185
|
+
;;
|
|
186
|
+
*)
|
|
187
|
+
_grill_err "grill currently supports the claude and codex providers (got: $provider)"
|
|
188
|
+
return $GRILL_EXIT_ERROR
|
|
189
|
+
;;
|
|
190
|
+
esac
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
# ---------------------------------------------------------------------------
|
|
194
|
+
# Help
|
|
195
|
+
# ---------------------------------------------------------------------------
|
|
196
|
+
grill_help() {
|
|
197
|
+
cat <<'EOF'
|
|
198
|
+
loki grill - interrogate a spec with the hardest questions before you build it.
|
|
199
|
+
|
|
200
|
+
USAGE:
|
|
201
|
+
loki grill [<spec-path>] [options]
|
|
202
|
+
|
|
203
|
+
DESCRIPTION:
|
|
204
|
+
Invokes the provider once with a Devil's-Advocate prompt to produce the
|
|
205
|
+
10-15 hardest questions exposing ambiguities, missing acceptance criteria,
|
|
206
|
+
unstated assumptions, and security/scale blind spots in a spec. Writes a
|
|
207
|
+
structured markdown report to .loki/grill/report.md.
|
|
208
|
+
|
|
209
|
+
This is a PRE-build hardening step: a grilled spec is a better Reason input
|
|
210
|
+
to the RARV-C loop. It requires the provider CLI and fails cleanly (no
|
|
211
|
+
fabricated questions) when the provider is unavailable.
|
|
212
|
+
|
|
213
|
+
SPEC RESOLUTION (when <spec-path> is omitted, first match wins):
|
|
214
|
+
prd.md -> .loki/generated-prd.md -> PRD.md -> docs/prd.md
|
|
215
|
+
|
|
216
|
+
OPTIONS:
|
|
217
|
+
--apply Append the "Grill findings" section to the spec file itself.
|
|
218
|
+
--out <dir> Output directory for the report. Default: .loki/grill
|
|
219
|
+
-h, --help Show this help.
|
|
220
|
+
|
|
221
|
+
ENVIRONMENT:
|
|
222
|
+
LOKI_PROVIDER Provider to use (claude default; codex supported).
|
|
223
|
+
LOKI_GRILL_MODEL Claude model for the interrogation (default: sonnet).
|
|
224
|
+
LOKI_GRILL_TIMEOUT Per-invocation timeout in seconds (default: 180).
|
|
225
|
+
|
|
226
|
+
EXIT CODES:
|
|
227
|
+
0 report written
|
|
228
|
+
2 usage error (spec not found)
|
|
229
|
+
3 provider unavailable or interrogation failed (never silent)
|
|
230
|
+
|
|
231
|
+
OUTPUT:
|
|
232
|
+
<out>/report.md the structured interrogation report
|
|
233
|
+
EOF
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
# ---------------------------------------------------------------------------
|
|
237
|
+
# Entry point
|
|
238
|
+
# ---------------------------------------------------------------------------
|
|
239
|
+
grill_main() {
|
|
240
|
+
local spec_arg=""
|
|
241
|
+
local out_dir="$GRILL_DIR_DEFAULT"
|
|
242
|
+
local apply="false"
|
|
243
|
+
|
|
244
|
+
while [ $# -gt 0 ]; do
|
|
245
|
+
case "$1" in
|
|
246
|
+
-h|--help) grill_help; return $GRILL_EXIT_OK ;;
|
|
247
|
+
--apply) apply="true"; shift ;;
|
|
248
|
+
--out) out_dir="${2:-}"; shift 2 ;;
|
|
249
|
+
--) shift; break ;;
|
|
250
|
+
-*) _grill_err "unknown option: $1"; grill_help; return $GRILL_EXIT_USAGE ;;
|
|
251
|
+
*)
|
|
252
|
+
if [ -z "$spec_arg" ]; then spec_arg="$1"; else
|
|
253
|
+
_grill_err "unexpected argument: $1"; return $GRILL_EXIT_USAGE
|
|
254
|
+
fi
|
|
255
|
+
shift ;;
|
|
256
|
+
esac
|
|
257
|
+
done
|
|
258
|
+
|
|
259
|
+
local spec_path
|
|
260
|
+
if ! spec_path="$(grill_resolve_source "$spec_arg")"; then
|
|
261
|
+
if [ -n "$spec_arg" ]; then
|
|
262
|
+
_grill_err "spec file not found: $spec_arg"
|
|
263
|
+
else
|
|
264
|
+
_grill_err "no spec found (looked for prd.md, .loki/generated-prd.md, PRD.md, docs/prd.md). Pass a path explicitly."
|
|
265
|
+
fi
|
|
266
|
+
return $GRILL_EXIT_USAGE
|
|
267
|
+
fi
|
|
268
|
+
|
|
269
|
+
local spec_body
|
|
270
|
+
spec_body="$(cat "$spec_path" 2>/dev/null)"
|
|
271
|
+
if [ -z "$spec_body" ]; then
|
|
272
|
+
_grill_err "spec file is empty: $spec_path"
|
|
273
|
+
return $GRILL_EXIT_USAGE
|
|
274
|
+
fi
|
|
275
|
+
|
|
276
|
+
# LOW-6: validate the provider BEFORE logging the interrogation line, so an
|
|
277
|
+
# unavailable/unsupported provider fails cleanly (rc=3) without first printing
|
|
278
|
+
# a misleading "interrogating ... via <provider>" message.
|
|
279
|
+
grill_check_provider || return $GRILL_EXIT_ERROR
|
|
280
|
+
|
|
281
|
+
local prompt
|
|
282
|
+
prompt="$(grill_build_prompt "$spec_path" "$spec_body")"
|
|
283
|
+
|
|
284
|
+
_grill_log "interrogating $spec_path via ${LOKI_PROVIDER:-claude}..."
|
|
285
|
+
local report
|
|
286
|
+
report="$(grill_invoke_provider "$prompt")" || return $GRILL_EXIT_ERROR
|
|
287
|
+
|
|
288
|
+
mkdir -p "$out_dir" || { _grill_err "cannot create $out_dir"; return $GRILL_EXIT_ERROR; }
|
|
289
|
+
local report_path="$out_dir/$GRILL_REPORT_NAME"
|
|
290
|
+
|
|
291
|
+
{
|
|
292
|
+
printf '# Spec grill report\n\n'
|
|
293
|
+
# printf format strings must not begin with '-': bash's printf builtin
|
|
294
|
+
# parses a leading dash as an option flag (rc=2 "invalid option") and
|
|
295
|
+
# silently drops the line. Use '%s\n' with the dash inside the argument.
|
|
296
|
+
printf '%s\n' "- Spec: $spec_path"
|
|
297
|
+
printf '%s\n' "- Generated: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
298
|
+
printf '%s\n\n' "- Provider: ${LOKI_PROVIDER:-claude}"
|
|
299
|
+
printf '%s\n' "$report"
|
|
300
|
+
} >"$report_path" || { _grill_err "failed to write $report_path"; return $GRILL_EXIT_ERROR; }
|
|
301
|
+
|
|
302
|
+
_grill_log "report written: $report_path"
|
|
303
|
+
printf 'Grill report: %s\n' "$report_path"
|
|
304
|
+
|
|
305
|
+
if [ "$apply" = "true" ]; then
|
|
306
|
+
{
|
|
307
|
+
printf '\n\n<!-- loki grill: appended %s -->\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
308
|
+
printf '%s\n' "$report"
|
|
309
|
+
} >>"$spec_path" || { _grill_err "failed to append findings to $spec_path"; return $GRILL_EXIT_ERROR; }
|
|
310
|
+
_grill_log "appended Grill findings to $spec_path"
|
|
311
|
+
printf 'Appended Grill findings to: %s\n' "$spec_path"
|
|
312
|
+
fi
|
|
313
|
+
|
|
314
|
+
return $GRILL_EXIT_OK
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
# Allow direct execution: bash autonomy/grill.sh [args]
|
|
318
|
+
if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
|
|
319
|
+
grill_main "$@"
|
|
320
|
+
exit $?
|
|
321
|
+
fi
|