loki-mode 10.2.5 → 10.3.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/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/lib/engine10-push.sh +12 -1
- package/autonomy/lib/modernize/java_capture.sh +444 -0
- package/dashboard/__init__.py +1 -1
- package/docs/INSTALLATION.md +1 -1
- package/docs/v10/BOARD.md +25 -22
- package/docs/v10/DECISIONS.md +5 -0
- package/docs/v10/GUARDS.md +140 -0
- package/docs/v10/GUIDE-MODERNIZE.md +93 -0
- package/docs/v10/PROGRESS.md +16 -0
- package/loki-ts/dist/loki.js +532 -517
- package/mcp/__init__.py +1 -1
- package/package.json +1 -1
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/web-app/dist/assets/{AdminPage-BOESW7uR.js → AdminPage-Cbw_ElCY.js} +1 -1
- package/web-app/dist/assets/{Avatar-Blm74_mD.js → Avatar-BIPSPAq_.js} +1 -1
- package/web-app/dist/assets/{Badge-DdJmac3t.js → Badge-Ds9MSd7u.js} +1 -1
- package/web-app/dist/assets/{Button-Do43CF5O.js → Button-C0Flsmvz.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-DEPQn2Xm.js → CockpitPage-Bp1_2hHf.js} +1 -1
- package/web-app/dist/assets/{ComparePage-Dp4MSpts.js → ComparePage-BYUoDxD4.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-wTGWFgom.js → ErrorBoundary-2RVnleyJ.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-ChvPQb1U.js → EvidenceReceiptPanel-CsL2KIoA.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-uB0MpIb7.js → GitHubIssuesPanel-CjtkXtH4.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-B9FSjHfu.js → GitHubPRsPanel-Dn0MQlOl.js} +1 -1
- package/web-app/dist/assets/{HomePage-CriEbwCE.js → HomePage-TK7wY27j.js} +2 -2
- package/web-app/dist/assets/{LoginPage-DHbNkrh_.js → LoginPage-IWO6iIbt.js} +1 -1
- package/web-app/dist/assets/{MagicPage-BcpCAml7.js → MagicPage-BvXPjLPl.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-j75KQpua.js → MetricsPage-WB6chNRQ.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-CKbUnP7E.js → NotFoundPage-wHzb58is.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-BjGf-x2u.js → ProjectPage-BvfgSuNH.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-C3kHhUQ7.js → ProjectsPage-Bc-XKOdi.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-C1yjVDOm.js → SettingsPage-BoasXtyi.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-DhKkDB_5.js → ShowcasePage-BQ3Oi2Kt.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-BfAiCemG.js → SystemSettingsPage-D3mLoggO.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-DGAEPPh1.js → TeamsPage-BVO23r7A.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-LvQ3hwuA.js → TemplatesPage-CiLaTDHP.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-D8jsFsvX.js → TerminalOutput-3DwL15aa.js} +1 -1
- package/web-app/dist/assets/{activity-Hime0DJg.js → activity-nE9JBZE1.js} +1 -1
- package/web-app/dist/assets/{bell-CGbbuRF4.js → bell-CRDj-S-l.js} +1 -1
- package/web-app/dist/assets/{bot-CcTLPQ3e.js → bot-scrkkEwS.js} +1 -1
- package/web-app/dist/assets/{check-BzO3GwoU.js → check-DB5UlEKq.js} +1 -1
- package/web-app/dist/assets/{chevron-left-BRFaXiHd.js → chevron-left-DI1ZUltn.js} +1 -1
- package/web-app/dist/assets/{circle-alert-DDl3SqIA.js → circle-alert-DmjqpClG.js} +1 -1
- package/web-app/dist/assets/{clock-CK7f8Yqa.js → clock-CxOxLpB9.js} +1 -1
- package/web-app/dist/assets/{cloud-CbMCeoxr.js → cloud-Cioy4N3d.js} +1 -1
- package/web-app/dist/assets/{code-xml-BpwdRqwP.js → code-xml-XGTyeaui.js} +1 -1
- package/web-app/dist/assets/{database-B4JofR5i.js → database-DxNOgRAL.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-D3Uo_9Me.js → dollar-sign-DkudXWee.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-DWrhbnIl.js → file-code-corner-DD1ALh56.js} +1 -1
- package/web-app/dist/assets/{file-plus-Bob-tb45.js → file-plus-DRKBaZOM.js} +1 -1
- package/web-app/dist/assets/{globe-uJN2j0RG.js → globe-Cx9Kefsu.js} +1 -1
- package/web-app/dist/assets/{hammer-DHg-1oSy.js → hammer-DHivTbzj.js} +1 -1
- package/web-app/dist/assets/{index-NHr7F-mq.js → index-CZUWd8_O.js} +2 -2
- package/web-app/dist/assets/{layers-CsbGfI1E.js → layers-BK9AO5zh.js} +1 -1
- package/web-app/dist/assets/{loader-circle-C8iaLvST.js → loader-circle-BlQhXbH7.js} +1 -1
- package/web-app/dist/assets/{lock-B2ZA5xyD.js → lock-CUd78HQV.js} +1 -1
- package/web-app/dist/assets/{package-BIe5yA3N.js → package-DqgAeAvu.js} +1 -1
- package/web-app/dist/assets/{plus-Dutu3zwz.js → plus-BnNbuEwQ.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-DAodka-p.js → refresh-cw-BA2qvce4.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-BD6KP_Vv.js → rotate-ccw-BRWuu0SG.js} +1 -1
- package/web-app/dist/assets/{scroll-text-YKA_5gyw.js → scroll-text-BesWiqca.js} +1 -1
- package/web-app/dist/assets/{server-C21dybST.js → server-BcALRvWT.js} +1 -1
- package/web-app/dist/assets/{shield-alert-C70DSrSH.js → shield-alert-B9lelKUZ.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-Cc2gHDZ9.js → thumbs-up-kvcd_6aB.js} +1 -1
- package/web-app/dist/assets/{trash-2-Ch7SIljf.js → trash-2-yVZSntnY.js} +1 -1
- package/web-app/dist/assets/{trending-down-Ssp5wdTa.js → trending-down-BrJ1Rg6x.js} +1 -1
- package/web-app/dist/assets/{trending-up-BnDZm4bU.js → trending-up-B8KBS1fi.js} +1 -1
- package/web-app/dist/assets/{upload-DtQjXwrK.js → upload-DT3f6xVq.js} +1 -1
- package/web-app/dist/assets/{usePolling-7rvTmkii.js → usePolling-DqdFR9Fb.js} +1 -1
- package/web-app/dist/assets/{user-4s1moXeZ.js → user-mEyKrfXr.js} +1 -1
- package/web-app/dist/index.html +1 -1
package/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: loki-mode
|
|
|
3
3
|
description: Autonomous spec-driven build system with a built-in trust layer. It does not call work done until it is verified (RARV-C closure loop, 8 quality gates, completion council, verified-completion evidence gate). Triggers on "Loki Mode". Takes a spec (PRD, GitHub issue, OpenAPI doc, etc.) to deployed product with minimal human intervention. Provider-agnostic. Requires --dangerously-skip-permissions flag.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Loki Mode v10.
|
|
6
|
+
# Loki Mode v10.3.1
|
|
7
7
|
|
|
8
8
|
**You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
|
|
9
9
|
|
|
@@ -470,4 +470,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
|
|
|
470
470
|
|
|
471
471
|
---
|
|
472
472
|
|
|
473
|
-
**v10.
|
|
473
|
+
**v10.3.1 | [Autonomi](https://www.autonomi.dev/) flagship product | ~410 lines core**
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
10.
|
|
1
|
+
10.3.1
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
#
|
|
4
4
|
# engine10-push.sh push-pr <repo-dir> <branch> <title> <body-file> [--draft]
|
|
5
5
|
# engine10-push.sh comment <pr-number> <body-file>
|
|
6
|
+
# engine10-push.sh issue-comment <issue-ref> <body-file>
|
|
6
7
|
# engine10-push.sh status <sha> <pending|success|failure|error> <description>
|
|
7
8
|
#
|
|
8
9
|
# Holds GitHub credentials, runs no LLM, reads no untrusted text. Inputs come
|
|
@@ -137,6 +138,16 @@ case "$mode" in
|
|
|
137
138
|
[ -z "$_e10_local" ] || { log_info "local origin: no PR to comment on (no-op)"; exit 0; }
|
|
138
139
|
_e10_gh pr comment "$1" --repo "$_e10_repo" --body-file "$2" || die "gh pr comment failed"
|
|
139
140
|
;;
|
|
141
|
+
issue-comment)
|
|
142
|
+
# E-67: a FAILED run with no diff (or no remote) has no PR to open; comment on the issue
|
|
143
|
+
# instead so the run's reason is never silently lost. <issue-ref> is owner/repo#N or #N.
|
|
144
|
+
[ "$#" -eq 2 ] || die "usage: issue-comment <issue-ref> <body-file>"
|
|
145
|
+
num="${1##*#}"
|
|
146
|
+
case "$num" in '' | *[!0-9]*) die "cannot extract issue number from: $1" ;; esac
|
|
147
|
+
[ -f "$2" ] || die "body file not found: $2"
|
|
148
|
+
[ -z "$_e10_local" ] || { log_info "local origin: no issue to comment on (no-op)"; exit 0; }
|
|
149
|
+
_e10_gh issue comment "$num" --repo "$_e10_repo" --body-file "$2" || die "gh issue comment failed"
|
|
150
|
+
;;
|
|
140
151
|
status)
|
|
141
152
|
[ "$#" -eq 3 ] || die "usage: status <sha> <state> <description>"
|
|
142
153
|
[[ "$1" =~ ^[0-9a-f]{40}$ ]] || die "sha must be 40 lowercase hex characters"
|
|
@@ -145,5 +156,5 @@ case "$mode" in
|
|
|
145
156
|
_e10_gh api "repos/$_e10_repo/statuses/$1" -f "state=$2" -f context=loki/deep-verify \
|
|
146
157
|
-f "description=$3" >/dev/null || die "gh api status failed"
|
|
147
158
|
;;
|
|
148
|
-
*) die "usage: engine10-push.sh push-pr|comment|status ..." ;;
|
|
159
|
+
*) die "usage: engine10-push.sh push-pr|comment|issue-comment|status ..." ;;
|
|
149
160
|
esac
|
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# autonomy/lib/modernize/java_capture.sh -- M-11: Java 8 to 21 oracle capture
|
|
3
|
+
# (docs/v10/MODERNIZE.md sections 3.2 and 7: "Run the existing JUnit suite
|
|
4
|
+
# under JDK 8 with the JaCoCo agent. Add Randoop-generated regression tests
|
|
5
|
+
# per unit class ... Cases record the method, serialized arguments ..., the
|
|
6
|
+
# return value, the exception class and stdout.").
|
|
7
|
+
#
|
|
8
|
+
# Split (loki-ts/src/engine10/modernize/oracle/java.ts does every verdict):
|
|
9
|
+
# this script only runs tools and dumps RAW artifacts into --out:
|
|
10
|
+
# status.json -- what was detected: JDK 8 or not, jacoco/randoop jars
|
|
11
|
+
# jacoco.xml -- JaCoCo's own XML report (untouched, so java.ts can
|
|
12
|
+
# parse the real schema instead of a shape this script
|
|
13
|
+
# invents)
|
|
14
|
+
# replay1.jsonl -- one CaptureRunner run's raw case records
|
|
15
|
+
# replay2.jsonl -- a second, independent run of the same cases
|
|
16
|
+
# java.ts applies the double-replay determinism filter, the boundary check,
|
|
17
|
+
# coverage floor and NOT PROVEN reasons -- never this script. This script
|
|
18
|
+
# never claims a case is proven or a coverage number is final.
|
|
19
|
+
#
|
|
20
|
+
# CaptureRunner (embedded below as a heredoc, compiled once per call) does
|
|
21
|
+
# the actual reflection: it walks each unit class's public methods and
|
|
22
|
+
# invokes the capturable ones (primitives, String, List/Set/Map only --
|
|
23
|
+
# ponytail: no attempt to construct arbitrary objects or to replay Randoop's
|
|
24
|
+
# literal call sequences, which would need parsing generated Java source;
|
|
25
|
+
# upgrade path is Randoop's library API (randoop.sequence.Sequence) once a
|
|
26
|
+
# JDK 8 + Randoop jar host exists to build and test it against). A method
|
|
27
|
+
# whose parameter or return type falls outside that set gets ONE case record
|
|
28
|
+
# with a "not_capturable" reason and no invocation -- capture never guesses.
|
|
29
|
+
#
|
|
30
|
+
# Every branch below is exercised in loki-ts/tests/engine10/modernize/
|
|
31
|
+
# java_capture.test.ts with a stubbed PATH (fake java/javac/jacoco/randoop),
|
|
32
|
+
# because this repo has no JDK 8, JaCoCo or Randoop jar to run for real.
|
|
33
|
+
set -uo pipefail
|
|
34
|
+
|
|
35
|
+
usage() {
|
|
36
|
+
echo "usage: java_capture.sh --unit-dir DIR --classes FQCN[,FQCN...] --out DIR" \
|
|
37
|
+
"[--files REL.java[,REL.java...]] [--jacoco-agent JAR] [--jacoco-cli JAR]" \
|
|
38
|
+
"[--randoop-jar JAR] [--test-classpath CP] [--randoop-time-limit SECS]" >&2
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
UNIT_DIR=""
|
|
42
|
+
CLASSES=""
|
|
43
|
+
OUT_DIR=""
|
|
44
|
+
FILES_ARG=""
|
|
45
|
+
JACOCO_AGENT="${LOKI_MOD_JACOCO_AGENT:-}"
|
|
46
|
+
JACOCO_CLI="${LOKI_MOD_JACOCO_CLI:-}"
|
|
47
|
+
RANDOOP_JAR="${LOKI_MOD_RANDOOP_JAR:-}"
|
|
48
|
+
TEST_CLASSPATH=""
|
|
49
|
+
RANDOOP_TIME_LIMIT="20"
|
|
50
|
+
|
|
51
|
+
while [ $# -gt 0 ]; do
|
|
52
|
+
case "$1" in
|
|
53
|
+
--unit-dir) UNIT_DIR="$2"; shift 2 ;;
|
|
54
|
+
--classes) CLASSES="$2"; shift 2 ;;
|
|
55
|
+
--files) FILES_ARG="$2"; shift 2 ;;
|
|
56
|
+
--out) OUT_DIR="$2"; shift 2 ;;
|
|
57
|
+
--jacoco-agent) JACOCO_AGENT="$2"; shift 2 ;;
|
|
58
|
+
--jacoco-cli) JACOCO_CLI="$2"; shift 2 ;;
|
|
59
|
+
--randoop-jar) RANDOOP_JAR="$2"; shift 2 ;;
|
|
60
|
+
--test-classpath) TEST_CLASSPATH="$2"; shift 2 ;;
|
|
61
|
+
--randoop-time-limit) RANDOOP_TIME_LIMIT="$2"; shift 2 ;;
|
|
62
|
+
-h|--help) usage; exit 0 ;;
|
|
63
|
+
*) echo "java_capture.sh: unknown arg: $1" >&2; usage; exit 2 ;;
|
|
64
|
+
esac
|
|
65
|
+
done
|
|
66
|
+
|
|
67
|
+
if [ -z "$UNIT_DIR" ] || [ -z "$CLASSES" ] || [ -z "$OUT_DIR" ]; then
|
|
68
|
+
usage
|
|
69
|
+
exit 2
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
mkdir -p "$OUT_DIR" || { echo "java_capture.sh: cannot create --out $OUT_DIR" >&2; exit 2; }
|
|
73
|
+
|
|
74
|
+
REASONS=()
|
|
75
|
+
# JSON string escaping: backslash, double quote, then every C0 control character (0x00-0x1F).
|
|
76
|
+
# \n \r \t get their short escapes; the rest (e.g. a stray 0x01 or 0x1B in a user-set
|
|
77
|
+
# LOKI_MOD_JACOCO_AGENT/RANDOOP_JAR path, or an unusual `java -version` line) become \u00XX so
|
|
78
|
+
# status.json is always valid JSON no matter what these values contain. 0x00 is not handled --
|
|
79
|
+
# a bash/env-var string cannot carry a literal NUL byte, so it is unreachable here.
|
|
80
|
+
json_escape() {
|
|
81
|
+
local s="$1"
|
|
82
|
+
s="${s//\\/\\\\}"
|
|
83
|
+
s="${s//\"/\\\"}"
|
|
84
|
+
s="${s//$'\t'/\\t}"
|
|
85
|
+
s="${s//$'\r'/\\r}"
|
|
86
|
+
s="${s//$'\n'/\\n}"
|
|
87
|
+
local i c esc
|
|
88
|
+
for i in {1..31}; do
|
|
89
|
+
case "$i" in 9|10|13) continue ;; esac
|
|
90
|
+
c=$(printf '%b' "\\$(printf '%03o' "$i")")
|
|
91
|
+
esc=$(printf '\\u%04x' "$i")
|
|
92
|
+
s="${s//$c/$esc}"
|
|
93
|
+
done
|
|
94
|
+
printf '%s' "$s"
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
write_status() {
|
|
98
|
+
local jdk8="$1" jdk_raw="$2"
|
|
99
|
+
local reasons_json="[]"
|
|
100
|
+
if [ "${#REASONS[@]}" -gt 0 ]; then
|
|
101
|
+
reasons_json="["
|
|
102
|
+
local first=1
|
|
103
|
+
for r in "${REASONS[@]}"; do
|
|
104
|
+
[ "$first" -eq 1 ] || reasons_json+=","
|
|
105
|
+
reasons_json+="\"$(json_escape "$r")\""
|
|
106
|
+
first=0
|
|
107
|
+
done
|
|
108
|
+
reasons_json+="]"
|
|
109
|
+
fi
|
|
110
|
+
cat > "$OUT_DIR/status.json" <<EOF
|
|
111
|
+
{"jdk8":$jdk8,"jdkVersionRaw":$([ -n "$jdk_raw" ] && echo "\"$(json_escape "$jdk_raw")\"" || echo null),"jacocoAgent":$([ -n "$JACOCO_AGENT" ] && echo "\"$(json_escape "$JACOCO_AGENT")\"" || echo null),"jacocoCli":$([ -n "$JACOCO_CLI" ] && echo "\"$(json_escape "$JACOCO_CLI")\"" || echo null),"randoopJar":$([ -n "$RANDOOP_JAR" ] && echo "\"$(json_escape "$RANDOOP_JAR")\"" || echo null),"reasons":$reasons_json}
|
|
112
|
+
EOF
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
# --- 1. JDK 8 detection --------------------------------------------------
|
|
116
|
+
# A bare `command -v java` succeeds on macOS even with no JDK installed (the
|
|
117
|
+
# /usr/bin/java stub). The only reliable signal is `java -version`'s STDOUT
|
|
118
|
+
# (not stderr -- that varies by vendor/newer JDKs; javac/java both print the
|
|
119
|
+
# version string to stdout as of JDK 10+, and to stderr on 8/9 -- so check
|
|
120
|
+
# both streams rather than assume one).
|
|
121
|
+
if ! command -v java >/dev/null 2>&1; then
|
|
122
|
+
REASONS+=("skipped: no JDK 8" "old runtime unavailable: java not found on PATH")
|
|
123
|
+
write_status false ""
|
|
124
|
+
: > "$OUT_DIR/replay1.jsonl"
|
|
125
|
+
: > "$OUT_DIR/replay2.jsonl"
|
|
126
|
+
: > "$OUT_DIR/jacoco.xml"
|
|
127
|
+
exit 0
|
|
128
|
+
fi
|
|
129
|
+
|
|
130
|
+
JAVA_VER_OUT="$(java -version 2>&1)"
|
|
131
|
+
JDK8=false
|
|
132
|
+
if printf '%s' "$JAVA_VER_OUT" | grep -qE '"(1\.8\.|8\.)'; then
|
|
133
|
+
JDK8=true
|
|
134
|
+
fi
|
|
135
|
+
|
|
136
|
+
if [ "$JDK8" != "true" ]; then
|
|
137
|
+
REASONS+=("skipped: no JDK 8" "old runtime unavailable: detected $(printf '%s' "$JAVA_VER_OUT" | head -1)")
|
|
138
|
+
write_status false "$JAVA_VER_OUT"
|
|
139
|
+
: > "$OUT_DIR/replay1.jsonl"
|
|
140
|
+
: > "$OUT_DIR/replay2.jsonl"
|
|
141
|
+
: > "$OUT_DIR/jacoco.xml"
|
|
142
|
+
exit 0
|
|
143
|
+
fi
|
|
144
|
+
|
|
145
|
+
# --- 2. Compile the unit -------------------------------------------------
|
|
146
|
+
CLASSES_DIR="$OUT_DIR/classes"
|
|
147
|
+
mkdir -p "$CLASSES_DIR"
|
|
148
|
+
# The unit's own file list (--files, repo-relative to --unit-dir) is authoritative when given --
|
|
149
|
+
# oracle/java.ts always passes it, built from the merged M-04 graph, so only the unit's actual
|
|
150
|
+
# files ever get compiled here. Without it (a direct CLI call), every .java under --unit-dir is
|
|
151
|
+
# used, which is only correct when --unit-dir IS the unit (never a shared multi-unit checkout).
|
|
152
|
+
if [ -n "$FILES_ARG" ]; then
|
|
153
|
+
JAVA_FILES=$(printf '%s' "$FILES_ARG" | tr ',' '\n' | sed "s#^#${UNIT_DIR}/#" | tr '\n' ' ')
|
|
154
|
+
else
|
|
155
|
+
JAVA_FILES=$(find "$UNIT_DIR" -name '*.java' 2>/dev/null)
|
|
156
|
+
fi
|
|
157
|
+
if [ -z "$JAVA_FILES" ]; then
|
|
158
|
+
REASONS+=("no .java files found under --unit-dir")
|
|
159
|
+
write_status true "$JAVA_VER_OUT"
|
|
160
|
+
: > "$OUT_DIR/replay1.jsonl"
|
|
161
|
+
: > "$OUT_DIR/replay2.jsonl"
|
|
162
|
+
: > "$OUT_DIR/jacoco.xml"
|
|
163
|
+
exit 0
|
|
164
|
+
fi
|
|
165
|
+
# shellcheck disable=SC2086
|
|
166
|
+
if ! javac -d "$CLASSES_DIR" -cp "$TEST_CLASSPATH" $JAVA_FILES > "$OUT_DIR/javac.log" 2>&1; then
|
|
167
|
+
REASONS+=("javac failed: see javac.log")
|
|
168
|
+
write_status true "$JAVA_VER_OUT"
|
|
169
|
+
: > "$OUT_DIR/replay1.jsonl"
|
|
170
|
+
: > "$OUT_DIR/replay2.jsonl"
|
|
171
|
+
: > "$OUT_DIR/jacoco.xml"
|
|
172
|
+
exit 0
|
|
173
|
+
fi
|
|
174
|
+
|
|
175
|
+
# --- 3. Existing JUnit suite under the JaCoCo agent (coverage only) -----
|
|
176
|
+
# ponytail: not run. java_capture.sh only receives the unit's production FQCNs (--classes) --
|
|
177
|
+
# never which of them are JUnit test classes, because M-04/M-05 do not yet tag test files
|
|
178
|
+
# separately from production files in the unit graph. Running JUnitCore against the production
|
|
179
|
+
# classes (the previous behaviour here) executed no actual tests and silently mislabeled
|
|
180
|
+
# coverage as measuring the existing suite, so it is removed rather than kept wrong. Upgrade
|
|
181
|
+
# path: once the unit graph distinguishes test files, thread their FQCNs through as their own
|
|
182
|
+
# flag and run JUnitCore on those (not $CLASSES), under this same agent, before CaptureRunner.
|
|
183
|
+
EXEC_FILE="$OUT_DIR/jacoco.exec"
|
|
184
|
+
REASONS+=("existing JUnit suite not run: no test classes given to java_capture.sh")
|
|
185
|
+
if [ -z "$JACOCO_AGENT" ] || [ ! -f "$JACOCO_AGENT" ]; then
|
|
186
|
+
REASONS+=("jacoco agent not available: coverage not measured")
|
|
187
|
+
fi
|
|
188
|
+
|
|
189
|
+
# --- 4. Randoop regression tests: generated, compiled, smoke-run --------
|
|
190
|
+
# Randoop's own generated tests are run to confirm they compile and pass, but NOT under the
|
|
191
|
+
# jacoco agent: their branches are not yet turned into oracle cases (see the CaptureRunner
|
|
192
|
+
# comment below), so counting their coverage into EXEC_FILE would let branch_pct clear the 80%
|
|
193
|
+
# floor on branches cases.jsonl does not actually cover -- the exact failure this slice's review
|
|
194
|
+
# reproduced. ponytail: parsing Randoop's generated call sequences into cases.jsonl via the
|
|
195
|
+
# double replay (section 7) is not implemented; upgrade path is Randoop's library API
|
|
196
|
+
# (randoop.sequence.Sequence) once a JDK 8 + Randoop jar host exists to build against.
|
|
197
|
+
if [ -n "$RANDOOP_JAR" ] && [ -f "$RANDOOP_JAR" ]; then
|
|
198
|
+
RANDOOP_OUT="$OUT_DIR/randoop-tests"
|
|
199
|
+
mkdir -p "$RANDOOP_OUT"
|
|
200
|
+
RANDOOP_TESTCLASS_ARGS=()
|
|
201
|
+
IFS=',' read -ra RANDOOP_CLASS_LIST <<< "$CLASSES"
|
|
202
|
+
for rc in "${RANDOOP_CLASS_LIST[@]}"; do
|
|
203
|
+
RANDOOP_TESTCLASS_ARGS+=("--testclass=$rc")
|
|
204
|
+
done
|
|
205
|
+
(cd "$RANDOOP_OUT" && java -cp "${RANDOOP_JAR}:${CLASSES_DIR}" randoop.main.Main gentests \
|
|
206
|
+
"${RANDOOP_TESTCLASS_ARGS[@]}" \
|
|
207
|
+
--time-limit="$RANDOOP_TIME_LIMIT" \
|
|
208
|
+
--junit-output-dir="$RANDOOP_OUT" \
|
|
209
|
+
--regression-test-basename=RandoopRegression \
|
|
210
|
+
> "$OUT_DIR/randoop.log" 2>&1) || REASONS+=("randoop exited non-zero: see randoop.log")
|
|
211
|
+
RANDOOP_JAVA=$(find "$RANDOOP_OUT" -name '*.java' 2>/dev/null)
|
|
212
|
+
if [ -n "$RANDOOP_JAVA" ]; then
|
|
213
|
+
# shellcheck disable=SC2086
|
|
214
|
+
if javac -d "$CLASSES_DIR" -cp "${RANDOOP_JAR}:${CLASSES_DIR}" $RANDOOP_JAVA \
|
|
215
|
+
> "$OUT_DIR/randoop-javac.log" 2>&1; then
|
|
216
|
+
RANDOOP_CLASSES=$(cd "$RANDOOP_OUT" && find . -name '*.java' | sed 's#^\./##; s#\.java$##; s#/#.#g' | tr '\n' ' ')
|
|
217
|
+
# shellcheck disable=SC2086
|
|
218
|
+
java -cp "${CLASSES_DIR}:${RANDOOP_JAR}" org.junit.runner.JUnitCore \
|
|
219
|
+
$RANDOOP_CLASSES > "$OUT_DIR/junit-randoop.log" 2>&1 || true
|
|
220
|
+
REASONS+=("randoop tests generated and run but not yet added as oracle cases: double-replay of generated sequences not implemented")
|
|
221
|
+
else
|
|
222
|
+
REASONS+=("randoop-generated tests failed to compile: see randoop-javac.log")
|
|
223
|
+
fi
|
|
224
|
+
else
|
|
225
|
+
REASONS+=("randoop produced no regression tests")
|
|
226
|
+
fi
|
|
227
|
+
else
|
|
228
|
+
REASONS+=("randoop jar not available: no generated regression tests")
|
|
229
|
+
fi
|
|
230
|
+
|
|
231
|
+
# --- 5. CaptureRunner: reflective double replay (coverage source) -------
|
|
232
|
+
RUNNER_SRC="$OUT_DIR/CaptureRunner.java"
|
|
233
|
+
cat > "$RUNNER_SRC" <<'JAVA_EOF'
|
|
234
|
+
import java.lang.reflect.*;
|
|
235
|
+
import java.io.*;
|
|
236
|
+
import java.util.*;
|
|
237
|
+
|
|
238
|
+
/** M-11 embedded capture runner: for each given class, invokes every public
|
|
239
|
+
* capturable method (primitives/wrappers, String, List/Set/Map params and
|
|
240
|
+
* return only) with one canned argument per parameter, and writes one JSON
|
|
241
|
+
* case record per method to the given output file. A method outside that
|
|
242
|
+
* type set gets a not_capturable record with no invocation -- never guessed. */
|
|
243
|
+
public final class CaptureRunner {
|
|
244
|
+
static final Set<Class<?>> SCALAR = new HashSet<Class<?>>(Arrays.asList(
|
|
245
|
+
boolean.class, Boolean.class, byte.class, Byte.class, short.class, Short.class,
|
|
246
|
+
int.class, Integer.class, long.class, Long.class, float.class, Float.class,
|
|
247
|
+
double.class, Double.class, char.class, Character.class, String.class));
|
|
248
|
+
|
|
249
|
+
static boolean capturable(Class<?> t) {
|
|
250
|
+
if (t == void.class || t == Void.class) return true;
|
|
251
|
+
if (SCALAR.contains(t)) return true;
|
|
252
|
+
return List.class.isAssignableFrom(t) || Set.class.isAssignableFrom(t) || Map.class.isAssignableFrom(t);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
static Object canned(Class<?> t) {
|
|
256
|
+
if (t == boolean.class || t == Boolean.class) return Boolean.TRUE;
|
|
257
|
+
if (t == byte.class || t == Byte.class) return (byte) 1;
|
|
258
|
+
if (t == short.class || t == Short.class) return (short) 1;
|
|
259
|
+
if (t == int.class || t == Integer.class) return 1;
|
|
260
|
+
if (t == long.class || t == Long.class) return 1L;
|
|
261
|
+
if (t == float.class || t == Float.class) return 1.0f;
|
|
262
|
+
if (t == double.class || t == Double.class) return 1.0d;
|
|
263
|
+
if (t == char.class || t == Character.class) return 'a';
|
|
264
|
+
if (t == String.class) return "a";
|
|
265
|
+
if (List.class.isAssignableFrom(t)) return new ArrayList<Object>();
|
|
266
|
+
if (Set.class.isAssignableFrom(t)) return new TreeSet<Object>();
|
|
267
|
+
if (Map.class.isAssignableFrom(t)) return new TreeMap<Object, Object>();
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
static String esc(String s) {
|
|
272
|
+
StringBuilder b = new StringBuilder();
|
|
273
|
+
for (int i = 0; i < s.length(); i++) {
|
|
274
|
+
char c = s.charAt(i);
|
|
275
|
+
if (c == '"' || c == '\\') b.append('\\').append(c);
|
|
276
|
+
else if (c == '\n') b.append("\\n");
|
|
277
|
+
else if (c == '\r') b.append("\\r");
|
|
278
|
+
else if (c == '\t') b.append("\\t");
|
|
279
|
+
else if (c < 0x20) b.append(String.format("\\u%04x", (int) c));
|
|
280
|
+
else b.append(c);
|
|
281
|
+
}
|
|
282
|
+
return b.toString();
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
static String tag(Object v) {
|
|
286
|
+
if (v == null) return "{\"t\":\"none\"}";
|
|
287
|
+
if (v instanceof Boolean) return "{\"t\":\"bool\",\"v\":" + v + "}";
|
|
288
|
+
if (v instanceof Byte || v instanceof Short || v instanceof Integer || v instanceof Long) {
|
|
289
|
+
return "{\"t\":\"int\",\"v\":\"" + v + "\"}";
|
|
290
|
+
}
|
|
291
|
+
if (v instanceof Float || v instanceof Double) {
|
|
292
|
+
double d = ((Number) v).doubleValue();
|
|
293
|
+
String s = Double.isNaN(d) ? "\"nan\"" : Double.isInfinite(d) ? (d > 0 ? "\"inf\"" : "\"-inf\"") : String.valueOf(d);
|
|
294
|
+
return "{\"t\":\"float\",\"v\":" + s + "}";
|
|
295
|
+
}
|
|
296
|
+
if (v instanceof Character) return "{\"t\":\"text\",\"v\":\"" + esc(String.valueOf(v)) + "\"}";
|
|
297
|
+
if (v instanceof String) return "{\"t\":\"text\",\"v\":\"" + esc((String) v) + "\"}";
|
|
298
|
+
if (v instanceof List || v instanceof Set) {
|
|
299
|
+
StringBuilder b = new StringBuilder("{\"t\":\"list\",\"v\":[");
|
|
300
|
+
boolean first = true;
|
|
301
|
+
for (Object o : (Iterable<?>) v) {
|
|
302
|
+
if (!first) b.append(",");
|
|
303
|
+
b.append(tag(o));
|
|
304
|
+
first = false;
|
|
305
|
+
}
|
|
306
|
+
return b.append("]}").toString();
|
|
307
|
+
}
|
|
308
|
+
if (v instanceof Map) {
|
|
309
|
+
StringBuilder b = new StringBuilder("{\"t\":\"dict\",\"v\":[");
|
|
310
|
+
boolean first = true;
|
|
311
|
+
for (Map.Entry<?, ?> e : ((Map<?, ?>) v).entrySet()) {
|
|
312
|
+
if (!first) b.append(",");
|
|
313
|
+
b.append("[").append(tag(e.getKey())).append(",").append(tag(e.getValue())).append("]");
|
|
314
|
+
first = false;
|
|
315
|
+
}
|
|
316
|
+
return b.append("]}").toString();
|
|
317
|
+
}
|
|
318
|
+
return "{\"t\":\"unsupported\",\"type\":\"" + esc(v.getClass().getName()) + "\"}";
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
public static void main(String[] args) throws Exception {
|
|
322
|
+
if (args.length < 2) {
|
|
323
|
+
System.err.println("usage: CaptureRunner <out.jsonl> <FQCN>[,FQCN...]");
|
|
324
|
+
System.exit(2);
|
|
325
|
+
}
|
|
326
|
+
PrintWriter out = new PrintWriter(new FileWriter(args[0]));
|
|
327
|
+
for (String fqcn : args[1].split(",")) {
|
|
328
|
+
Class<?> cls;
|
|
329
|
+
try {
|
|
330
|
+
cls = Class.forName(fqcn);
|
|
331
|
+
} catch (Throwable t) {
|
|
332
|
+
out.println("{\"class\":\"" + esc(fqcn) + "\",\"method\":null,\"not_capturable\":[\"boundary:class " + esc(fqcn) + " failed to load\"]}");
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
335
|
+
Object instance = null;
|
|
336
|
+
boolean hasCtor = false;
|
|
337
|
+
try {
|
|
338
|
+
Constructor<?> c = cls.getDeclaredConstructor();
|
|
339
|
+
hasCtor = Modifier.isPublic(c.getModifiers());
|
|
340
|
+
} catch (Throwable ignored) {
|
|
341
|
+
hasCtor = false;
|
|
342
|
+
}
|
|
343
|
+
for (Method m : cls.getDeclaredMethods()) {
|
|
344
|
+
if (!Modifier.isPublic(m.getModifiers()) || m.isSynthetic() || m.isBridge()) continue;
|
|
345
|
+
Class<?>[] ptypes = m.getParameterTypes();
|
|
346
|
+
// Signature includes each parameter's simple type name, not just the count --
|
|
347
|
+
// same-name overloads with equal arity (add(int,int) vs add(String,String))
|
|
348
|
+
// would otherwise collide into one downstream map key and silently drop a case.
|
|
349
|
+
StringBuilder sigParams = new StringBuilder();
|
|
350
|
+
for (int i = 0; i < ptypes.length; i++) {
|
|
351
|
+
if (i > 0) sigParams.append(",");
|
|
352
|
+
sigParams.append(ptypes[i].getSimpleName());
|
|
353
|
+
}
|
|
354
|
+
String sig = fqcn + "#" + m.getName() + "(" + sigParams + ")";
|
|
355
|
+
boolean okParams = true;
|
|
356
|
+
for (Class<?> p : ptypes) if (!capturable(p)) okParams = false;
|
|
357
|
+
boolean okReturn = capturable(m.getReturnType());
|
|
358
|
+
boolean staticOk = Modifier.isStatic(m.getModifiers()) || hasCtor;
|
|
359
|
+
if (!okParams || !okReturn || !staticOk) {
|
|
360
|
+
String reason = !staticOk ? "no public zero-arg constructor" : "parameter or return type not capturable";
|
|
361
|
+
out.println("{\"class\":\"" + esc(fqcn) + "\",\"method\":\"" + esc(sig) + "\",\"not_capturable\":[\"boundary:" + esc(reason) + "\"]}");
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
Object[] callArgs = new Object[ptypes.length];
|
|
365
|
+
for (int i = 0; i < ptypes.length; i++) callArgs[i] = canned(ptypes[i]);
|
|
366
|
+
if (instance == null && !Modifier.isStatic(m.getModifiers())) {
|
|
367
|
+
try {
|
|
368
|
+
Constructor<?> c = cls.getDeclaredConstructor();
|
|
369
|
+
c.setAccessible(true);
|
|
370
|
+
instance = c.newInstance();
|
|
371
|
+
} catch (Throwable t) {
|
|
372
|
+
out.println("{\"class\":\"" + esc(fqcn) + "\",\"method\":\"" + esc(sig) + "\",\"not_capturable\":[\"boundary:constructor threw\"]}");
|
|
373
|
+
continue;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
ByteArrayOutputStream buf = new ByteArrayOutputStream();
|
|
377
|
+
PrintStream prevOut = System.out;
|
|
378
|
+
Object ret = null;
|
|
379
|
+
Throwable exc = null;
|
|
380
|
+
try {
|
|
381
|
+
System.setOut(new PrintStream(buf, true, "UTF-8"));
|
|
382
|
+
m.setAccessible(true);
|
|
383
|
+
ret = m.invoke(Modifier.isStatic(m.getModifiers()) ? null : instance, callArgs);
|
|
384
|
+
} catch (InvocationTargetException e) {
|
|
385
|
+
exc = e.getCause() != null ? e.getCause() : e;
|
|
386
|
+
} catch (Throwable t) {
|
|
387
|
+
exc = t;
|
|
388
|
+
} finally {
|
|
389
|
+
System.setOut(prevOut);
|
|
390
|
+
}
|
|
391
|
+
StringBuilder argsJson = new StringBuilder("[");
|
|
392
|
+
for (int i = 0; i < callArgs.length; i++) {
|
|
393
|
+
if (i > 0) argsJson.append(",");
|
|
394
|
+
argsJson.append(tag(callArgs[i]));
|
|
395
|
+
}
|
|
396
|
+
argsJson.append("]");
|
|
397
|
+
String stdout = buf.toString("UTF-8");
|
|
398
|
+
String excJson = exc == null ? "null" : "{\"type\":\"" + esc(exc.getClass().getName()) + "\"}";
|
|
399
|
+
String retJson = exc == null ? tag(ret) : "null";
|
|
400
|
+
out.println("{\"class\":\"" + esc(fqcn) + "\",\"method\":\"" + esc(sig) + "\",\"args\":" + argsJson
|
|
401
|
+
+ ",\"return\":" + retJson + ",\"exc\":" + excJson + ",\"stdout\":\"" + esc(stdout) + "\",\"not_capturable\":[]}");
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
out.close();
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
JAVA_EOF
|
|
408
|
+
|
|
409
|
+
if javac -d "$OUT_DIR" "$RUNNER_SRC" > "$OUT_DIR/runner-javac.log" 2>&1; then
|
|
410
|
+
# Only replay1 carries the jacoco agent: branch_pct must measure exactly the run that
|
|
411
|
+
# produced cases.jsonl, never a second, redundant pass -- replay2 exists purely for the
|
|
412
|
+
# determinism check above, not for coverage.
|
|
413
|
+
if [ -n "$JACOCO_AGENT" ] && [ -f "$JACOCO_AGENT" ]; then
|
|
414
|
+
java "-javaagent:${JACOCO_AGENT}=destfile=${EXEC_FILE},append=true" \
|
|
415
|
+
-cp "${OUT_DIR}:${CLASSES_DIR}" CaptureRunner "$OUT_DIR/replay1.jsonl" "$CLASSES" \
|
|
416
|
+
> "$OUT_DIR/replay1.log" 2>&1 || REASONS+=("CaptureRunner replay 1 exited non-zero")
|
|
417
|
+
else
|
|
418
|
+
java -cp "${OUT_DIR}:${CLASSES_DIR}" CaptureRunner "$OUT_DIR/replay1.jsonl" "$CLASSES" \
|
|
419
|
+
> "$OUT_DIR/replay1.log" 2>&1 || REASONS+=("CaptureRunner replay 1 exited non-zero")
|
|
420
|
+
fi
|
|
421
|
+
java -cp "${OUT_DIR}:${CLASSES_DIR}" CaptureRunner "$OUT_DIR/replay2.jsonl" "$CLASSES" \
|
|
422
|
+
> "$OUT_DIR/replay2.log" 2>&1 || REASONS+=("CaptureRunner replay 2 exited non-zero")
|
|
423
|
+
else
|
|
424
|
+
REASONS+=("CaptureRunner failed to compile: see runner-javac.log")
|
|
425
|
+
: > "$OUT_DIR/replay1.jsonl"
|
|
426
|
+
: > "$OUT_DIR/replay2.jsonl"
|
|
427
|
+
fi
|
|
428
|
+
|
|
429
|
+
# --- 6. JaCoCo XML report (raw, untouched -- java.ts parses it) ---------
|
|
430
|
+
# Runs after CaptureRunner so EXEC_FILE (written above, replay1 only) is complete before the
|
|
431
|
+
# report is built from it -- generating the report before the coverage-producing run even
|
|
432
|
+
# happened (the previous ordering here) always reported empty or stale coverage.
|
|
433
|
+
if [ -n "$JACOCO_CLI" ] && [ -f "$JACOCO_CLI" ] && [ -f "$EXEC_FILE" ]; then
|
|
434
|
+
java -jar "$JACOCO_CLI" report "$EXEC_FILE" \
|
|
435
|
+
--classfiles "$CLASSES_DIR" --sourcefiles "$UNIT_DIR" \
|
|
436
|
+
--xml "$OUT_DIR/jacoco.xml" > "$OUT_DIR/jacoco-report.log" 2>&1 \
|
|
437
|
+
|| REASONS+=("jacococli report failed: see jacoco-report.log")
|
|
438
|
+
else
|
|
439
|
+
REASONS+=("jacoco report not generated: agent, cli or exec data missing")
|
|
440
|
+
: > "$OUT_DIR/jacoco.xml"
|
|
441
|
+
fi
|
|
442
|
+
|
|
443
|
+
write_status true "$JAVA_VER_OUT"
|
|
444
|
+
exit 0
|
package/dashboard/__init__.py
CHANGED
package/docs/INSTALLATION.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The flagship product of [Autonomi](https://www.autonomi.dev/). Loki Mode is a spec-driven autonomous builder with a built-in trust layer that takes any spec to a deployed product and verifies completion with evidence (quality gates plus a completion council), not just a "done" claim. Complete installation instructions for all platforms and use cases.
|
|
4
4
|
|
|
5
|
-
**Version:** v10.
|
|
5
|
+
**Version:** v10.3.1
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|