@esoteric-logic/praxis-harness 2.3.1 → 2.4.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.
Files changed (35) hide show
  1. package/base/CLAUDE.md +4 -0
  2. package/base/configs/linters/.editorconfig +29 -0
  3. package/base/configs/linters/.golangci.yml +63 -0
  4. package/base/configs/linters/.hadolint.yaml +7 -0
  5. package/base/configs/linters/.shellcheckrc +4 -0
  6. package/base/configs/linters/.tflint.hcl +30 -0
  7. package/base/configs/linters/commitlint.config.js +10 -0
  8. package/base/configs/vale/.vale.ini +16 -0
  9. package/base/configs/vale/Praxis/AISlop.yml +90 -0
  10. package/base/configs/vale/Praxis/CopulaAvoidance.yml +22 -0
  11. package/base/configs/vale/Praxis/ElegantVariation.yml +14 -0
  12. package/base/configs/vale/Praxis/Hedging.yml +22 -0
  13. package/base/configs/vale/Praxis/NaturalVoice.yml +85 -0
  14. package/base/configs/vale/Praxis/Precision.yml +60 -0
  15. package/base/hooks/file-guard.sh +53 -0
  16. package/base/hooks/post-session-lint.sh +5 -0
  17. package/base/hooks/quality-check.sh +165 -0
  18. package/base/hooks/settings-hooks.json +14 -1
  19. package/base/hooks/vault-checkpoint.sh +25 -0
  20. package/base/rules/coding.md +23 -0
  21. package/base/rules/context-management.md +2 -0
  22. package/base/rules/terraform.md +10 -0
  23. package/base/skills/execute/SKILL.md +15 -0
  24. package/base/skills/plan/SKILL.md +16 -0
  25. package/base/skills/pre-commit-lint/SKILL.md +21 -1
  26. package/base/skills/repair/SKILL.md +7 -0
  27. package/base/skills/scaffold-new/SKILL.md +40 -0
  28. package/base/skills/scaffold-new/references/repo-CLAUDE-md-template.md +35 -0
  29. package/base/skills/ship/SKILL.md +6 -0
  30. package/base/skills/verify/SKILL.md +16 -5
  31. package/bin/praxis.js +19 -0
  32. package/package.json +1 -1
  33. package/scripts/install-tools.sh +137 -0
  34. package/scripts/lint-harness.sh +2 -1
  35. package/scripts/test-harness.sh +87 -0
package/base/CLAUDE.md CHANGED
@@ -103,6 +103,10 @@ Missing servers are non-blocking — features degrade gracefully.
103
103
  - Git operation → `~/.claude/rules/git-workflow.md`
104
104
  - Client-facing writing → auto-loaded by `communication-standards` skill
105
105
  - Architecture/specs → auto-loaded by `architecture-patterns` skill
106
+ 5. Quality re-anchor: read most recent `compact-checkpoint.md` → check the Quality State section.
107
+ - If lint findings existed before compaction: re-run `golangci-lint run`, confirm status.
108
+ - If tests were failing before compaction: re-run test command, confirm status.
109
+ - Do NOT assume pre-compaction state is current. Always re-run fresh.
106
110
 
107
111
  ## Core Anti-Patterns (NEVER)
108
112
  - Silently swallow errors or use empty catch blocks
