@esoteric-logic/praxis-harness 2.11.0 → 2.12.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/base/CLAUDE.md +14 -1
- package/base/hooks/auto-format.sh +1 -1
- package/base/hooks/dep-audit.sh +1 -1
- package/base/hooks/file-guard.sh +3 -3
- package/base/hooks/recursion-guard.sh +7 -1
- package/base/hooks/session-data-collect.sh +1 -1
- package/base/hooks/vault-checkpoint.sh +5 -5
- package/base/rules/code-excellence.md +22 -0
- package/base/rules/coding.md +16 -0
- package/base/rules/observable-code.md +87 -0
- package/base/rules/refactor-triggers.md +59 -0
- package/base/rules/writing-quality.md +122 -0
- package/base/skills/px-complexity-audit/SKILL.md +118 -0
- package/base/skills/px-discover/SKILL.md +4 -1
- package/base/skills/px-discuss/SKILL.md +4 -1
- package/base/skills/px-doc-lint/SKILL.md +107 -0
- package/base/skills/px-prose-review/SKILL.md +96 -0
- package/base/skills/px-quality-gate/SKILL.md +182 -0
- package/base/skills/px-risk/SKILL.md +4 -1
- package/base/skills/px-scaffold-new/SKILL.md +16 -14
- package/base/skills/px-session-retro/SKILL.md +1 -1
- package/base/skills/px-spec/SKILL.md +6 -2
- package/base/skills/px-verify/SKILL.md +2 -1
- package/bin/praxis.js +27 -6
- package/kits/api/install.sh +1 -1
- package/kits/api/teardown.sh +1 -1
- package/kits/code-quality/hooks/generate-baseline.sh +1 -1
- package/kits/code-quality/hooks/post-commit.sh +3 -2
- package/kits/code-quality/hooks/pre-push.sh +15 -15
- package/kits/code-quality/install.sh +1 -1
- package/kits/code-quality/teardown.sh +3 -3
- package/kits/data/install.sh +1 -1
- package/kits/data/teardown.sh +1 -1
- package/kits/infrastructure/install.sh +1 -1
- package/kits/infrastructure/teardown.sh +1 -1
- package/kits/security/install.sh +1 -1
- package/kits/security/teardown.sh +1 -1
- package/kits/web-designer/install.sh +1 -1
- package/kits/web-designer/teardown.sh +1 -1
- package/package.json +1 -1
- package/scripts/health-check.sh +21 -15
- package/scripts/install-tools.sh +5 -5
- package/scripts/lint-harness.sh +1 -1
- package/scripts/onboard-mcp.sh +1 -1
- package/scripts/test-harness.sh +1 -1
- package/scripts/update.sh +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
set -
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
3
|
|
|
4
4
|
REPO_ROOT=$(git rev-parse --show-toplevel)
|
|
5
5
|
KIT_DIR="$REPO_ROOT/.claude/kits/code-quality"
|
|
@@ -33,7 +33,7 @@ echo "------------------------"
|
|
|
33
33
|
|
|
34
34
|
# Get changed files only (diff-scoped scanning)
|
|
35
35
|
CHANGED=$(git diff --name-only origin/HEAD...HEAD 2>/dev/null || git diff --name-only HEAD~1...HEAD 2>/dev/null || echo "")
|
|
36
|
-
if [ -z "$CHANGED" ]; then
|
|
36
|
+
if [[ -z "$CHANGED" ]]; then
|
|
37
37
|
echo " No changed files detected — skipping gate"
|
|
38
38
|
exit 0
|
|
39
39
|
fi
|
|
@@ -46,7 +46,7 @@ GATE_FAILURES=()
|
|
|
46
46
|
GATE_WARNINGS=()
|
|
47
47
|
|
|
48
48
|
# -- SAST (OpenGrep) --
|
|
49
|
-
if [ -s "$TMP/code-files.txt" ]; then
|
|
49
|
+
if [[ -s "$TMP/code-files.txt" ]]; then
|
|
50
50
|
echo " SAST scan (OpenGrep)..."
|
|
51
51
|
FILES=$(cat "$TMP/code-files.txt" | tr '\n' ' ')
|
|
52
52
|
opengrep scan --config auto --json $FILES > "$TMP/sast.json" 2>/dev/null || true
|
|
@@ -54,8 +54,8 @@ if [ -s "$TMP/code-files.txt" ]; then
|
|
|
54
54
|
CRITICAL=$(safe_jq '[.results[] | select(.extra.severity == "ERROR")] | length' "$TMP/sast.json")
|
|
55
55
|
HIGH=$(safe_jq '[.results[] | select(.extra.severity == "WARNING")] | length' "$TMP/sast.json")
|
|
56
56
|
|
|
57
|
-
[ "$CRITICAL" -gt 0 ] && GATE_FAILURES+=("SAST: $CRITICAL critical findings")
|
|
58
|
-
[ "$HIGH" -gt 0 ] && GATE_WARNINGS+=("SAST: $HIGH high findings")
|
|
57
|
+
[[ "$CRITICAL" -gt 0 ]] && GATE_FAILURES+=("SAST: $CRITICAL critical findings")
|
|
58
|
+
[[ "$HIGH" -gt 0 ]] && GATE_WARNINGS+=("SAST: $HIGH high findings")
|
|
59
59
|
echo " Critical: $CRITICAL High: $HIGH"
|
|
60
60
|
fi &
|
|
61
61
|
SAST_PID=$!
|
|
@@ -68,7 +68,7 @@ if [[ -s "$TMP/secrets.json" ]]; then
|
|
|
68
68
|
else
|
|
69
69
|
SECRETS=0
|
|
70
70
|
fi
|
|
71
|
-
[ "$SECRETS" -gt 0 ] && GATE_FAILURES+=("SECRETS: $SECRETS verified secrets found")
|
|
71
|
+
[[ "$SECRETS" -gt 0 ]] && GATE_FAILURES+=("SECRETS: $SECRETS verified secrets found")
|
|
72
72
|
echo " Verified secrets: $SECRETS" &
|
|
73
73
|
SECRETS_PID=$!
|
|
74
74
|
|
|
@@ -77,17 +77,17 @@ echo " Dependency scan (OSV-Scanner)..."
|
|
|
77
77
|
osv-scanner scan --format json "$REPO_ROOT" > "$TMP/sca.json" 2>/dev/null || true
|
|
78
78
|
SCA_CRITICAL=$(safe_jq '[.vulns[]? | select(.database_specific.severity? == "CRITICAL")] | length' "$TMP/sca.json")
|
|
79
79
|
SCA_HIGH=$(safe_jq '[.vulns[]? | select(.database_specific.severity? == "HIGH")] | length' "$TMP/sca.json")
|
|
80
|
-
[ "$SCA_CRITICAL" -gt 0 ] && GATE_FAILURES+=("SCA: $SCA_CRITICAL critical CVEs in dependencies")
|
|
81
|
-
[ "$SCA_HIGH" -gt 0 ] && GATE_WARNINGS+=("SCA: $SCA_HIGH high CVEs in dependencies")
|
|
80
|
+
[[ "$SCA_CRITICAL" -gt 0 ]] && GATE_FAILURES+=("SCA: $SCA_CRITICAL critical CVEs in dependencies")
|
|
81
|
+
[[ "$SCA_HIGH" -gt 0 ]] && GATE_WARNINGS+=("SCA: $SCA_HIGH high CVEs in dependencies")
|
|
82
82
|
echo " Critical CVEs: $SCA_CRITICAL High CVEs: $SCA_HIGH" &
|
|
83
83
|
SCA_PID=$!
|
|
84
84
|
|
|
85
85
|
# -- IaC (Checkov) --
|
|
86
|
-
if [ -s "$TMP/iac-files.txt" ]; then
|
|
86
|
+
if [[ -s "$TMP/iac-files.txt" ]]; then
|
|
87
87
|
echo " IaC scan (Checkov)..."
|
|
88
88
|
checkov -d "$REPO_ROOT" --output json --quiet --compact 2>/dev/null > "$TMP/iac.json" || true
|
|
89
89
|
IaC_FAIL=$(safe_jq '.results.failed_checks | length' "$TMP/iac.json")
|
|
90
|
-
[ "$IaC_FAIL" -gt 0 ] && GATE_WARNINGS+=("IaC: $IaC_FAIL policy violations")
|
|
90
|
+
[[ "$IaC_FAIL" -gt 0 ]] && GATE_WARNINGS+=("IaC: $IaC_FAIL policy violations")
|
|
91
91
|
echo " Policy violations: $IaC_FAIL"
|
|
92
92
|
fi &
|
|
93
93
|
IaC_PID=$!
|
|
@@ -97,10 +97,10 @@ wait $SAST_PID $SECRETS_PID $SCA_PID $IaC_PID 2>/dev/null || true
|
|
|
97
97
|
|
|
98
98
|
# -- COVERAGE --
|
|
99
99
|
COVERAGE_THRESHOLD=$(safe_jq '.coverage.line_min' "$CONFIG" 80)
|
|
100
|
-
if [ -f "$REPO_ROOT/coverage/coverage-summary.json" ]; then
|
|
100
|
+
if [[ -f "$REPO_ROOT/coverage/coverage-summary.json" ]]; then
|
|
101
101
|
COVERAGE=$(safe_jq '.total.lines.pct' "$REPO_ROOT/coverage/coverage-summary.json" 100)
|
|
102
102
|
BELOW=$(echo "$COVERAGE < $COVERAGE_THRESHOLD" | bc -l 2>/dev/null || echo 0)
|
|
103
|
-
[ "$BELOW"
|
|
103
|
+
[[ "$BELOW" == "1" ]] && GATE_WARNINGS+=("COVERAGE: ${COVERAGE}% below threshold ${COVERAGE_THRESHOLD}%")
|
|
104
104
|
echo " Coverage: ${COVERAGE}% (threshold: ${COVERAGE_THRESHOLD}%)"
|
|
105
105
|
fi
|
|
106
106
|
|
|
@@ -108,12 +108,12 @@ fi
|
|
|
108
108
|
echo ""
|
|
109
109
|
echo "------------------------"
|
|
110
110
|
|
|
111
|
-
if [ ${#GATE_WARNINGS[@]} -gt 0 ]; then
|
|
111
|
+
if [[ ${#GATE_WARNINGS[@]} -gt 0 ]]; then
|
|
112
112
|
echo "Warnings:"
|
|
113
113
|
for w in "${GATE_WARNINGS[@]}"; do echo " $w"; done
|
|
114
114
|
fi
|
|
115
115
|
|
|
116
|
-
if [ ${#GATE_FAILURES[@]} -gt 0 ]; then
|
|
116
|
+
if [[ ${#GATE_FAILURES[@]} -gt 0 ]]; then
|
|
117
117
|
echo "Gate BLOCKED:"
|
|
118
118
|
for f in "${GATE_FAILURES[@]}"; do echo " $f"; done
|
|
119
119
|
echo ""
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/bin/bash
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
2
|
set -euo pipefail
|
|
3
3
|
|
|
4
4
|
echo "Removing code-quality kit hooks..."
|
|
@@ -6,8 +6,8 @@ echo "Removing code-quality kit hooks..."
|
|
|
6
6
|
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || echo ".")
|
|
7
7
|
HOOKS_DIR="$REPO_ROOT/.git/hooks"
|
|
8
8
|
|
|
9
|
-
[ -f "$HOOKS_DIR/pre-push" ] && rm "$HOOKS_DIR/pre-push" && echo " pre-push hook removed"
|
|
10
|
-
[ -f "$HOOKS_DIR/post-commit" ] && rm "$HOOKS_DIR/post-commit" && echo " post-commit hook removed"
|
|
9
|
+
[[ -f "$HOOKS_DIR/pre-push" ]] && rm "$HOOKS_DIR/pre-push" && echo " pre-push hook removed"
|
|
10
|
+
[[ -f "$HOOKS_DIR/post-commit" ]] && rm "$HOOKS_DIR/post-commit" && echo " post-commit hook removed"
|
|
11
11
|
|
|
12
12
|
echo ""
|
|
13
13
|
echo "Note: CLI tools (opengrep, trufflehog, osv-scanner, checkov) are system-level"
|
package/kits/data/install.sh
CHANGED
package/kits/data/teardown.sh
CHANGED
package/kits/security/install.sh
CHANGED
package/package.json
CHANGED
package/scripts/health-check.sh
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/bin/bash
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
2
|
set -euo pipefail
|
|
3
3
|
|
|
4
4
|
# ════════════════════════════════════════════════════════════════
|
|
@@ -16,23 +16,29 @@ FAIL=0
|
|
|
16
16
|
TOTAL=0
|
|
17
17
|
|
|
18
18
|
check() {
|
|
19
|
+
local label="$2"
|
|
19
20
|
TOTAL=$((TOTAL + 1))
|
|
20
|
-
if
|
|
21
|
-
echo " ✓ $
|
|
21
|
+
if "$@" 2>/dev/null; then
|
|
22
|
+
echo " ✓ $label"
|
|
22
23
|
PASS=$((PASS + 1))
|
|
23
24
|
else
|
|
24
|
-
echo " ✗ $
|
|
25
|
+
echo " ✗ $label"
|
|
25
26
|
FAIL=$((FAIL + 1))
|
|
26
27
|
fi
|
|
27
28
|
}
|
|
28
29
|
|
|
30
|
+
check_exists() { [[ -e "$1" ]]; }
|
|
31
|
+
check_file() { [[ -f "$1" ]]; }
|
|
32
|
+
check_dir() { [[ -d "$1" ]]; }
|
|
33
|
+
check_cmd() { command -v "$1" &>/dev/null; }
|
|
34
|
+
|
|
29
35
|
echo "Praxis Health Check"
|
|
30
36
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
31
37
|
|
|
32
38
|
# ─── CLAUDE.md symlink ───
|
|
33
39
|
echo ""
|
|
34
40
|
echo "Core:"
|
|
35
|
-
check "
|
|
41
|
+
check check_exists "$CLAUDE_DIR/CLAUDE.md" "CLAUDE.md installed"
|
|
36
42
|
|
|
37
43
|
# ─── Rules symlinks ───
|
|
38
44
|
echo ""
|
|
@@ -41,7 +47,7 @@ if [[ -d "$PRAXIS_DIR/base/rules" ]]; then
|
|
|
41
47
|
for rule in "$PRAXIS_DIR"/base/rules/*.md; do
|
|
42
48
|
[[ -f "$rule" ]] || continue
|
|
43
49
|
fname=$(basename "$rule")
|
|
44
|
-
check "
|
|
50
|
+
check check_exists "$CLAUDE_DIR/rules/$fname" "rules/$fname installed"
|
|
45
51
|
done
|
|
46
52
|
fi
|
|
47
53
|
|
|
@@ -52,7 +58,7 @@ if [[ -d "$PRAXIS_DIR/base/commands" ]]; then
|
|
|
52
58
|
for cmd in "$PRAXIS_DIR"/base/commands/*.md; do
|
|
53
59
|
[[ -f "$cmd" ]] || continue
|
|
54
60
|
fname=$(basename "$cmd")
|
|
55
|
-
check "
|
|
61
|
+
check check_exists "$CLAUDE_DIR/commands/$fname" "commands/$fname installed"
|
|
56
62
|
done
|
|
57
63
|
fi
|
|
58
64
|
|
|
@@ -63,24 +69,24 @@ if [[ -d "$PRAXIS_DIR/base/skills" ]]; then
|
|
|
63
69
|
for skill_dir in "$PRAXIS_DIR"/base/skills/*/; do
|
|
64
70
|
[[ -d "$skill_dir" ]] || continue
|
|
65
71
|
skill_name=$(basename "$skill_dir")
|
|
66
|
-
check "
|
|
72
|
+
check check_exists "$CLAUDE_DIR/skills/$skill_name" "skills/$skill_name installed"
|
|
67
73
|
done
|
|
68
74
|
fi
|
|
69
75
|
|
|
70
76
|
# ─── Kits symlink ───
|
|
71
77
|
echo ""
|
|
72
78
|
echo "Kits:"
|
|
73
|
-
check "
|
|
79
|
+
check check_exists "$CLAUDE_DIR/kits" "kits directory installed"
|
|
74
80
|
|
|
75
81
|
# ─── Config ───
|
|
76
82
|
echo ""
|
|
77
83
|
echo "Config:"
|
|
78
|
-
check "
|
|
84
|
+
check check_file "$CONFIG_FILE" "praxis.config.json exists"
|
|
79
85
|
|
|
80
86
|
if [[ -f "$CONFIG_FILE" ]]; then
|
|
81
87
|
VAULT_PATH=$(jq -r '.vault_path // empty' "$CONFIG_FILE" 2>/dev/null)
|
|
82
88
|
if [[ -n "$VAULT_PATH" ]]; then
|
|
83
|
-
check "
|
|
89
|
+
check check_dir "$VAULT_PATH" "vault_path ($VAULT_PATH) is a real directory"
|
|
84
90
|
else
|
|
85
91
|
TOTAL=$((TOTAL + 1))
|
|
86
92
|
echo " ✗ vault_path not set in config"
|
|
@@ -91,10 +97,10 @@ fi
|
|
|
91
97
|
# ─── Required tools ───
|
|
92
98
|
echo ""
|
|
93
99
|
echo "Tools:"
|
|
94
|
-
check
|
|
95
|
-
check
|
|
96
|
-
check
|
|
97
|
-
check
|
|
100
|
+
check check_cmd obsidian "Obsidian CLI available"
|
|
101
|
+
check check_cmd node "node available"
|
|
102
|
+
check check_cmd claude "claude available"
|
|
103
|
+
check check_cmd jq "jq available"
|
|
98
104
|
|
|
99
105
|
# ─── MCP Servers (warn only) ───
|
|
100
106
|
echo ""
|
package/scripts/install-tools.sh
CHANGED
|
@@ -17,7 +17,7 @@ for arg in "$@"; do
|
|
|
17
17
|
done
|
|
18
18
|
|
|
19
19
|
# Auto-detect if no flags
|
|
20
|
-
if [ $# -eq 0 ]; then
|
|
20
|
+
if [[ $# -eq 0 ]]; then
|
|
21
21
|
command -v go &>/dev/null && INSTALL_GO=true
|
|
22
22
|
command -v terraform &>/dev/null && INSTALL_TF=true
|
|
23
23
|
fi
|
|
@@ -43,7 +43,7 @@ install_go() { go install "$@" 2>/dev/null || true; }
|
|
|
43
43
|
|
|
44
44
|
# ── Core (always) ──
|
|
45
45
|
echo "── Installing core tools ──"
|
|
46
|
-
if [ "$PKG"
|
|
46
|
+
if [[ "$PKG" == "brew" ]]; then
|
|
47
47
|
install_brew shellcheck shfmt jq gitleaks
|
|
48
48
|
else
|
|
49
49
|
sudo apt-get update -qq
|
|
@@ -60,7 +60,7 @@ if $INSTALL_GO; then
|
|
|
60
60
|
echo "── Installing Go quality tools ──"
|
|
61
61
|
install_go golang.org/x/tools/cmd/goimports@latest
|
|
62
62
|
install_go golang.org/x/vuln/cmd/govulncheck@latest
|
|
63
|
-
if [ "$PKG"
|
|
63
|
+
if [[ "$PKG" == "brew" ]]; then
|
|
64
64
|
install_brew golangci-lint
|
|
65
65
|
else
|
|
66
66
|
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b "$(go env GOPATH)/bin" 2>/dev/null || true
|
|
@@ -71,7 +71,7 @@ fi
|
|
|
71
71
|
if $INSTALL_TF; then
|
|
72
72
|
echo ""
|
|
73
73
|
echo "── Installing Terraform quality tools ──"
|
|
74
|
-
if [ "$PKG"
|
|
74
|
+
if [[ "$PKG" == "brew" ]]; then
|
|
75
75
|
install_brew tflint trivy infracost
|
|
76
76
|
else
|
|
77
77
|
echo "NOTE: Install tflint, trivy, infracost manually for Linux"
|
|
@@ -82,7 +82,7 @@ fi
|
|
|
82
82
|
if command -v docker &>/dev/null; then
|
|
83
83
|
echo ""
|
|
84
84
|
echo "── Installing container tools ──"
|
|
85
|
-
if [ "$PKG"
|
|
85
|
+
if [[ "$PKG" == "brew" ]]; then
|
|
86
86
|
install_brew hadolint
|
|
87
87
|
fi
|
|
88
88
|
fi
|
package/scripts/lint-harness.sh
CHANGED
package/scripts/onboard-mcp.sh
CHANGED
package/scripts/test-harness.sh
CHANGED
package/scripts/update.sh
CHANGED