loki-mode 7.56.0 → 7.58.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 +1 -1
- package/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/app-runner.sh +101 -0
- package/autonomy/lib/prd-enrich.sh +437 -0
- package/autonomy/loki +58 -9
- package/autonomy/run.sh +175 -60
- package/dashboard/__init__.py +1 -1
- package/dashboard/server.py +652 -194
- package/dashboard/static/index.html +164 -151
- package/docs/INSTALLATION.md +2 -2
- package/loki-ts/dist/loki.js +2 -2
- package/mcp/__init__.py +1 -1
- package/memory/consolidation.py +14 -2
- package/memory/retrieval.py +10 -0
- package/memory/storage.py +10 -0
- package/package.json +1 -1
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/skills/quality-gates.md +135 -11
package/autonomy/loki
CHANGED
|
@@ -2044,7 +2044,7 @@ cmd_start() {
|
|
|
2044
2044
|
case "$effective_provider" in
|
|
2045
2045
|
claude) echo " npm install -g @anthropic-ai/claude-code" ;;
|
|
2046
2046
|
codex) echo " npm install -g @openai/codex" ;;
|
|
2047
|
-
cline) echo " npm install -g
|
|
2047
|
+
cline) echo " npm install -g cline" ;;
|
|
2048
2048
|
aider) echo " pip install aider-chat" ;;
|
|
2049
2049
|
*) echo " Check the provider documentation for installation." ;;
|
|
2050
2050
|
esac
|
|
@@ -8049,10 +8049,37 @@ cmd_doctor() {
|
|
|
8049
8049
|
echo ""
|
|
8050
8050
|
|
|
8051
8051
|
echo -e "${CYAN}AI Providers:${NC}"
|
|
8052
|
-
|
|
8053
|
-
|
|
8054
|
-
doctor_check
|
|
8055
|
-
|
|
8052
|
+
# C1 (doctor UX): when an individual provider CLI is missing, print the
|
|
8053
|
+
# EXACT install command right under the WARN line so the user never has to
|
|
8054
|
+
# look it up. doctor_check returns 1 when the CLI is absent; we capture that
|
|
8055
|
+
# and emit the canonical install command for that provider. Honest: this
|
|
8056
|
+
# only PRINTS the command -- the offer-to-run path lives below, gated on a
|
|
8057
|
+
# TTY, and only when NO provider at all is installed.
|
|
8058
|
+
doctor_provider_install_cmd() {
|
|
8059
|
+
case "$1" in
|
|
8060
|
+
claude) echo "npm install -g @anthropic-ai/claude-code" ;;
|
|
8061
|
+
codex) echo "npm install -g @openai/codex" ;;
|
|
8062
|
+
cline) echo "npm install -g cline" ;;
|
|
8063
|
+
aider) echo "pip install aider-chat" ;;
|
|
8064
|
+
*) echo "" ;;
|
|
8065
|
+
esac
|
|
8066
|
+
}
|
|
8067
|
+
doctor_check_provider() {
|
|
8068
|
+
local _label="$1" _cmd="$2"
|
|
8069
|
+
if ! doctor_check "$_label" "$_cmd" optional; then
|
|
8070
|
+
local _install
|
|
8071
|
+
_install=$(doctor_provider_install_cmd "$_cmd")
|
|
8072
|
+
# Route the per-provider install hint to STDERR (fd 2), mirroring the
|
|
8073
|
+
# doctor_probe_note stderr-only pattern above. This keeps the
|
|
8074
|
+
# parity-captured STDOUT byte-identical to the Bun route (which emits
|
|
8075
|
+
# no per-provider Install line) while the user still sees the hint.
|
|
8076
|
+
[ -n "$_install" ] && echo -e " ${YELLOW}Install: ${_install}${NC}" >&2
|
|
8077
|
+
fi
|
|
8078
|
+
}
|
|
8079
|
+
doctor_check_provider "Claude CLI" claude || true
|
|
8080
|
+
doctor_check_provider "Codex CLI" codex || true
|
|
8081
|
+
doctor_check_provider "Cline CLI" cline || true
|
|
8082
|
+
doctor_check_provider "Aider CLI" aider || true
|
|
8056
8083
|
|
|
8057
8084
|
# Check if at least one provider is installed (detect_any_provider is the
|
|
8058
8085
|
# shared helper from provider-offer.sh, extracted from this exact loop).
|
|
@@ -8161,11 +8188,30 @@ cmd_doctor() {
|
|
|
8161
8188
|
echo -e " ${YELLOW}WARN${NC} sentence-transformers - not installed (loki memory vectors setup)"
|
|
8162
8189
|
warn_count=$((warn_count + 1))
|
|
8163
8190
|
fi
|
|
8164
|
-
#
|
|
8165
|
-
|
|
8191
|
+
# C3 (doctor UX): the next checks are bounded network probes, not instant
|
|
8192
|
+
# local lookups. They are the slowest part of doctor (a stale/unreachable
|
|
8193
|
+
# host could otherwise hang on curl's default ~2min connect timeout). We
|
|
8194
|
+
# (a) bound every probe with --connect-timeout/--max-time so a dead host
|
|
8195
|
+
# fails fast, and (b) print a transient progress note to stderr on a TTY so
|
|
8196
|
+
# the user knows doctor is doing network work, not stuck. The note goes to
|
|
8197
|
+
# stderr only -- the parity-captured stdout stays byte-identical across the
|
|
8198
|
+
# bash and Bun routes.
|
|
8199
|
+
doctor_probe_note() {
|
|
8200
|
+
[ -t 2 ] && printf ' %s...\r' "$1" >&2
|
|
8201
|
+
}
|
|
8202
|
+
doctor_probe_clear() {
|
|
8203
|
+
# Erase the transient progress line so it does not linger above the
|
|
8204
|
+
# PASS/WARN result. Only on a TTY (where the note was printed).
|
|
8205
|
+
[ -t 2 ] && printf '\r\033[K' >&2
|
|
8206
|
+
}
|
|
8207
|
+
# ChromaDB check (bounded network probe)
|
|
8208
|
+
doctor_probe_note "Probing ChromaDB (port 8100)"
|
|
8209
|
+
if curl -sf --connect-timeout 2 --max-time 5 http://localhost:8100/api/v2/heartbeat >/dev/null 2>&1; then
|
|
8210
|
+
doctor_probe_clear
|
|
8166
8211
|
echo -e " ${GREEN}PASS${NC} ChromaDB server (port 8100)"
|
|
8167
8212
|
pass_count=$((pass_count + 1))
|
|
8168
8213
|
else
|
|
8214
|
+
doctor_probe_clear
|
|
8169
8215
|
echo -e " ${YELLOW}WARN${NC} ChromaDB - not running (docker start loki-chroma)"
|
|
8170
8216
|
warn_count=$((warn_count + 1))
|
|
8171
8217
|
fi
|
|
@@ -8189,10 +8235,13 @@ cmd_doctor() {
|
|
|
8189
8235
|
# MiroFish check (optional service)
|
|
8190
8236
|
local _mf_url="${LOKI_MIROFISH_URL:-http://localhost:5001}"
|
|
8191
8237
|
if docker inspect loki-mirofish &>/dev/null 2>&1 || [[ -n "${LOKI_MIROFISH_URL:-}" ]]; then
|
|
8192
|
-
|
|
8238
|
+
doctor_probe_note "Probing MiroFish ($_mf_url)"
|
|
8239
|
+
if curl -sf --connect-timeout 2 --max-time 5 "$_mf_url/health" >/dev/null 2>&1; then
|
|
8240
|
+
doctor_probe_clear
|
|
8193
8241
|
echo -e " ${GREEN}PASS${NC} MiroFish server ($_mf_url)"
|
|
8194
8242
|
pass_count=$((pass_count + 1))
|
|
8195
8243
|
else
|
|
8244
|
+
doctor_probe_clear
|
|
8196
8245
|
echo -e " ${YELLOW}WARN${NC} MiroFish - not running (loki start --mirofish-docker <image>)"
|
|
8197
8246
|
warn_count=$((warn_count + 1))
|
|
8198
8247
|
fi
|
|
@@ -9939,7 +9988,7 @@ QPRDEOF
|
|
|
9939
9988
|
case "$_quick_provider" in
|
|
9940
9989
|
claude) echo " npm install -g @anthropic-ai/claude-code" ;;
|
|
9941
9990
|
codex) echo " npm install -g @openai/codex" ;;
|
|
9942
|
-
cline) echo " npm install -g
|
|
9991
|
+
cline) echo " npm install -g cline" ;;
|
|
9943
9992
|
aider) echo " pip install aider-chat" ;;
|
|
9944
9993
|
*) echo " Check the provider documentation for installation." ;;
|
|
9945
9994
|
esac
|
package/autonomy/run.sh
CHANGED
|
@@ -8320,23 +8320,31 @@ enforce_mutation_integrity() {
|
|
|
8320
8320
|
}
|
|
8321
8321
|
|
|
8322
8322
|
# ============================================================================
|
|
8323
|
-
# Semantic Test-Authenticity Gate (P1-3): wire tests/detect-semantic-test-problems.sh
|
|
8324
|
-
#
|
|
8325
|
-
#
|
|
8326
|
-
#
|
|
8327
|
-
#
|
|
8323
|
+
# Semantic Test-Authenticity Gate (P1-3): wire tests/detect-semantic-test-problems.sh.
|
|
8324
|
+
# The detector catches the harder class of fake tests that the regex detectors
|
|
8325
|
+
# (gates 5+6) miss: assertions that look real but verify nothing because the
|
|
8326
|
+
# asserted value never flows through code under test (literal-via-variable echo
|
|
8327
|
+
# HIGH, mock-return echo MED, deleted assertions MED).
|
|
8328
8328
|
#
|
|
8329
|
-
#
|
|
8330
|
-
#
|
|
8331
|
-
#
|
|
8332
|
-
#
|
|
8333
|
-
#
|
|
8334
|
-
#
|
|
8335
|
-
#
|
|
8336
|
-
#
|
|
8337
|
-
#
|
|
8338
|
-
#
|
|
8339
|
-
#
|
|
8329
|
+
# POSTURE (v7.57.0): this enforce_* helper is the shared core for TWO callers:
|
|
8330
|
+
# 1) the DEFAULT-ON mid-iteration ADVISORY arm (gated on LOKI_GATE_SEMANTIC_TESTS,
|
|
8331
|
+
# default true) -- runs every iteration, writes findings, and on a CRIT/HIGH
|
|
8332
|
+
# result the arm only calls track_gate_failure (surfaces to the next prompt),
|
|
8333
|
+
# NEVER PAUSEs / NEVER rejects completion (clone of the mock arm).
|
|
8334
|
+
# 2) the OPT-IN completion-BLOCKING elif (gated on LOKI_GATE_SEMANTIC_TESTS_BLOCK,
|
|
8335
|
+
# default false) -- when set, rejects the completion claim on a CRIT/HIGH.
|
|
8336
|
+
# The default-on flip applies ONLY to surfacing; blocking stays opt-in via the
|
|
8337
|
+
# separate _BLOCK flag, so surfacing-default-on does NOT make blocking default-on.
|
|
8338
|
+
#
|
|
8339
|
+
# NO-DEADLOCK CONTRACT: it runs the detector with --block-high (clean exit-code
|
|
8340
|
+
# contract: rc 2 iff a CRITICAL/HIGH finding exists). It surfaces ALL severities
|
|
8341
|
+
# to a findings file (advisory) and returns nonzero ONLY on rc 2. Every other
|
|
8342
|
+
# exit -- rc 0 (clean), rc 124 (timeout), detector absent, no test files,
|
|
8343
|
+
# malformed output -- returns 0 (pass/fall-through), so the autonomous loop can
|
|
8344
|
+
# NEVER deadlock on a clean run (default-on surfacing is therefore deadlock-safe,
|
|
8345
|
+
# exactly as the mock/mutation gates prove in production). Mirrors
|
|
8346
|
+
# enforce_mock_integrity's invocation (cd TARGET_DIR + LOKI_SCAN_DIR=TARGET_DIR +
|
|
8347
|
+
# timeout), swapping --strict for --block-high and deciding on the rc-2 contract.
|
|
8340
8348
|
# ============================================================================
|
|
8341
8349
|
enforce_semantic_integrity() {
|
|
8342
8350
|
local loki_dir="${TARGET_DIR:-.}/.loki"
|
|
@@ -8416,9 +8424,19 @@ _semantic_gate_and_surface() {
|
|
|
8416
8424
|
# redirect the scan).
|
|
8417
8425
|
# The PLURAL token LOKI_GATE_INVARIANTS is used deliberately to match the Bun
|
|
8418
8426
|
# readToggles flag name; the detector's own reference comment suggests a
|
|
8419
|
-
# singular
|
|
8420
|
-
#
|
|
8421
|
-
#
|
|
8427
|
+
# singular variant (no trailing S), which is NOT used here (parity needs the
|
|
8428
|
+
# plural).
|
|
8429
|
+
#
|
|
8430
|
+
# POSTURE (v7.57.0): this enforce_* helper is the shared core for TWO callers,
|
|
8431
|
+
# mirroring enforce_semantic_integrity:
|
|
8432
|
+
# 1) the DEFAULT-ON mid-iteration ADVISORY arm (gated on LOKI_GATE_INVARIANTS,
|
|
8433
|
+
# default true) -- runs every iteration, writes invariant-findings.txt, and
|
|
8434
|
+
# on a CRIT/HIGH result the arm only calls track_gate_failure (surfaces to
|
|
8435
|
+
# the next prompt via the invariant injector in build_prompt), NEVER PAUSEs /
|
|
8436
|
+
# NEVER rejects completion.
|
|
8437
|
+
# 2) the OPT-IN completion-BLOCKING elif (gated on LOKI_GATE_INVARIANTS_BLOCK,
|
|
8438
|
+
# default false) -- when set, rejects the completion claim on a CRIT/HIGH.
|
|
8439
|
+
# Surfacing-default-on does NOT make blocking default-on (separate _BLOCK flag).
|
|
8422
8440
|
enforce_invariant_integrity() {
|
|
8423
8441
|
local loki_dir="${TARGET_DIR:-.}/.loki"
|
|
8424
8442
|
local quality_dir="$loki_dir/quality"
|
|
@@ -12435,6 +12453,21 @@ if d.get('blocked'):
|
|
|
12435
12453
|
fi
|
|
12436
12454
|
fi
|
|
12437
12455
|
|
|
12456
|
+
# P1-4 / v7.57.0: surface specific invariant/property findings (which file,
|
|
12457
|
+
# which violated invariant) when the default-on advisory gate (or the opt-in
|
|
12458
|
+
# LOKI_GATE_INVARIANTS_BLOCK gate) wrote them, so a block converges and an
|
|
12459
|
+
# advisory run still informs the next iteration. The file exists only when
|
|
12460
|
+
# the gate ran AND found something (cleared on clean), so this is zero-cost on
|
|
12461
|
+
# a clean run and when the surfacing gate is opted out. Mirrors the semantic
|
|
12462
|
+
# injector above and is independent of gate-failures.txt presence.
|
|
12463
|
+
if [ -f "${TARGET_DIR:-.}/.loki/quality/invariant-findings.txt" ]; then
|
|
12464
|
+
local inv_findings
|
|
12465
|
+
inv_findings=$(grep -E '\[(CRITICAL|HIGH|MEDIUM|LOW)\]' "${TARGET_DIR:-.}/.loki/quality/invariant-findings.txt" 2>/dev/null | head -20 || true)
|
|
12466
|
+
if [ -n "$inv_findings" ]; then
|
|
12467
|
+
gate_failure_context="${gate_failure_context} INVARIANT/PROPERTY FINDINGS (fix the violated invariants; the code must preserve the stated property/metamorphic relation, not just pass example-based tests): ${inv_findings}"
|
|
12468
|
+
fi
|
|
12469
|
+
fi
|
|
12470
|
+
|
|
12438
12471
|
# P2-2: high-severity spec-assumption context. When DISCOVERY recorded any
|
|
12439
12472
|
# high-severity assumption (the spec was ambiguous in a high-impact place),
|
|
12440
12473
|
# surface it to the build agent so it implements with the gap in view (or
|
|
@@ -13461,9 +13494,12 @@ if not features:
|
|
|
13461
13494
|
continue
|
|
13462
13495
|
clean_name = strip_numbering(section_name)
|
|
13463
13496
|
if len(section_content) > 20 and len(clean_name) > 5:
|
|
13497
|
+
# BUG-A fix: store the REAL section/heading key (not a hardcoded
|
|
13498
|
+
# "Requirements") so sections.get(feat["section"]) later resolves
|
|
13499
|
+
# to this section's body and the description is not just the title.
|
|
13464
13500
|
features.append({
|
|
13465
13501
|
"title": clean_name,
|
|
13466
|
-
"section":
|
|
13502
|
+
"section": section_name,
|
|
13467
13503
|
})
|
|
13468
13504
|
|
|
13469
13505
|
if not features:
|
|
@@ -13601,6 +13637,20 @@ PRD_PARSE_EOF
|
|
|
13601
13637
|
return 0
|
|
13602
13638
|
fi
|
|
13603
13639
|
|
|
13640
|
+
# LLM enrichment post-pass (v7.52.0). The python heredoc above has no model
|
|
13641
|
+
# access, so stub tasks (description == title, or the templated user_story)
|
|
13642
|
+
# are enriched here via one batched provider call. Best-effort: on any
|
|
13643
|
+
# failure (non-claude provider, degraded mode, no binary, timeout, parse
|
|
13644
|
+
# error) the deterministic output is left intact. Never blocks the queue.
|
|
13645
|
+
local _prd_enrich_lib="$SCRIPT_DIR/lib/prd-enrich.sh"
|
|
13646
|
+
if [ -f "$_prd_enrich_lib" ]; then
|
|
13647
|
+
# shellcheck source=lib/prd-enrich.sh
|
|
13648
|
+
source "$_prd_enrich_lib" 2>/dev/null || true
|
|
13649
|
+
if declare -f loki_prd_enrich >/dev/null 2>&1; then
|
|
13650
|
+
loki_prd_enrich ".loki/queue/pending.json" "$effective_prd" || true
|
|
13651
|
+
fi
|
|
13652
|
+
fi
|
|
13653
|
+
|
|
13604
13654
|
touch ".loki/queue/.prd-populated"
|
|
13605
13655
|
log_info "PRD task parsing complete"
|
|
13606
13656
|
}
|
|
@@ -15146,27 +15196,39 @@ if __name__ == "__main__":
|
|
|
15146
15196
|
log_warn "Mutation integrity gate FAILED ($mt_count consecutive) - HIGH test-fitting detected"
|
|
15147
15197
|
fi
|
|
15148
15198
|
fi
|
|
15149
|
-
# LSP diagnostics gate (P1-5 bash-route parity, v7.51.0
|
|
15150
|
-
# parity gap: the Bun
|
|
15151
|
-
# (loki-ts/src/runner/quality_gates.ts)
|
|
15152
|
-
# writer (mcp/lsp_proxy.py); the bash
|
|
15153
|
-
#
|
|
15154
|
-
#
|
|
15155
|
-
#
|
|
15156
|
-
#
|
|
15157
|
-
#
|
|
15158
|
-
#
|
|
15159
|
-
#
|
|
15199
|
+
# LSP diagnostics gate (P1-5 bash-route parity, v7.51.0; default-on
|
|
15200
|
+
# advisory-surfacing as of v7.57.0). Closes the parity gap: the Bun
|
|
15201
|
+
# route ships runLSPDiagnostics (loki-ts/src/runner/quality_gates.ts)
|
|
15202
|
+
# with a route-neutral Python writer (mcp/lsp_proxy.py); the bash
|
|
15203
|
+
# route had NO writer/reader.
|
|
15204
|
+
#
|
|
15205
|
+
# POSTURE (v7.57.0): DEFAULT-ON SURFACING (no blocking arm exists).
|
|
15206
|
+
# This is the mid-iteration advisory arm -- it RUNS by default (like
|
|
15207
|
+
# the mock/mutation gates), writes lsp-diagnostics.json, and surfaces
|
|
15208
|
+
# errors to the NEXT iteration via track_gate_failure (the
|
|
15209
|
+
# lsp_diagnostics token flows into gate-failures.txt -> build_prompt).
|
|
15210
|
+
# It does NOT reject completion: the "block*" case below only calls
|
|
15211
|
+
# track_gate_failure, never PAUSE / never the completion-promise arm,
|
|
15212
|
+
# exactly like the mock gate. Default-on surfacing CANNOT deadlock
|
|
15213
|
+
# (mock/mutation prove this in production); there is therefore NO
|
|
15214
|
+
# separate blocking knob for LSP (none ever existed on the bash route).
|
|
15215
|
+
# - Toggle: LOKI_GATE_LSP_DIAGNOSTICS (default TRUE = surfacing on;
|
|
15216
|
+
# opt out with =false). Accepts "true" or "1". Single knob (no
|
|
15217
|
+
# blocking arm exists on the bash route, so there is no _BLOCK flag).
|
|
15218
|
+
# - count_errors > 0 -> surface (track_gate_failure), mirroring the
|
|
15219
|
+
# TS "errorCount > 0" finding at quality_gates.ts:1667 but WITHOUT
|
|
15220
|
+
# rejecting completion (advisory-first on the bash route).
|
|
15160
15221
|
# - warnings only -> advisory PASS (quality_gates.ts:1673).
|
|
15161
|
-
# - artifact absent/malformed -> honest pass-through, NEVER
|
|
15162
|
-
#
|
|
15222
|
+
# - artifact absent/malformed/timeout -> honest pass-through, NEVER
|
|
15223
|
+
# surface a block, NEVER deadlock (deny-filter; mirrors
|
|
15224
|
+
# quality_gates.ts:1646 returning passed:true on null artifact).
|
|
15163
15225
|
# The writer is OPT-OUT-able with LOKI_GATE_LSP_WRITER=0 (operator can
|
|
15164
15226
|
# supply a pre-built artifact), matching the TS escape hatch
|
|
15165
15227
|
# (quality_gates.ts:1630). cwd must be the install dir (PROJECT_DIR =
|
|
15166
15228
|
# $SCRIPT_DIR/.. ) so `-m mcp.lsp_proxy` imports, while --root points
|
|
15167
15229
|
# at the TARGET project the loop is building (mirrors
|
|
15168
15230
|
# runLSPDiagnosticsWriter: cwd=REPO_ROOT, --root=ctx.cwd).
|
|
15169
|
-
if [ "${LOKI_GATE_LSP_DIAGNOSTICS:-
|
|
15231
|
+
if { [ "${LOKI_GATE_LSP_DIAGNOSTICS:-true}" = "true" ] || [ "${LOKI_GATE_LSP_DIAGNOSTICS:-true}" = "1" ]; } && [ "$ITERATION_COUNT" -gt 0 ]; then
|
|
15170
15232
|
log_info "Quality gate: LSP diagnostics..."
|
|
15171
15233
|
# WRITER: route-neutral Python, same program as the Bun route.
|
|
15172
15234
|
if [ "${LOKI_GATE_LSP_WRITER:-1}" != "0" ]; then
|
|
@@ -15228,6 +15290,54 @@ else:
|
|
|
15228
15290
|
;;
|
|
15229
15291
|
esac
|
|
15230
15292
|
fi
|
|
15293
|
+
# Semantic test-authenticity gate -- mid-iteration ADVISORY arm
|
|
15294
|
+
# (v7.57.0 default-on surfacing). Clones the mock arm (~15126)
|
|
15295
|
+
# byte-for-byte: runs enforce_semantic_integrity, which writes
|
|
15296
|
+
# semantic-findings.txt and returns 1 ONLY on a CRITICAL/HIGH
|
|
15297
|
+
# fake-test finding (clean / no-test-files / detector-absent / timeout
|
|
15298
|
+
# / malformed all collapse to rc 0 inside the function -- deny-filter).
|
|
15299
|
+
# On rc 1 we ONLY track_gate_failure (surface to the next prompt via
|
|
15300
|
+
# the semantic-findings injector at build_prompt); we NEVER PAUSE and
|
|
15301
|
+
# NEVER reject completion here. Default-on surfacing cannot deadlock
|
|
15302
|
+
# (mock/mutation prove this in production). The opt-in completion-
|
|
15303
|
+
# BLOCKING arm lives behind LOKI_GATE_SEMANTIC_TESTS_BLOCK at the
|
|
15304
|
+
# completion-promise elif below; this surfacing arm is independent.
|
|
15305
|
+
# - Toggle: LOKI_GATE_SEMANTIC_TESTS (default TRUE = surfacing on;
|
|
15306
|
+
# opt out with =false). Accepts "true" or "1".
|
|
15307
|
+
if { [ "${LOKI_GATE_SEMANTIC_TESTS:-true}" = "true" ] || [ "${LOKI_GATE_SEMANTIC_TESTS:-true}" = "1" ]; } && [ "$ITERATION_COUNT" -gt 0 ]; then
|
|
15308
|
+
log_info "Quality gate: semantic test-authenticity (advisory)..."
|
|
15309
|
+
if enforce_semantic_integrity; then
|
|
15310
|
+
clear_gate_failure "semantic_tests"
|
|
15311
|
+
else
|
|
15312
|
+
local sem_count
|
|
15313
|
+
sem_count=$(track_gate_failure "semantic_tests")
|
|
15314
|
+
gate_failures="${gate_failures}semantic_tests,"
|
|
15315
|
+
log_warn "Semantic test-authenticity gate FAILED ($sem_count consecutive) - CRITICAL/HIGH fake-test problems (advisory; surfaced to next iteration)"
|
|
15316
|
+
fi
|
|
15317
|
+
fi
|
|
15318
|
+
# Invariant/property gate -- mid-iteration ADVISORY arm (v7.57.0
|
|
15319
|
+
# default-on surfacing). Mirrors the semantic arm above: runs
|
|
15320
|
+
# enforce_invariant_integrity, which writes invariant-findings.txt and
|
|
15321
|
+
# returns 1 ONLY on a CRITICAL/HIGH invariant violation (clean /
|
|
15322
|
+
# detector-absent / timeout / malformed all collapse to rc 0 inside
|
|
15323
|
+
# the function -- deny-filter). On rc 1 we ONLY track_gate_failure
|
|
15324
|
+
# (surfaced to the next prompt via the invariant-findings injector in
|
|
15325
|
+
# build_prompt); we NEVER PAUSE and NEVER reject completion here. The
|
|
15326
|
+
# opt-in completion-BLOCKING arm lives behind LOKI_GATE_INVARIANTS_BLOCK
|
|
15327
|
+
# at the completion-promise elif below.
|
|
15328
|
+
# - Toggle: LOKI_GATE_INVARIANTS (default TRUE = surfacing on; opt
|
|
15329
|
+
# out with =false). Accepts "true" or "1".
|
|
15330
|
+
if { [ "${LOKI_GATE_INVARIANTS:-true}" = "true" ] || [ "${LOKI_GATE_INVARIANTS:-true}" = "1" ]; } && [ "$ITERATION_COUNT" -gt 0 ]; then
|
|
15331
|
+
log_info "Quality gate: invariant/property (advisory)..."
|
|
15332
|
+
if enforce_invariant_integrity; then
|
|
15333
|
+
clear_gate_failure "invariants"
|
|
15334
|
+
else
|
|
15335
|
+
local inv_count
|
|
15336
|
+
inv_count=$(track_gate_failure "invariants")
|
|
15337
|
+
gate_failures="${gate_failures}invariants,"
|
|
15338
|
+
log_warn "Invariant gate FAILED ($inv_count consecutive) - CRITICAL/HIGH invariant/property violations (advisory; surfaced to next iteration)"
|
|
15339
|
+
fi
|
|
15340
|
+
fi
|
|
15231
15341
|
# Code review gate (upgraded from advisory, with escalation)
|
|
15232
15342
|
if [ "$PHASE_CODE_REVIEW" = "true" ] && [ "$ITERATION_COUNT" -gt 0 ]; then
|
|
15233
15343
|
log_info "Quality gate: code review..."
|
|
@@ -15534,35 +15644,40 @@ else:
|
|
|
15534
15644
|
log_warn "Completion claim rejected: assumption ledger gate found unresolved high-severity spec assumption(s)."
|
|
15535
15645
|
log_warn " Details under .loki/council/assumption-block.json ; opt out with LOKI_ASSUMPTION_GATE=0"
|
|
15536
15646
|
# Fall through; keep iterating until high-sev assumptions resolve.
|
|
15537
|
-
# P1-3: semantic test-authenticity gate (OPT-IN,
|
|
15538
|
-
# fake tests that look real but verify nothing
|
|
15539
|
-
# echo etc.) that the regex gates 5+6 miss.
|
|
15540
|
-
#
|
|
15541
|
-
#
|
|
15542
|
-
#
|
|
15543
|
-
#
|
|
15544
|
-
#
|
|
15545
|
-
#
|
|
15546
|
-
#
|
|
15547
|
-
|
|
15647
|
+
# P1-3: semantic test-authenticity completion-BLOCKING gate (OPT-IN,
|
|
15648
|
+
# default OFF). Catches fake tests that look real but verify nothing
|
|
15649
|
+
# (literal-via-variable echo etc.) that the regex gates 5+6 miss.
|
|
15650
|
+
# v7.57.0: the SURFACING of these findings is now default-on (see the
|
|
15651
|
+
# mid-iteration advisory arm above, gated on LOKI_GATE_SEMANTIC_TESTS,
|
|
15652
|
+
# default true). This completion-BLOCKING arm is a SEPARATE opt-in,
|
|
15653
|
+
# gated on LOKI_GATE_SEMANTIC_TESTS_BLOCK (default OFF; accepts "true"
|
|
15654
|
+
# or "1"), so the surfacing-default-on flip does NOT make blocking
|
|
15655
|
+
# default-on. When the BLOCK flag is set it runs the detector with --block-high and
|
|
15656
|
+
# rejects completion ONLY on a CRITICAL/HIGH finding; clean /
|
|
15657
|
+
# no-test-files / detector-absent / timeout / malformed all collapse
|
|
15658
|
+
# to a pass inside _semantic_gate_and_surface, so the autonomous loop
|
|
15659
|
+
# can never deadlock on a clean run. Mirrors the evidence / held-out /
|
|
15660
|
+
# assumption arms above.
|
|
15661
|
+
elif [ "$_completion_claimed" = 1 ] && { [ "${LOKI_GATE_SEMANTIC_TESTS_BLOCK:-false}" = "true" ] || [ "${LOKI_GATE_SEMANTIC_TESTS_BLOCK:-false}" = "1" ]; } && type _semantic_gate_and_surface &>/dev/null && ! _semantic_gate_and_surface; then
|
|
15548
15662
|
log_warn "Completion claim rejected: semantic test-authenticity gate found CRITICAL/HIGH fake-test problem(s)."
|
|
15549
|
-
log_warn " Details under .loki/quality/semantic-findings.txt ; opt-in
|
|
15663
|
+
log_warn " Details under .loki/quality/semantic-findings.txt ; opt-in blocking -- disable with LOKI_GATE_SEMANTIC_TESTS_BLOCK=false"
|
|
15550
15664
|
# Fall through; keep iterating until the fake tests are fixed.
|
|
15551
|
-
# P1-4: invariant/property gate (OPT-IN, default
|
|
15552
|
-
# semantic arm above and the Bun route's invariants
|
|
15553
|
-
# (loki-ts/src/runner/quality_gates.ts:2057).
|
|
15554
|
-
#
|
|
15555
|
-
#
|
|
15556
|
-
#
|
|
15557
|
-
#
|
|
15558
|
-
#
|
|
15559
|
-
#
|
|
15560
|
-
#
|
|
15561
|
-
# collapse to a pass
|
|
15562
|
-
# autonomous loop can never
|
|
15563
|
-
|
|
15665
|
+
# P1-4: invariant/property completion-BLOCKING gate (OPT-IN, default
|
|
15666
|
+
# OFF). Mirrors the semantic arm above and the Bun route's invariants
|
|
15667
|
+
# toggle (loki-ts/src/runner/quality_gates.ts:2057). v7.57.0: the
|
|
15668
|
+
# SURFACING of these findings is now default-on (see the mid-iteration
|
|
15669
|
+
# advisory arm above, gated on LOKI_GATE_INVARIANTS, default true).
|
|
15670
|
+
# This completion-BLOCKING arm is a SEPARATE opt-in, gated on
|
|
15671
|
+
# LOKI_GATE_INVARIANTS_BLOCK (default OFF), so the surfacing-default-on
|
|
15672
|
+
# flip does NOT make blocking default-on. Accepts "true" or "1". When
|
|
15673
|
+
# the BLOCK flag is set it runs detect-invariant-violations.sh --strict
|
|
15674
|
+
# and rejects completion ONLY on a CRITICAL/HIGH (rc 1) finding;
|
|
15675
|
+
# clean / detector-absent / timeout / malformed all collapse to a pass
|
|
15676
|
+
# inside _invariant_gate_and_surface, so the autonomous loop can never
|
|
15677
|
+
# deadlock on a clean run.
|
|
15678
|
+
elif [ "$_completion_claimed" = 1 ] && { [ "${LOKI_GATE_INVARIANTS_BLOCK:-false}" = "true" ] || [ "${LOKI_GATE_INVARIANTS_BLOCK:-false}" = "1" ]; } && type _invariant_gate_and_surface &>/dev/null && ! _invariant_gate_and_surface; then
|
|
15564
15679
|
log_warn "Completion claim rejected: invariant gate found CRITICAL/HIGH invariant/property violation(s)."
|
|
15565
|
-
log_warn " Details under .loki/quality/invariant-findings.txt ; opt-in
|
|
15680
|
+
log_warn " Details under .loki/quality/invariant-findings.txt ; opt-in blocking -- disable with LOKI_GATE_INVARIANTS_BLOCK=false"
|
|
15566
15681
|
# Fall through; keep iterating until the invariant violations are fixed.
|
|
15567
15682
|
elif [ "$_completion_claimed" = 1 ]; then
|
|
15568
15683
|
echo ""
|