@@ -0,0 +1,29 @@
1
+ root = true
2
+
3
+ [*]
4
+ charset = utf-8
5
+ end_of_line = lf
6
+ insert_final_newline = true
7
+ trim_trailing_whitespace = true
8
+
9
+ [*.{yml,yaml,json,tf,tfvars,md,toml,bicep}]
10
+ indent_style = space
11
+ indent_size = 2
12
+
13
+ [*.py]
14
+ indent_style = space
15
+ indent_size = 4
16
+
17
+ [*.go]
18
+ indent_style = tab
19
+
20
+ [Makefile]
21
+ indent_style = tab
22
+
23
+ [*.{sh,bash}]
24
+ indent_style = space
25
+ indent_size = 2
26
+
27
+ [*.ps1]
28
+ indent_style = space
29
+ indent_size = 4
@@ -0,0 +1,63 @@
1
+ run:
2
+ timeout: 3m
3
+ modules-download-mode: readonly
4
+
5
+ linters:
6
+ enable:
7
+ # Error handling
8
+ - errcheck
9
+ - errchkjson
10
+ - nilerr
11
+ - wrapcheck
12
+ - errorlint
13
+ # Logic & correctness
14
+ - govet
15
+ - staticcheck
16
+ - exhaustive
17
+ - nilnil
18
+ - copyloopvar
19
+ - bodyclose
20
+ - sqlclosecheck
21
+ # Security
22
+ - gosec
23
+ # Maintainability
24
+ - dupl
25
+ - goconst
26
+ - funlen
27
+ - gocognit
28
+ - unused
29
+ - ineffassign
30
+ - unconvert
31
+ - misspell
32
+ - goimports
33
+ - gosimple
34
+ - revive
35
+ disable:
36
+ - depguard
37
+
38
+ linters-settings:
39
+ funlen:
40
+ lines: 60
41
+ statements: 40
42
+ gocognit:
43
+ min-complexity: 20
44
+ dupl:
45
+ threshold: 100
46
+ goconst:
47
+ min-len: 3
48
+ min-occurrences: 3
49
+ errcheck:
50
+ check-type-assertions: true
51
+ revive:
52
+ rules:
53
+ - name: exported
54
+ disabled: false
55
+ - name: unexported-return
56
+ disabled: false
57
+ - name: blank-imports
58
+ disabled: false
59
+
60
+ issues:
61
+ max-issues-per-linter: 50
62
+ max-same-issues: 5
63
+ exclude-use-default: false
@@ -0,0 +1,7 @@
1
+ ignored:
2
+ - DL3003
3
+ trustedRegistries:
4
+ - docker.io
5
+ - mcr.microsoft.com
6
+ - ghcr.io
7
+ strict-labels: true
@@ -0,0 +1,4 @@
1
+ shell=bash
2
+ enable=all
3
+ # Suppress "not following sourced file" in hook context
4
+ disable=SC1091
@@ -0,0 +1,30 @@
1
+ plugin "azurerm" {
2
+ enabled = true
3
+ version = "0.27.0"
4
+ source = "github.com/terraform-linters/tflint-ruleset-azurerm"
5
+ }
6
+
7
+ rule "terraform_naming_convention" {
8
+ enabled = true
9
+ format = "snake_case"
10
+ }
11
+
12
+ rule "terraform_documented_variables" {
13
+ enabled = true
14
+ }
15
+
16
+ rule "terraform_documented_outputs" {
17
+ enabled = true
18
+ }
19
+
20
+ rule "terraform_unused_declarations" {
21
+ enabled = true
22
+ }
23
+
24
+ rule "terraform_typed_variables" {
25
+ enabled = true
26
+ }
27
+
28
+ rule "terraform_standard_module_structure" {
29
+ enabled = true
30
+ }
@@ -0,0 +1,10 @@
1
+ module.exports = {
2
+ extends: ['@commitlint/config-conventional'],
3
+ rules: {
4
+ 'type-enum': [2, 'always', ['feat', 'fix', 'refactor', 'test', 'docs', 'chore', 'ci', 'perf', 'style', 'build', 'revert']],
5
+ 'scope-empty': [1, 'never'],
6
+ 'subject-max-length': [2, 'always', 72],
7
+ 'body-max-line-length': [2, 'always', 100],
8
+ 'subject-case': [2, 'always', 'lower-case'],
9
+ }
10
+ };
@@ -0,0 +1,16 @@
1
+ StylesPath = .vale-styles
2
+ MinAlertLevel = suggestion
3
+
4
+ Packages = Microsoft, write-good, Readability
5
+
6
+ # Full suite on Markdown
7
+ [*.md]
8
+ BasedOnStyles = Praxis, Microsoft, write-good, Readability
9
+
10
+ # Comment-only scanning on code files
11
+ [*.{go,tf,sh,ps1}]
12
+ BasedOnStyles = Praxis
13
+
14
+ # Praxis rules only on YAML
15
+ [*.{yml,yaml}]
16
+ BasedOnStyles = Praxis
@@ -0,0 +1,90 @@
1
+ extends: substitution
2
+ message: "AI vocabulary detected: '%s' — rephrase in plain language."
3
+ level: warning
4
+ ignorecase: true
5
+ swap:
6
+ delve: "examine, explore, investigate"
7
+ tapestry: "combination, mix"
8
+ multifaceted: "complex, varied"
9
+ leverage: "use"
10
+ paradigm: "model, approach"
11
+ synergy: "collaboration, combination"
12
+ holistic: "complete, whole"
13
+ robust: "strong, reliable"
14
+ seamless: "smooth"
15
+ cutting-edge: "modern, latest"
16
+ game-changer: "improvement, breakthrough"
17
+ deep dive: "detailed look, analysis"
18
+ unpack: "explain, examine"
19
+ landscape: "field, area, environment"
20
+ ecosystem: "system, environment"
21
+ streamline: "simplify"
22
+ spearhead: "lead"
23
+ groundbreaking: "new, innovative"
24
+ transformative: "significant"
25
+ empower: "enable, help"
26
+ reimagine: "rethink, redesign"
27
+ cornerstone: "foundation, basis"
28
+ pivotal: "important, key"
29
+ catalyst: "trigger, cause"
30
+ navigate: "manage, handle"
31
+ harness: "use"
32
+ unlock: "enable, reveal"
33
+ bolster: "strengthen, support"
34
+ underscore: "highlight, emphasize"
35
+ illuminate: "explain, clarify"
36
+ forge: "build, create"
37
+ foster: "encourage, develop"
38
+ cultivate: "develop, build"
39
+ paramount: "important, critical"
40
+ meticulous: "careful, thorough"
41
+ intricate: "complex, detailed"
42
+ nuanced: "subtle"
43
+ comprehensive: "complete, thorough"
44
+ invaluable: "very useful, essential"
45
+ instrumental: "important, helpful"
46
+ embark: "start, begin"
47
+ endeavor: "effort, attempt"
48
+ realm: "area, field"
49
+ facet: "aspect, part"
50
+ Moreover: "Also, Additionally"
51
+ Furthermore: "Also"
52
+ Notably: "Note that"
53
+ Importantly: "Note"
54
+ Essentially: "(omit or rewrite)"
55
+ Fundamentally: "(omit or rewrite)"
56
+ Undoubtedly: "(omit or rewrite)"
57
+ Interestingly: "(omit or rewrite)"
58
+ testament: "proof, evidence"
59
+ beacon: "example, guide"
60
+ resonate: "connect, appeal"
61
+ bespoke: "custom"
62
+ elevate: "improve, raise"
63
+ amplify: "increase, strengthen"
64
+ augment: "add to, supplement"
65
+ myriad: "many"
66
+ plethora: "many, excess"
67
+ burgeoning: "growing"
68
+ nascent: "new, early"
69
+ advent: "arrival, start"
70
+ proliferation: "spread, growth"
71
+ propel: "drive, push"
72
+ overarching: "main, overall"
73
+ dovetail: "fit, align"
74
+ tailored: "custom, specific"
75
+ juxtapose: "compare, contrast"
76
+ dichotomy: "contrast, split"
77
+ eponymous: "named after"
78
+ erstwhile: "former"
79
+ zeitgeist: "spirit of the time"
80
+ ethos: "values, character"
81
+ nexus: "connection, link"
82
+ crucible: "test, trial"
83
+ vanguard: "forefront, leading edge"
84
+ linchpin: "key element"
85
+ bedrock: "foundation"
86
+ scaffolding: "framework, structure"
87
+ underpinning: "basis, foundation"
88
+ bulwark: "defense, safeguard"
89
+ bastion: "stronghold"
90
+ harbinger: "sign, indicator"
@@ -0,0 +1,22 @@
1
+ extends: existence
2
+ message: "Inflated copula: '%s' — simplify."
3
+ level: suggestion
4
+ ignorecase: true
5
+ tokens:
6
+ - "serves as a"
7
+ - "acts as a"
8
+ - "functions as a"
9
+ - "plays a pivotal role"
10
+ - "plays a crucial role"
11
+ - "plays a vital role"
12
+ - "plays a key role"
13
+ - "plays an important role"
14
+ - "boasts a"
15
+ - "represents a"
16
+ - "constitutes a"
17
+ - "comprises a"
18
+ - "stands as a"
19
+ - "remains a"
20
+ - "proves to be"
21
+ - "turns out to be"
22
+ - "happens to be"
@@ -0,0 +1,14 @@
1
+ extends: existence
2
+ message: "Elegant variation: '%s' — use the plain term."
3
+ level: suggestion
4
+ ignorecase: true
5
+ tokens:
6
+ - "the aforementioned"
7
+ - "the above-mentioned"
8
+ - "the previously mentioned"
9
+ - "this individual"
10
+ - "said individual"
11
+ - "the eponymous"
12
+ - "this entity"
13
+ - "the latter"
14
+ - "the former"
@@ -0,0 +1,22 @@
1
+ extends: existence
2
+ message: "Hedging detected: '%s' — commit to a position or remove."
3
+ level: suggestion
4
+ ignorecase: true
5
+ tokens:
6
+ - "it could potentially"
7
+ - "it might potentially"
8
+ - "it may potentially"
9
+ - "arguably"
10
+ - "it remains to be seen"
11
+ - "only time will tell"
12
+ - "it is not unreasonable to"
13
+ - "one could argue"
14
+ - "some might say"
15
+ - "it would not be wrong to"
16
+ - "to some extent"
17
+ - "to a certain degree"
18
+ - "in some ways"
19
+ - "more or less"
20
+ - "for the most part"
21
+ - "by and large"
22
+ - "generally speaking"
@@ -0,0 +1,85 @@
1
+ extends: existence
2
+ message: "AI phrasing detected: '%s' — rewrite in your natural voice."
3
+ level: warning
4
+ ignorecase: true
5
+ tokens:
6
+ # Exhausted openers
7
+ - "In today's"
8
+ - "In the realm of"
9
+ - "In an era of"
10
+ - "In the world of"
11
+ - "When it comes to"
12
+ - "It's worth noting that"
13
+ - "It's important to note"
14
+ - "It bears mentioning"
15
+ - "It goes without saying"
16
+ - "Needless to say"
17
+ - "As we all know"
18
+ - "At the end of the day"
19
+ - "Let's face it"
20
+ - "The fact of the matter is"
21
+ - "The bottom line is"
22
+ - "The reality is"
23
+ - "The truth is"
24
+ - "The thing is"
25
+ # Sycophantic filler
26
+ - "That's a great question"
27
+ - "That's an excellent question"
28
+ - "Great question"
29
+ - "Excellent question"
30
+ - "What a great"
31
+ - "Absolutely"
32
+ - "That's a fantastic"
33
+ # Filler transitions
34
+ - "With that being said"
35
+ - "Having said that"
36
+ - "That said"
37
+ - "On that note"
38
+ - "Moving forward"
39
+ - "Going forward"
40
+ - "Looking ahead"
41
+ - "To that end"
42
+ - "In light of this"
43
+ - "In light of the above"
44
+ - "With this in mind"
45
+ - "Bearing this in mind"
46
+ - "Taking this into account"
47
+ - "With the above in mind"
48
+ # Performative exploration
49
+ - "Let's explore"
50
+ - "Let's delve"
51
+ - "Let's unpack"
52
+ - "Let's dive into"
53
+ - "Let's take a closer look"
54
+ - "Let's examine"
55
+ - "shall we explore"
56
+ - "shall we delve"
57
+ # Filler conclusions
58
+ - "In conclusion"
59
+ - "To sum up"
60
+ - "To summarize"
61
+ - "In summary"
62
+ - "All in all"
63
+ - "By and large"
64
+ - "On the whole"
65
+ - "When all is said and done"
66
+ # Performative framing
67
+ - "It's crucial to"
68
+ - "It's essential to"
69
+ - "It's vital to"
70
+ - "It's imperative to"
71
+ - "play a crucial role"
72
+ - "play a vital role"
73
+ - "play a pivotal role"
74
+ - "play an important role"
75
+ - "serves as a testament"
76
+ - "serves as a reminder"
77
+ - "serves as a beacon"
78
+ # Unnecessary hedging stacks
79
+ - "might potentially"
80
+ - "could potentially"
81
+ - "may potentially"
82
+ - "would potentially"
83
+ - "seems to suggest"
84
+ - "appears to indicate"
85
+ - "tends to suggest"
@@ -0,0 +1,60 @@
1
+ extends: existence
2
+ message: "Vague word: '%s' — be specific."
3
+ level: suggestion
4
+ ignorecase: true
5
+ tokens:
6
+ - "various"
7
+ - "several"
8
+ - "numerous"
9
+ - "a number of"
10
+ - "a wide range of"
11
+ - "a broad range of"
12
+ - "a variety of"
13
+ - "wide array of"
14
+ - "enables"
15
+ - "facilitates"
16
+ - "utilizes"
17
+ - "utilize"
18
+ - "leverages"
19
+ - "comprehensive solution"
20
+ - "innovative solution"
21
+ - "scalable solution"
22
+ - "world-class"
23
+ - "best-in-class"
24
+ - "state-of-the-art"
25
+ - "end-to-end"
26
+ - "full-stack"
27
+ - "next-generation"
28
+ - "enterprise-grade"
29
+ - "mission-critical"
30
+ - "production-ready"
31
+ - "battle-tested"
32
+ - "highly scalable"
33
+ - "highly available"
34
+ - "highly performant"
35
+ - "best practices"
36
+ - "industry standard"
37
+ - "gold standard"
38
+ - "significant"
39
+ - "meaningful"
40
+ - "impactful"
41
+ - "thoughtful"
42
+ - "intentional"
43
+ - "robust"
44
+ - "performant"
45
+ - "elegant"
46
+ - "powerful"
47
+ - "flexible"
48
+ - "extensible"
49
+ - "modular"
50
+ - "opinionated"
51
+ - "batteries-included"
52
+ - "turnkey"
53
+ - "frictionless"
54
+ - "effortless"
55
+ - "painless"
56
+ - "blazing fast"
57
+ - "lightning fast"
58
+ - "blazingly fast"
59
+ - "extremely fast"
60
+ - "incredibly fast"
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env bash
2
+ # file-guard.sh — PreToolUse hook
3
+ # Blocks writes to protected paths. Exit 2 = hard block.
4
+ set -euo pipefail
5
+
6
+ INPUT=$(cat)
7
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // empty')
8
+
9
+ if [ -z "$FILE_PATH" ]; then
10
+ exit 0
11
+ fi
12
+
13
+ # Default protected patterns
14
+ PROTECTED_PATTERNS=(
15
+ "go\.sum$"
16
+ "go\.mod$"
17
+ "\.lock$"
18
+ "\.lock\.json$"
19
+ "\.github/workflows/"
20
+ "^\.claude/"
21
+ )
22
+
23
+ # Check against protected patterns
24
+ for pattern in "${PROTECTED_PATTERNS[@]}"; do
25
+ if echo "$FILE_PATH" | grep -qE "$pattern"; then
26
+ echo "BLOCKED: $FILE_PATH is protected. Explain the intended change before proceeding."
27
+ exit 2
28
+ fi
29
+ done
30
+
31
+ # Check project-level protected files from CLAUDE.md if it exists
32
+ if [ -f "CLAUDE.md" ]; then
33
+ # Extract paths from ## Protected Files section
34
+ IN_SECTION=false
35
+ while IFS= read -r line; do
36
+ if echo "$line" | grep -qE "^## Protected Files"; then
37
+ IN_SECTION=true
38
+ continue
39
+ fi
40
+ if $IN_SECTION && echo "$line" | grep -qE "^##"; then
41
+ break
42
+ fi
43
+ if $IN_SECTION && echo "$line" | grep -qE "^- "; then
44
+ PROTECTED=$(echo "$line" | sed 's/^- //' | sed 's/ *#.*//' | xargs)
45
+ if [ -n "$PROTECTED" ] && echo "$FILE_PATH" | grep -qE "$PROTECTED"; then
46
+ echo "BLOCKED: $FILE_PATH matches project-protected pattern '$PROTECTED'. Explain the intended change."
47
+ exit 2
48
+ fi
49
+ fi
50
+ done < CLAUDE.md
51
+ fi
52
+
53
+ exit 0
@@ -3,6 +3,11 @@
3
3
  # Always exits 0 (never blocks session end).
4
4
  set -uo pipefail
5
5
 
6
+ INPUT=$(cat)
7
+ if [ "$(echo "$INPUT" | jq -r '.stop_hook_active // false')" = "true" ]; then
8
+ exit 0
9
+ fi
10
+
6
11
  CONFIG_FILE="$HOME/.claude/praxis.config.json"
7
12
 
8
13
  # Find project CLAUDE.md by walking up from CWD