loki-mode 11.3.9 → 11.5.1
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 +34 -18
- package/SKILL.md +3 -3
- package/VERSION +1 -1
- package/agents/custom_agents.py +280 -0
- package/autonomy/council-v2.sh +22 -1
- package/autonomy/edit.sh +242 -0
- package/autonomy/lib/chat.sh +315 -0
- package/autonomy/lib/engine10-push.sh +19 -1
- package/autonomy/lib/help-core.sh +164 -0
- package/autonomy/lib/json-output.sh +38 -0
- package/autonomy/lib/proof-generator.py +23 -5
- package/autonomy/lib/proof-verify.py +607 -5
- package/autonomy/lib/run-summary.sh +112 -0
- package/autonomy/lib/setup-requirements.json +35 -0
- package/autonomy/loki +337 -46
- package/autonomy/provider-offer.sh +95 -47
- package/autonomy/route.sh +302 -0
- package/autonomy/run.sh +48 -14
- package/autonomy/setup-wizard.sh +170 -0
- package/autonomy/verify.sh +62 -3
- package/bin/loki +73 -18
- package/completions/_loki +58 -1
- package/completions/loki.bash +57 -5
- package/dashboard/__init__.py +1 -1
- package/docs/CLI-CORE-VERBS.md +112 -0
- package/docs/CLI-REFERENCE.md +9 -1
- package/docs/COMPARE-OPENCODE.md +94 -0
- package/docs/COMPONENTS.md +1 -0
- package/docs/EVALUATING.md +27 -0
- package/docs/HARNESS-INTELLIGENCE-PLAN.md +20 -0
- package/docs/INSTALLATION.md +56 -12
- package/docs/KNOWN-ISSUES.md +8 -9
- package/docs/PROOF-PASSPORT.md +114 -0
- package/docs/QUICKSTART.md +108 -0
- package/docs/alternative-installations.md +103 -0
- package/docs/cost-controls.md +139 -0
- package/docs/environment-variables.md +45 -2
- package/docs/exit-codes.md +129 -12
- package/docs/spec-first-intent.md +29 -0
- package/docs/v10/CLI-MODERN.md +11 -5
- package/docs/v10/ENGINE.md +32 -0
- package/docs/v10/GUIDE.md +270 -44
- package/docs/v10/OPENCODE-PARITY-PLAN.md +84 -0
- package/loki-ts/data/model-pricing.json +1 -0
- package/loki-ts/dist/loki.js +1065 -978
- package/mcp/__init__.py +1 -1
- package/package.json +2 -2
- package/packages/control-plane/dist/server.js +1829 -715
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/plugins/loki-mode/README.md +41 -1
- package/plugins/loki-mode/commands/handoff.md +12 -0
- package/plugins/loki-mode/commands/loki-verify.md +9 -2
- package/plugins/loki-mode/commands/start.md +20 -0
- package/plugins/loki-mode/hooks/hooks.json +11 -0
- package/plugins/loki-mode/scripts/loki-stop-verify.sh +84 -0
- package/providers/claude.sh +16 -2
- package/providers/model_route_exec.sh +22 -0
- package/providers/model_routes.sh +188 -0
- package/skills/providers.md +13 -0
- package/templates/agents/planner.md +10 -0
- package/templates/agents/reviewer.md +10 -0
- package/templates/agents/tester.md +10 -0
- package/web-app/dist/assets/{AdminPage-QK-i_x-O.js → AdminPage-Cbu3pXL8.js} +1 -1
- package/web-app/dist/assets/{Avatar-DblkLNjB.js → Avatar-DGqGGcGx.js} +1 -1
- package/web-app/dist/assets/{Badge-DIV2ny5H.js → Badge-Bhlipt6v.js} +1 -1
- package/web-app/dist/assets/{Button--rePJOlQ.js → Button-CpN2sO61.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-BZlKxpGy.js → CockpitPage-BqeDJwdL.js} +1 -1
- package/web-app/dist/assets/{ComparePage-3_INSVux.js → ComparePage-DUieA2ba.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-DHG63CNr.js → ErrorBoundary-DTWsYrOm.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-DFsBnLlO.js → EvidenceReceiptPanel-BU_B9X19.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-phPGah98.js → GitHubIssuesPanel-DEZoLOsP.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-T7KQqJmx.js → GitHubPRsPanel-BEsnrq7Y.js} +1 -1
- package/web-app/dist/assets/{HomePage-DFjGUF5I.js → HomePage-BoUVuq7h.js} +2 -2
- package/web-app/dist/assets/{LoginPage-CorUid_5.js → LoginPage-CmOED7vb.js} +1 -1
- package/web-app/dist/assets/{MagicPage-DofbSxKD.js → MagicPage-DATZitrZ.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-qzrhhfLC.js → MetricsPage-DGL1v0I-.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-BAZR0mMb.js → NotFoundPage-C2WgOjZd.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-BOSUzG9J.js → ProjectPage-BMi1tepj.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-Ba0YLtzD.js → ProjectsPage-vc3y5YPh.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-Cr10Ue2K.js → SettingsPage-kbq0Ftvi.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-Czn655fe.js → ShowcasePage-Bn6Q8Kbg.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-Dwjnw6Ob.js → SystemSettingsPage-Basmhs_b.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-D8nc69Be.js → TeamsPage-BTqOc4TR.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-DHsaCDGv.js → TemplatesPage-2P9002VL.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-DBejni2a.js → TerminalOutput-CAoSPBrg.js} +1 -1
- package/web-app/dist/assets/{activity-B2VsBl1C.js → activity-BcWVWCqU.js} +1 -1
- package/web-app/dist/assets/{bell-CT77Fq2H.js → bell-CYRqqgZ6.js} +1 -1
- package/web-app/dist/assets/{bot-DfaWgF4H.js → bot-CU7gdn3g.js} +1 -1
- package/web-app/dist/assets/{check-D1yp7Ndv.js → check-DLlCpz9V.js} +1 -1
- package/web-app/dist/assets/{chevron-left-B6Pa8IOX.js → chevron-left-CE9Cb30C.js} +1 -1
- package/web-app/dist/assets/{circle-alert-D5jrL_Y7.js → circle-alert-uou4bjua.js} +1 -1
- package/web-app/dist/assets/{clock-DIsY_fa_.js → clock-C_dSJcDX.js} +1 -1
- package/web-app/dist/assets/{cloud-eGwLh1As.js → cloud-DZ22ITF6.js} +1 -1
- package/web-app/dist/assets/{code-xml-CGDIcZ3m.js → code-xml-BrJS0hhS.js} +1 -1
- package/web-app/dist/assets/{database-CWpdaykI.js → database-D2HOmxtl.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-DZEuTCs6.js → dollar-sign-CQ1vK_6q.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-BHBW6m9v.js → file-code-corner-w2vpGm5d.js} +1 -1
- package/web-app/dist/assets/{file-plus-D4h1jZSR.js → file-plus-DlF6wjkD.js} +1 -1
- package/web-app/dist/assets/{globe-CXdqKgwd.js → globe-Dy3lBJg1.js} +1 -1
- package/web-app/dist/assets/{hammer-B3YuuYI_.js → hammer-C3xIiRXN.js} +1 -1
- package/web-app/dist/assets/{index-BLEnboSv.js → index-4t-_IW2y.js} +3 -3
- package/web-app/dist/assets/{layers-Dvp5nFtw.js → layers-Y8Fs8qXI.js} +1 -1
- package/web-app/dist/assets/{loader-circle-DodDmIZ3.js → loader-circle-CxgN1v4m.js} +1 -1
- package/web-app/dist/assets/{lock-EiuaH1Ep.js → lock-DFFNbXDs.js} +1 -1
- package/web-app/dist/assets/{package-Cx4m2hFg.js → package-5e6qCTUg.js} +1 -1
- package/web-app/dist/assets/{plus-D-Sd5rpH.js → plus-C0Go_ytj.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-C0w1cdmF.js → refresh-cw-D4i-NW3o.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-C_qk6MTT.js → rotate-ccw-YlKkiUW6.js} +1 -1
- package/web-app/dist/assets/{scroll-text-DSxiFtkc.js → scroll-text-4qXOHTap.js} +1 -1
- package/web-app/dist/assets/{server-NTJt7I8M.js → server-BB6zXNp9.js} +1 -1
- package/web-app/dist/assets/{shield-alert-HBxMQOvH.js → shield-alert-D4tzjB1H.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-DEgsHzSD.js → thumbs-up-DZiRwdFj.js} +1 -1
- package/web-app/dist/assets/{trash-2-px46FnTD.js → trash-2-Dv_LkRIK.js} +1 -1
- package/web-app/dist/assets/{trending-down-CBosVGKa.js → trending-down-BJYp9PQe.js} +1 -1
- package/web-app/dist/assets/{trending-up-Dbd7zrQj.js → trending-up-BTcXLklK.js} +1 -1
- package/web-app/dist/assets/{upload-nhdFKAs1.js → upload-fcHqwOxr.js} +1 -1
- package/web-app/dist/assets/{usePolling-BgaGdinh.js → usePolling-BeJYw_4L.js} +1 -1
- package/web-app/dist/assets/{user-CzIihUy9.js → user-BcDwUCsO.js} +1 -1
- package/web-app/dist/index.html +1 -1
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Core help screen and help topics for `loki help`. Source this file; it
|
|
3
|
+
# defines functions only. The full command table stays in show_help_all
|
|
4
|
+
# (autonomy/loki) and is reached with `loki help all`.
|
|
5
|
+
|
|
6
|
+
# Topics reachable as `loki help <topic>`. Keep in sync with help_topic_text.
|
|
7
|
+
LOKI_HELP_TOPICS="providers exit-codes"
|
|
8
|
+
|
|
9
|
+
help_core_screen() {
|
|
10
|
+
local version="$1"
|
|
11
|
+
echo "Loki Mode v${version}"
|
|
12
|
+
echo ""
|
|
13
|
+
echo "Usage: loki <command> [options]"
|
|
14
|
+
echo ""
|
|
15
|
+
echo "Start:"
|
|
16
|
+
echo " start [SPEC] PRIMARY: build from a PRD file, brief, or issue (owner/repo#N, PROJ-1) (alias: run)"
|
|
17
|
+
echo " chat [--attach] Interactive alternative; --attach joins the current 'loki start' run"
|
|
18
|
+
echo " edit \"<change>\" Make one targeted change to the current repo"
|
|
19
|
+
echo " quick \"<task>\" One small task, no PR"
|
|
20
|
+
echo ""
|
|
21
|
+
echo "Check:"
|
|
22
|
+
echo " status [--json] What is running and where it stands"
|
|
23
|
+
echo " verify [--json] Deterministic verification (CI-gate exit codes)"
|
|
24
|
+
echo " receipt Inspect the proof-of-run receipt (alias of: proof)"
|
|
25
|
+
echo " diff / undo See what a run changed; undo <run> to plan or apply a rollback"
|
|
26
|
+
echo ""
|
|
27
|
+
echo "Configure:"
|
|
28
|
+
echo " setup First-run setup (provider, keys, defaults)"
|
|
29
|
+
echo " config Show or change settings (config list --json)"
|
|
30
|
+
echo " models Model tiers and routes (models --local for local models)"
|
|
31
|
+
echo " agents Agent roles and routing (route shows where a task would go)"
|
|
32
|
+
echo " doctor [--json] Check your setup is ready"
|
|
33
|
+
echo ""
|
|
34
|
+
echo "Options for 'start': --provider NAME, --model ID, --budget USD (default cap $(loki_budget_default_usd 2>/dev/null)), --isolation LVL (isolation dial: none | worktree | docker)"
|
|
35
|
+
echo "Also: cost / estimate (spend before you build), resume (continue a paused or interrupted run)"
|
|
36
|
+
echo "Exit codes: docs/exit-codes.md"
|
|
37
|
+
echo ""
|
|
38
|
+
echo "Examples:"
|
|
39
|
+
echo " loki start ./prd.md Build from a spec file"
|
|
40
|
+
echo " loki start owner/repo#123 Build from a GitHub issue"
|
|
41
|
+
echo " loki start ./prd.md --budget 20 Cap spend at 20 USD"
|
|
42
|
+
echo " loki plan ./prd.md Dry run: complexity, cost, plan"
|
|
43
|
+
echo " loki verify --json Machine-readable verification for CI"
|
|
44
|
+
echo " loki resume Continue a paused or interrupted run"
|
|
45
|
+
echo " loki status --json What is running, as JSON"
|
|
46
|
+
echo " loki cost ./prd.md Estimate spend before you build"
|
|
47
|
+
echo " loki doctor --fix Check setup and repair what it can"
|
|
48
|
+
echo ""
|
|
49
|
+
echo "More:"
|
|
50
|
+
echo " loki help all Every command"
|
|
51
|
+
echo " loki help <topic> Topics: ${LOKI_HELP_TOPICS// /, }"
|
|
52
|
+
echo " loki <command> --help Help for one command"
|
|
53
|
+
echo ""
|
|
54
|
+
echo "New here? Run: loki doctor, then loki quickstart"
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
help_topic_text() {
|
|
58
|
+
case "$1" in
|
|
59
|
+
start)
|
|
60
|
+
cat <<'T'
|
|
61
|
+
Starting work
|
|
62
|
+
|
|
63
|
+
loki start ./prd.md Build from a spec file
|
|
64
|
+
loki start owner/repo#123 Build from a GitHub issue
|
|
65
|
+
loki "<task>" Same as quick
|
|
66
|
+
loki quick "add dark mode" One small task, no PR
|
|
67
|
+
loki edit "rename foo to bar" One targeted change
|
|
68
|
+
loki chat Interactive alternative to start (/run inside chat runs loki start)
|
|
69
|
+
loki chat --attach Chat about the current or latest start run (/status /steer /diff /stop)
|
|
70
|
+
loki plan ./prd.md Dry run: complexity, cost, plan
|
|
71
|
+
|
|
72
|
+
Common flags: --provider NAME, --model ID (tier or route, e.g. ollama/qwen3-coder), --budget USD, --simple, --complex,
|
|
73
|
+
--no-dashboard, --spec FILE, --config PATH. Full list: loki help all.
|
|
74
|
+
T
|
|
75
|
+
;;
|
|
76
|
+
models)
|
|
77
|
+
cat <<'T'
|
|
78
|
+
Models
|
|
79
|
+
|
|
80
|
+
Loki routes work by tier: planning (opus), development (sonnet), fast (haiku).
|
|
81
|
+
loki models Show the model for each tier
|
|
82
|
+
loki models --local Show local models (Ollama, LM Studio, llama.cpp)
|
|
83
|
+
loki config set maxTier sonnet Cap model cost
|
|
84
|
+
loki config set model.development <id> Override one tier
|
|
85
|
+
LOKI_MODEL_OVERRIDE=<id> Force one model id (Anthropic-protocol gateways)
|
|
86
|
+
T
|
|
87
|
+
;;
|
|
88
|
+
providers)
|
|
89
|
+
cat <<'T'
|
|
90
|
+
Providers
|
|
91
|
+
|
|
92
|
+
Claude Code is the default and the only Tier 1 provider.
|
|
93
|
+
loki provider list Providers and install status
|
|
94
|
+
loki provider set codex Switch provider (claude, codex, cline, aider, opencode)
|
|
95
|
+
loki start ./prd.md --provider cline
|
|
96
|
+
|
|
97
|
+
Tier 2: cline. Tier 3 (sequential, degraded): codex, aider. opencode is model-agnostic.
|
|
98
|
+
T
|
|
99
|
+
;;
|
|
100
|
+
agents)
|
|
101
|
+
cat <<'T'
|
|
102
|
+
Agents
|
|
103
|
+
|
|
104
|
+
loki agents list|new|show Your own agents (.loki/agents/<name>.md); council reviewers use them
|
|
105
|
+
loki route "<task>" Show which engine, provider and model a task would use
|
|
106
|
+
loki agent --help Lower-level agent commands
|
|
107
|
+
|
|
108
|
+
Roles use Opus for planning, Sonnet for development, Haiku for fast work.
|
|
109
|
+
T
|
|
110
|
+
;;
|
|
111
|
+
verify)
|
|
112
|
+
cat <<'T'
|
|
113
|
+
Verification
|
|
114
|
+
|
|
115
|
+
loki verify Deterministic PR verification
|
|
116
|
+
loki verify --fast Exogenous checks only, milliseconds, no model call
|
|
117
|
+
loki verify --json One JSON object: command, exit_code, ok, output
|
|
118
|
+
loki verify --pubkey FILE Check a receipt against a public key
|
|
119
|
+
loki receipt Inspect the proof-of-run receipt
|
|
120
|
+
loki undo <run> [--plan] Plan or apply an undo of a run
|
|
121
|
+
|
|
122
|
+
Exit codes: see loki help exit-codes.
|
|
123
|
+
T
|
|
124
|
+
;;
|
|
125
|
+
exit-codes)
|
|
126
|
+
cat <<'T'
|
|
127
|
+
Exit codes
|
|
128
|
+
|
|
129
|
+
0 success
|
|
130
|
+
1 failure
|
|
131
|
+
2 usage error (unknown command, bad flag)
|
|
132
|
+
3 missing component
|
|
133
|
+
|
|
134
|
+
Severity rises with the code: a bigger number is never better news.
|
|
135
|
+
Per-command contracts (verify, proof, start under LOKI_DURABLE_STATE=1):
|
|
136
|
+
docs/exit-codes.md
|
|
137
|
+
T
|
|
138
|
+
;;
|
|
139
|
+
config)
|
|
140
|
+
cat <<'T'
|
|
141
|
+
Configuration
|
|
142
|
+
|
|
143
|
+
loki config Show current configuration
|
|
144
|
+
loki config list --json Machine-readable configuration
|
|
145
|
+
loki config set KEY VALUE Set a value (maxTier, model.planning, ...)
|
|
146
|
+
loki config get KEY Read a value
|
|
147
|
+
loki config validate [FILE] Validate loki.yaml
|
|
148
|
+
loki setup First-run setup
|
|
149
|
+
loki start --config FILE Load settings from a file
|
|
150
|
+
|
|
151
|
+
Precedence: CLI flag > env var > --config file > defaults.
|
|
152
|
+
Environment variables: docs/environment-variables.md
|
|
153
|
+
T
|
|
154
|
+
;;
|
|
155
|
+
*)
|
|
156
|
+
return 1
|
|
157
|
+
;;
|
|
158
|
+
esac
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
# Print the topic, or return 1 when $1 is not a topic.
|
|
162
|
+
help_topic() {
|
|
163
|
+
help_topic_text "$1"
|
|
164
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Shared --json helpers. Source this file; it defines functions only.
|
|
3
|
+
#
|
|
4
|
+
# loki_json_requested ARGS... exit 0 when --json is among ARGS
|
|
5
|
+
# loki_json_strip ARGS... print ARGS (one per line) without --json
|
|
6
|
+
# loki_json_wrap NAME CMD ARGS.. run CMD, print one JSON object:
|
|
7
|
+
# {"command":NAME,"exit_code":N,"ok":bool,"output":"..."}
|
|
8
|
+
# and return CMD's exit code. Use ONLY for
|
|
9
|
+
# commands with no native --json output.
|
|
10
|
+
|
|
11
|
+
loki_json_requested() {
|
|
12
|
+
local a
|
|
13
|
+
for a in "$@"; do
|
|
14
|
+
[ "$a" = "--json" ] && return 0
|
|
15
|
+
done
|
|
16
|
+
return 1
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
loki_json_strip() {
|
|
20
|
+
local a
|
|
21
|
+
for a in "$@"; do
|
|
22
|
+
[ "$a" = "--json" ] || printf '%s\n' "$a"
|
|
23
|
+
done
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
loki_json_wrap() {
|
|
27
|
+
local name="$1" out rc
|
|
28
|
+
shift
|
|
29
|
+
out="$("$@" 2>&1)"
|
|
30
|
+
rc=$?
|
|
31
|
+
LOKI_JW_NAME="$name" LOKI_JW_RC="$rc" LOKI_JW_OUT="$out" python3 -c '
|
|
32
|
+
import json, os, re
|
|
33
|
+
rc = int(os.environ["LOKI_JW_RC"])
|
|
34
|
+
out = re.sub(r"\x1b\[[0-9;]*m", "", os.environ["LOKI_JW_OUT"])
|
|
35
|
+
print(json.dumps({"command": os.environ["LOKI_JW_NAME"], "exit_code": rc, "ok": rc == 0, "output": out}))
|
|
36
|
+
'
|
|
37
|
+
return "$rc"
|
|
38
|
+
}
|
|
@@ -40,6 +40,21 @@ from efficiency_cost import collect_efficiency as _collect_efficiency # noqa: E
|
|
|
40
40
|
import effort_estimator # noqa: E402
|
|
41
41
|
from tree_digest import MANIFEST_VERSION, compute_tree_digest # noqa: E402
|
|
42
42
|
from workspace_diff import collect_workspace_diff # noqa: E402
|
|
43
|
+
import importlib.util as _ilu # noqa: E402
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _load_proof_verify_mod():
|
|
47
|
+
# proof-verify.py is hyphenated (not importable); it owns the verification record.
|
|
48
|
+
spec = _ilu.spec_from_file_location(
|
|
49
|
+
"loki_proof_verify", os.path.join(os.path.dirname(os.path.abspath(__file__)), "proof-verify.py"))
|
|
50
|
+
mod = _ilu.module_from_spec(spec)
|
|
51
|
+
spec.loader.exec_module(mod)
|
|
52
|
+
return mod
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
_PV = _load_proof_verify_mod()
|
|
56
|
+
_vr_capture_environment = _PV.capture_environment
|
|
57
|
+
_vr_git_dirty = _PV.git_dirty
|
|
43
58
|
|
|
44
59
|
|
|
45
60
|
# ---------------------------------------------------------------------------
|
|
@@ -1121,8 +1136,6 @@ def _empty_tree_sha(repo_dir):
|
|
|
1121
1136
|
# collect_workspace_diff), so uncommitted work is covered.
|
|
1122
1137
|
_TI_CFG_ALWAYS = re.compile(r"(^|/)(conftest\.py|\.?pytest\.(?:ini|toml)|tox\.ini|jest\.config\.[\w.]+|vitest\.config\.[\w.]+|\.mocharc[\w.]*)$")
|
|
1123
1138
|
_TI_CFG_SHARED = re.compile(r"(^|/)(setup\.cfg|pyproject\.toml|package\.json)$")
|
|
1124
|
-
_TI_TEST_FILE = re.compile(
|
|
1125
|
-
r"(^|/)(tests?|__tests__|spec|specs)/|\.(test|spec)\.[\w]+$|(^|/)test_[^/]*\.py$|_test\.(py|go|rs)$|(^|/)conftest\.py$")
|
|
1126
1139
|
_TI_SKIP_JS = re.compile(
|
|
1127
1140
|
# options object only as the 2nd argument: title (string or identifier), then `, {`
|
|
1128
1141
|
r"\b(test|it|describe|suite|context|specify)\s*\(\s*(?:'[^'\n]*'|\"[^\"\n]*\"|`[^`\n]*`|[\w.$]+)\s*,\s*\{[^}]*\b(skip|todo)\s*:\s*(?!(?:false|0|null|undefined)\b)\S"
|
|
@@ -1270,7 +1283,7 @@ def _collect_tests_integrity(target_dir, base):
|
|
|
1270
1283
|
if u and not u.startswith(".loki/"):
|
|
1271
1284
|
entries.append(("A", u, u))
|
|
1272
1285
|
for st, old, new in entries:
|
|
1273
|
-
if st in ("D", "R") and
|
|
1286
|
+
if st in ("D", "R") and _PV._TEST_FILE.search(old):
|
|
1274
1287
|
weakened.append("test file %s: %s" % ("deleted" if st == "D" else "renamed", old))
|
|
1275
1288
|
if not greenfield:
|
|
1276
1289
|
for st, old, new in entries:
|
|
@@ -1310,7 +1323,7 @@ def _collect_tests_integrity(target_dir, base):
|
|
|
1310
1323
|
edited.append(cur)
|
|
1311
1324
|
cur, rx, removed_assert = None, None, False
|
|
1312
1325
|
elif line.startswith("+++ b/"):
|
|
1313
|
-
cur = line[6:] if
|
|
1326
|
+
cur = line[6:] if _PV._TEST_FILE.search(line[6:]) else None
|
|
1314
1327
|
rx = _ti_skip_re(cur) if cur else None
|
|
1315
1328
|
elif cur and line.startswith("+") and rx and rx.search(line):
|
|
1316
1329
|
weakened.append("skip added in %s" % cur)
|
|
@@ -1318,7 +1331,7 @@ def _collect_tests_integrity(target_dir, base):
|
|
|
1318
1331
|
and _TI_ASSERT.search(line):
|
|
1319
1332
|
removed_assert = True
|
|
1320
1333
|
for u in untracked.split("\0"):
|
|
1321
|
-
if not u or u.startswith(".loki/") or not
|
|
1334
|
+
if not u or u.startswith(".loki/") or not _PV._TEST_FILE.search(u):
|
|
1322
1335
|
continue
|
|
1323
1336
|
rx = _ti_skip_re(u)
|
|
1324
1337
|
if not rx:
|
|
@@ -1625,6 +1638,9 @@ def _build_proof(args, loki_dir, target_dir, repo_root):
|
|
|
1625
1638
|
# recompute it after runner exit to reject proofs followed by code edits.
|
|
1626
1639
|
"tree_sha256": compute_tree_digest(target_dir),
|
|
1627
1640
|
"tree_manifest_version": MANIFEST_VERSION,
|
|
1641
|
+
# Execution validity (docs/PROOF-PASSPORT.md): whether the tree
|
|
1642
|
+
# was dirty when the checks ran. None when git could not answer.
|
|
1643
|
+
"dirty": _vr_git_dirty(target_dir),
|
|
1628
1644
|
}
|
|
1629
1645
|
facts = {
|
|
1630
1646
|
"git": git_facts,
|
|
@@ -1663,6 +1679,8 @@ def _build_proof(args, loki_dir, target_dir, repo_root):
|
|
|
1663
1679
|
# Descriptive; NOT read by _compute_headline (gating is founder-gated).
|
|
1664
1680
|
"healthcheck": healthcheck,
|
|
1665
1681
|
"cost": cost,
|
|
1682
|
+
# Environment the checks ran in (measured at generation time).
|
|
1683
|
+
"environment": _vr_capture_environment(),
|
|
1666
1684
|
"meta": {
|
|
1667
1685
|
"run_id": run_id,
|
|
1668
1686
|
"loki_version": loki_version,
|