guardian-framework 0.1.125 → 0.1.126
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/dist/cli.js +1 -1
- package/dist/exports.js +1 -1
- package/package.json +1 -1
- package/templates/pi/preflight_report.json +1 -1
- package/templates/pi/scripts/check_model_judgment.sh +4 -2
- package/templates/pi/scripts/coverage.sh +2 -2
- package/templates/pi/scripts/languages/java/check_model_judgment.sh +94 -62
- package/templates/pi/scripts/validate-runtime-wiring.sh +3 -3
package/dist/cli.js
CHANGED
|
@@ -3202,7 +3202,7 @@ __export(exports_package, {
|
|
|
3202
3202
|
bin: () => bin,
|
|
3203
3203
|
author: () => author
|
|
3204
3204
|
});
|
|
3205
|
-
var name = "guardian-framework", version = "0.1.
|
|
3205
|
+
var name = "guardian-framework", version = "0.1.126", description = "Token-optimized agentic framework scaffolder with pi-first architecture", type = "module", main = "dist/exports.js", exports, types = "dist/exports.d.ts", bin, files, engines, scripts, publishConfig, pi, repository, homepage = "https://github.com/arman-jalili/guardian-framework#readme", bugs, dependencies, devDependencies, keywords, author = "Arman Wolkensteiner-Jalili", license = "MIT", package_default;
|
|
3206
3206
|
var init_package = __esm(() => {
|
|
3207
3207
|
exports = {
|
|
3208
3208
|
".": {
|
package/dist/exports.js
CHANGED
|
@@ -1987,7 +1987,7 @@ __export(exports_package, {
|
|
|
1987
1987
|
bin: () => bin,
|
|
1988
1988
|
author: () => author
|
|
1989
1989
|
});
|
|
1990
|
-
var name = "guardian-framework", version = "0.1.
|
|
1990
|
+
var name = "guardian-framework", version = "0.1.126", description = "Token-optimized agentic framework scaffolder with pi-first architecture", type = "module", main = "dist/exports.js", exports, types = "dist/exports.d.ts", bin, files, engines, scripts, publishConfig, pi, repository, homepage = "https://github.com/arman-jalili/guardian-framework#readme", bugs, dependencies, devDependencies, keywords, author = "Arman Wolkensteiner-Jalili", license = "MIT", package_default;
|
|
1991
1991
|
var init_package = __esm(() => {
|
|
1992
1992
|
exports = {
|
|
1993
1993
|
".": {
|
package/package.json
CHANGED
|
@@ -13,10 +13,12 @@ cd "$ROOT" || exit 1
|
|
|
13
13
|
|
|
14
14
|
detect_language() {
|
|
15
15
|
if [ -f "Cargo.lock" ] || [ -f "Cargo.toml" ]; then echo "rust"
|
|
16
|
-
elif [ -f "package.json" ]; then echo "typescript"
|
|
17
16
|
elif [ -f "go.mod" ]; then echo "go"
|
|
17
|
+
# java first when a maven/gradle build (or src/main/java) is present — a root
|
|
18
|
+
# package.json (tooling) must not shadow a Java backend
|
|
19
|
+
elif [ -f "pom.xml" ] || [ -f "build.gradle" ] || [ -f "build.gradle.kts" ] || [ -d "src/main/java" ]; then echo "java"
|
|
20
|
+
elif [ -f "package.json" ]; then echo "typescript"
|
|
18
21
|
elif [ -f "pyproject.toml" ] || [ -f "requirements.txt" ]; then echo "python"
|
|
19
|
-
elif [ -f "pom.xml" ] || [ -f "build.gradle" ]; then echo "java"
|
|
20
22
|
else echo "unknown"; fi
|
|
21
23
|
}
|
|
22
24
|
LANG="$(detect_language)"
|
|
@@ -35,10 +35,10 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
|
35
35
|
|
|
36
36
|
detect_language() {
|
|
37
37
|
if [ -f "Cargo.lock" ] || [ -f "Cargo.toml" ]; then echo "rust"
|
|
38
|
-
elif [ -f "poetry.lock" ] || [ -f "pyproject.toml" ] || [ -f "requirements.txt" ]; then echo "python"
|
|
39
38
|
elif [ -f "go.mod" ]; then echo "go"
|
|
39
|
+
elif [ -f "pom.xml" ] || [ -f "build.gradle" ] || [ -f "build.gradle.kts" ] || [ -d "src/main/java" ]; then echo "java"
|
|
40
40
|
elif [ -f "package.json" ]; then echo "typescript"
|
|
41
|
-
elif [ -f "
|
|
41
|
+
elif [ -f "pyproject.toml" ] || [ -f "requirements.txt" ]; then echo "python"
|
|
42
42
|
else echo "unknown"; fi
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -1,41 +1,28 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# ============================================================================
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
# model, LSP base classes, Helper/Utils, primitive obsession) are NOT gated
|
|
7
|
-
# here — they surface as architecture-validator review questions instead.
|
|
8
|
-
#
|
|
9
|
-
# Rules (stable ids):
|
|
3
|
+
# check_model_judgment.sh — Java (ADR-008/009)
|
|
4
|
+
# Deterministic hard gates:
|
|
5
|
+
# dip-domain domain/ imports jakarta/javax.persistence, springframework, hibernate
|
|
10
6
|
# txn-placement @Transactional outside the application layer
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
# application/ of a generic subdomain
|
|
7
|
+
# interface-ownership (tactical) infra repository impls need a domain/-owned interface
|
|
8
|
+
# adapter-purity (adapter modules) model code in generic subdomains
|
|
9
|
+
# web-layer-leak interfaces/ (controllers) importing CONCRETE infrastructure
|
|
10
|
+
# implementations (Jdbc*/Local*/InMemory*/... or, in tactical
|
|
11
|
+
# modules, any .infrastructure. type)
|
|
17
12
|
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
# Exit: 0 all pass ; 1 violations found.
|
|
13
|
+
# Layout-aware: supports both src/<module>/{domain,...} and Maven
|
|
14
|
+
# src/main/java/<group>/<module>/{domain,...}. Module docs drive depth rules.
|
|
15
|
+
# Usage: bash check_model_judgment.sh [--root <dir>]
|
|
22
16
|
# ============================================================================
|
|
23
17
|
set -uo pipefail
|
|
24
|
-
|
|
25
18
|
ROOT="$(pwd)"
|
|
26
|
-
if [ "${1:-}" = "--root" ] && [ -n "${2:-}" ]; then
|
|
27
|
-
ROOT="$2"
|
|
28
|
-
fi
|
|
19
|
+
if [ "${1:-}" = "--root" ] && [ -n "${2:-}" ]; then ROOT="$2"; fi
|
|
29
20
|
cd "$ROOT" || exit 1
|
|
30
21
|
|
|
31
22
|
VIOLATIONS=0
|
|
23
|
+
report() { echo "$1:$2: [$3] $4"; VIOLATIONS=$((VIOLATIONS + 1)); }
|
|
32
24
|
|
|
33
|
-
|
|
34
|
-
echo "$1:$2: [$3] $4"
|
|
35
|
-
VIOLATIONS=$((VIOLATIONS + 1))
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
is_prod_java() { # path
|
|
25
|
+
is_prod_java() {
|
|
39
26
|
case "$1" in
|
|
40
27
|
*/test/*|*/src/test/*) return 1 ;;
|
|
41
28
|
*Test.java|*Tests.java) return 1 ;;
|
|
@@ -43,6 +30,28 @@ is_prod_java() { # path
|
|
|
43
30
|
return 0
|
|
44
31
|
}
|
|
45
32
|
|
|
33
|
+
# Resolve a module's source root for a module doc (kebab name).
|
|
34
|
+
# 1) legacy: src/<module>/
|
|
35
|
+
# 2) maven: src/main/java/<group>/<sanitized-module>/ (sanitized = lower, no separators)
|
|
36
|
+
resolve_module_root() { # doc_name
|
|
37
|
+
local doc_name="$1"
|
|
38
|
+
local norm legacy
|
|
39
|
+
norm="$(echo "$doc_name" | sed 's/^module[-_]//' | tr '[:upper:]' '[:lower:]' | tr '-' '_')"
|
|
40
|
+
legacy="src/$(echo "$doc_name" | sed 's/^module[-_]//' | tr '[:upper:]' '[:lower:]' | tr '-' '_')"
|
|
41
|
+
if [ -d "$legacy" ]; then echo "$legacy"; return; fi
|
|
42
|
+
if [ -d "src/main/java" ]; then
|
|
43
|
+
local sanitized
|
|
44
|
+
sanitized="$(echo "$doc_name" | tr '[:upper:]' '[:lower:]' | tr -d '_-')"
|
|
45
|
+
# match <group>/<sanitized> dir anywhere under the java tree (module package root)
|
|
46
|
+
local cand
|
|
47
|
+
while IFS= read -r cand; do
|
|
48
|
+
[ -n "$cand" ] || continue
|
|
49
|
+
if [ "$(basename "$cand")" = "$sanitized" ]; then echo "$cand"; return; fi
|
|
50
|
+
done < <(find "src/main/java" -type d -name "$sanitized" 2>/dev/null | head -3 || true)
|
|
51
|
+
fi
|
|
52
|
+
echo ""
|
|
53
|
+
}
|
|
54
|
+
|
|
46
55
|
# ── Rule 2: DIP — domain imports framework types ─────────────────────────────
|
|
47
56
|
while IFS= read -r f; do
|
|
48
57
|
[ -n "$f" ] || continue
|
|
@@ -77,28 +86,50 @@ while IFS= read -r f; do
|
|
|
77
86
|
done < <(grep -nE '@Transactional' "$f" || true)
|
|
78
87
|
done < <(find src -type f -name "*.java" 2>/dev/null || true)
|
|
79
88
|
|
|
80
|
-
# ── Rules 3
|
|
89
|
+
# ── Rules 3–5: module-doc depth-driven checks ─────────────────────────────────
|
|
81
90
|
if [ -d ".pi/architecture/modules" ]; then
|
|
82
91
|
for doc in .pi/architecture/modules/*.md; do
|
|
83
92
|
[ -f "$doc" ] || continue
|
|
84
93
|
doc_name="$(basename "$doc" .md)"
|
|
94
|
+
[ "$doc_name" = "module-template" ] && continue
|
|
85
95
|
depth="$(grep -m1 '^\*\*Modeling Depth:\*\*' "$doc" | sed 's/.*\*\*Modeling Depth:\*\* *//' | cut -d' ' -f1 || true)"
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
match_dir=""
|
|
89
|
-
while IFS= read -r d; do
|
|
90
|
-
[ -n "$d" ] || continue
|
|
91
|
-
norm="$(basename "$d" | tr '[:upper:]' '[:lower:]' | tr '-' '_')"
|
|
92
|
-
if [ "$norm" = "$docnorm" ]; then
|
|
93
|
-
match_dir="$d"
|
|
94
|
-
break
|
|
95
|
-
fi
|
|
96
|
-
done < <(find src -mindepth 1 -maxdepth 1 -type d 2>/dev/null || true)
|
|
97
|
-
|
|
96
|
+
match_dir="$(resolve_module_root "$doc_name")"
|
|
98
97
|
[ -n "$match_dir" ] || continue
|
|
99
98
|
|
|
99
|
+
# interfaces layer (http/web) — concrete infrastructure implementations leak
|
|
100
|
+
while IFS= read -r f; do
|
|
101
|
+
[ -n "$f" ] || continue
|
|
102
|
+
is_prod_java "$f" || continue
|
|
103
|
+
case "$f" in
|
|
104
|
+
*/interfaces/*)
|
|
105
|
+
while IFS=: read -r ln rest; do
|
|
106
|
+
case "$rest" in
|
|
107
|
+
*infrastructure.*)
|
|
108
|
+
cls="$(echo "$rest" | sed 's/^[[:space:]]*import[[:space:]]*//; s/;//' | awk -F. '{print $NF}')"
|
|
109
|
+
# concrete impl markers (Jdbc*/Jpa*/Local*/InMemory*/Hibernate*/...);
|
|
110
|
+
# in tactical modules ANY .infrastructure. import from web layer is a leak
|
|
111
|
+
case "$cls" in
|
|
112
|
+
Jdbc*|Jpa*|Local*|InMemory*|Hibernate*|Sql*|FileStore*|OutboxStore*)
|
|
113
|
+
report "$f" "$ln" "web-layer-leak" "web layer imports CONCRETE infrastructure impl $cls — depend on a port/interface via the application layer"
|
|
114
|
+
;;
|
|
115
|
+
esac
|
|
116
|
+
if [ "$depth" = "tactical" ]; then
|
|
117
|
+
case "$cls" in
|
|
118
|
+
*Repository*|*Port*|*Gateway*|*Service*|*Config*|*Store*)
|
|
119
|
+
: ;;
|
|
120
|
+
*)
|
|
121
|
+
report "$f" "$ln" "web-layer-leak" "tactical module: web layer imports infrastructure type $cls — go through the application layer"
|
|
122
|
+
;;
|
|
123
|
+
esac
|
|
124
|
+
fi
|
|
125
|
+
;;
|
|
126
|
+
esac
|
|
127
|
+
done < <(grep -nE '^[[:space:]]*import[[:space:]]+' "$f" || true)
|
|
128
|
+
;;
|
|
129
|
+
esac
|
|
130
|
+
done < <(find "$match_dir/interfaces" -type f -name "*.java" 2>/dev/null || true)
|
|
131
|
+
|
|
100
132
|
if [ "$depth" = "adapter" ]; then
|
|
101
|
-
# adapter-purity: no production java under domain/ or application/
|
|
102
133
|
for layer in domain application; do
|
|
103
134
|
while IFS= read -r f; do
|
|
104
135
|
[ -n "$f" ] || continue
|
|
@@ -107,36 +138,37 @@ if [ -d ".pi/architecture/modules" ]; then
|
|
|
107
138
|
done < <(find "$match_dir/$layer" -type f -name "*.java" 2>/dev/null || true)
|
|
108
139
|
done
|
|
109
140
|
elif [ "$depth" = "tactical" ]; then
|
|
110
|
-
# interface-ownership: infra repository
|
|
111
|
-
#
|
|
141
|
+
# interface-ownership: infra repository impls need a domain/-owned
|
|
142
|
+
# interface. Build candidate names by stripping Impl suffix and
|
|
143
|
+
# Jpa/Jdbc/Hibernate/Spring prefixes, then search the domain layer.
|
|
112
144
|
while IFS= read -r impl; do
|
|
113
145
|
[ -n "$impl" ] || continue
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
$
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
146
|
+
stem="$(basename "$impl" .java)"
|
|
147
|
+
names="$stem"
|
|
148
|
+
for n in "${stem%Impl}" "${stem#Jpa}" "${stem#Jdbc}" "${stem#Hibernate}" "${stem#Spring}"; do
|
|
149
|
+
[ -n "$n" ] || continue
|
|
150
|
+
case " $names " in *" $n "*) ;; *) names="$names $n" ;; esac
|
|
151
|
+
done
|
|
152
|
+
found=""
|
|
153
|
+
for n in $names; do
|
|
154
|
+
if grep -rqiE "interface ${n}\\b|class ${n}\\b" "$match_dir/domain" --include="*.java" 2>/dev/null; then
|
|
155
|
+
found=1; break
|
|
156
|
+
fi
|
|
157
|
+
done
|
|
158
|
+
if [ -z "$found" ]; then
|
|
159
|
+
compact="$(echo "$stem" | tr -d '_-')"
|
|
160
|
+
if [ -z "$compact" ] || ! grep -rqil --include="*.java" "$compact" "$match_dir/domain" 2>/dev/null; then
|
|
161
|
+
report "$impl" "1" "interface-ownership" "repository implementation without a domain/-owned interface (${stem})"
|
|
126
162
|
fi
|
|
127
|
-
done <<< "$candidates"
|
|
128
|
-
if [ ! -f "$domain_iface" ]; then
|
|
129
|
-
report "$impl" "1" "interface-ownership" "repository implementation without a domain/-owned interface (interface-ownership)"
|
|
130
163
|
fi
|
|
131
|
-
done < <(find "$match_dir/infrastructure" -type f -
|
|
164
|
+
done < <(find "$match_dir/infrastructure" -type f \( -iname "*Repository*.java" \) 2>/dev/null || true)
|
|
132
165
|
fi
|
|
133
166
|
done
|
|
134
167
|
fi
|
|
135
168
|
|
|
136
169
|
if [ "$VIOLATIONS" -gt 0 ]; then
|
|
137
|
-
echo "model-judgment: ${VIOLATIONS} violation(s)
|
|
170
|
+
echo "model-judgment (java): ${VIOLATIONS} violation(s)" >&2
|
|
138
171
|
exit 1
|
|
139
172
|
fi
|
|
140
|
-
|
|
141
|
-
echo "model-judgment (java): all gates passed (txn-placement, dip-domain, interface-ownership, adapter-purity)"
|
|
173
|
+
echo "model-judgment (java): all gates passed (dip-domain, txn-placement, interface-ownership, adapter-purity, web-layer-leak)"
|
|
142
174
|
exit 0
|
|
@@ -19,11 +19,11 @@ if [ "${1:-}" = "--root" ] && [ -n "${2:-}" ]; then ROOT="$2"; fi
|
|
|
19
19
|
cd "$ROOT" || exit 1
|
|
20
20
|
|
|
21
21
|
detect_language() {
|
|
22
|
-
if [ -f "Cargo.toml" ]; then echo "rust"
|
|
23
|
-
elif [ -f "package.json" ]; then echo "typescript"
|
|
22
|
+
if [ -f "Cargo.lock" ] || [ -f "Cargo.toml" ]; then echo "rust"
|
|
24
23
|
elif [ -f "go.mod" ]; then echo "go"
|
|
24
|
+
elif [ -f "pom.xml" ] || [ -f "build.gradle" ] || [ -f "build.gradle.kts" ] || [ -d "src/main/java" ]; then echo "java"
|
|
25
|
+
elif [ -f "package.json" ]; then echo "typescript"
|
|
25
26
|
elif [ -f "pyproject.toml" ] || [ -f "requirements.txt" ]; then echo "python"
|
|
26
|
-
elif [ -f "pom.xml" ] || [ -f "build.gradle" ]; then echo "java"
|
|
27
27
|
else echo "unknown"; fi
|
|
28
28
|
}
|
|
29
29
|
LANG="$(detect_language)"
|