torusguard 0.9.4 → 0.9.5

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.
@@ -8,7 +8,7 @@
8
8
  "agents/validator.md": "79fc4431de5c5507f8730aee6c5c3e61fd238cbf8cf8c7c6aac462eee9761ed6",
9
9
  "config/scope.json": "b198a86186b4c6d5e1af516bf4e3a6afa8878e622ca1d57a5bf72d294f8c6f25",
10
10
  "config/slash-commands.json": "5390f0d26f8117a62e56c58147d3a0d2deab1a20956302b212703281d13fa84e",
11
- "config/torusguard.json": "218eeae10b538aca9b548d1b756d7d4f91a5b624e0bce07533f0c187860586e6",
11
+ "config/torusguard.json": "077bc6a948f9420aded8dba248577ff3ebf054cab64cf538a7a6d05223fe27bc",
12
12
  "references/django-security.md": "a15b7eb11b51dd1970d3d65544cf79ebea91fb99dc0e085e58a56532a718dce7",
13
13
  "references/drf-security.md": "c7a7af3acaef895bf4798590acc88b3a2e9831a49eb2d23b4d8f31540ab264cc",
14
14
  "references/express-security.md": "dff1db15e614d29d8c272f9da345b418077e62dc883fe210c7a50c552c76493f",
@@ -40,7 +40,7 @@
40
40
  "scripts/safety_gate.py": "3379b7534b2590cf563717a448983ad8ed7e8f174f0ad65683d33e8a10f51558",
41
41
  "scripts/sarif_exporter.py": "35c66637413afc4b72d5bd426638447c77231d2a8594dce5addceffd4803a20d",
42
42
  "scripts/stack_detect.py": "99b7bdf9829d58ff5b8c59afd6e8b6429bbb11d830ac73dec491101cbbc41574",
43
- "skills/torusguard/SKILL.md": "5282a9e73c2faad97f079ff527def34b96709615c0dd297fe9b1bb2894f03e20",
43
+ "skills/torusguard/SKILL.md": "31a115886ffb115f2b975c4d0670e780e11ea68201559b24b20d0d0ef456058f",
44
44
  "skills/torusguard/bootstrap.py": "7e348065a622089ab1d51e9bf4864e5b0022aaee1ccb2ecbf7057c14e792e2c7",
45
45
  "skills/torusguard/references/auth-and-sessions.md": "34c2843f8c0dbe3574e54f00a39a92a1f431527ec5f69b2d64c84240d424a39e",
46
46
  "skills/torusguard/references/business-logic-and-abuse.md": "0d6088936bc1a01023070332fccef0f2e0734358a5119379055f3d2895c22567",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "../schemas/torusguard-config.schema.json",
3
- "version": "0.9.4",
3
+ "version": "0.9.5",
4
4
  "product": "TorusGuard Security Skill Kit",
5
5
  "severity_threshold": "medium",
6
6
  "auto_detect_stack": true,
@@ -1,23 +1,27 @@
1
1
  ---
2
2
  name: torusguard
3
- description: Security guardrails, governed remediation, and authorized runtime validation for AI-built web applications across Python and TypeScript.
4
- version: 0.9.4
3
+ description: "Autonomous security engine: 71 rules across 11 families, governed remediation (Ponytail Protocol), SARIF v2.1.0 exports, and 5-agent authority separation for Python & TypeScript web applications."
4
+ version: 0.9.5
5
5
  ---
6
6
 
7
- # TorusGuard Master Router
7
+ # TorusGuard Master Security Router
8
8
 
9
- **Principle:** If the browser receives it, users can inspect it. Keep secrets, direct database access, and authorization on trusted server-side code.
9
+ **Principle:** If the browser receives it, users can inspect it. Keep secrets, database queries, and authorization strictly on trusted server-side code.
10
10
 
11
11
  ---
12
12
 
13
13
  ## ⚡ Workspace Bootstrap Check
14
- 1. **If `.torusguard/` exists:** Load matching specialist skill on demand per command.
15
- 2. **If `.torusguard/` is missing:** Run `python skills/torusguard/bootstrap.py --target .` or `/torusguard init`.
14
+ 1. **If `.torusguard/` exists on disk:** Full governance active. Route slash commands to local specialist workflows below.
15
+ 2. **If `.torusguard/` is absent (Autonomous AI Mode):** Operates standalone in any AI agent (Kimi, Antigravity, VS Code, Cursor). Apply in-memory security invariants:
16
+ - Server-side auth & tenant scoping (`.filter(tenant=...)`).
17
+ - Zero client-side secrets (`SUPABASE_SERVICE_ROLE_KEY`, live API keys).
18
+ - Ponytail Protocol patch limits ($\le 35$ additions, $\le 25$ deletions).
19
+ - *Upgrade:* Run `npx torusguard init` to unlock local `.torusguard/` run tracking & individual commands.
16
20
 
17
21
  ---
18
22
 
19
23
  ## Specialist Skill Routing (Lazy Loading)
20
- Load **only** the designated sub-skill when a slash command is executed to maintain strict 1,000–1,500 token budget:
24
+ Load **only** the designated sub-skill on demand to preserve the 1,000–1,500 token budget:
21
25
 
22
26
  | Command | Specialist Skill | Agent |
23
27
  | :--- | :--- | :--- |
package/README.md CHANGED
@@ -1,12 +1,13 @@
1
1
  <div align="center">
2
- <img src="TorusGuard.png" alt="TorusGuard Security Banner" width="480" style="max-width: 100%; height: auto; border-radius: 8px;">
2
+ <img src="https://raw.githubusercontent.com/githubmofo/TorusGuard/main/TorusGuard.png" alt="TorusGuard Security Banner" width="480" style="max-width: 100%; height: auto; border-radius: 8px;">
3
3
 
4
4
  # TorusGuard
5
5
 
6
6
  **Autonomous Security Guardrails, Governed Remediation, and Authorized Runtime Validation for AI-Built Web Applications.**
7
7
 
8
8
  [![npm version](https://img.shields.io/npm/v/torusguard.svg?style=flat-square&color=cb3837&logo=npm)](https://www.npmjs.com/package/torusguard)
9
- [![Release](https://img.shields.io/badge/Release-v0.9.4-blue.svg?style=flat-square)](https://github.com/githubmofo/TorusGuard/releases/latest)
9
+ [![GitHub Packages](https://img.shields.io/badge/GitHub%20Packages-v0.9.5-181717.svg?style=flat-square&logo=github)](https://github.com/githubmofo/TorusGuard/pkgs/npm/torusguard)
10
+ [![Release](https://img.shields.io/badge/Release-v0.9.5-blue.svg?style=flat-square)](https://github.com/githubmofo/TorusGuard/releases/latest)
10
11
  [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg?style=flat-square)](LICENSE)
11
12
  [![Python 3.10+](https://img.shields.io/badge/Python-3.10%2B-blue.svg?style=flat-square&logo=python&logoColor=white)](https://python.org)
12
13
  [![Node.js 18+](https://img.shields.io/badge/Node.js-18%2B-339933.svg?style=flat-square&logo=node.js&logoColor=white)](https://nodejs.org)
package/bin/torusguard.js CHANGED
@@ -15,14 +15,16 @@ const command = args[0] || 'init';
15
15
  const rootDir = path.resolve(__dirname, '..');
16
16
  const cwd = process.cwd();
17
17
 
18
- // ANSI Color Helpers
18
+ // ─── ANSI Color Helpers ───────────────────────────────────────────────────────
19
19
  const BOLD = '\x1b[1m';
20
+ const DIM = '\x1b[2m';
20
21
  const RESET = '\x1b[0m';
21
22
  const CYAN = '\x1b[36m';
22
23
  const GREEN = '\x1b[32m';
23
24
  const YELLOW = '\x1b[33m';
25
+ const WHITE = '\x1b[97m';
24
26
  const GRAY = '\x1b[90m';
25
- const DIM = '\x1b[2m';
27
+ const RED = '\x1b[31m';
26
28
 
27
29
  // Detect available Python binary (python or python3)
28
30
  let pythonCmd = 'python';
@@ -45,24 +47,41 @@ try {
45
47
 
46
48
  function printHelp() {
47
49
  console.log(`
48
- ${CYAN}╭──────────────────────────────────────────────────────────────────────────╮${RESET}
49
- ${CYAN}│${RESET} ${BOLD}🛡️ TORUSGUARD CLI v0.9.4${RESET} ${GRAY}[Autonomous Security Engine]${RESET} ${CYAN}│${RESET}
50
- ${CYAN}│${RESET} ${DIM}Governed Remediation & Security Guardrails for AI Web Applications${RESET} ${CYAN}│${RESET}
51
- ${CYAN}╰──────────────────────────────────────────────────────────────────────────╯${RESET}
52
-
53
- ${BOLD}Usage:${RESET}
54
- ${GREEN}npx torusguard${RESET} [command] [options]
55
-
56
- ${BOLD}Commands:${RESET}
57
- ${CYAN}init${RESET} Scaffold ${BOLD}.torusguard/${RESET} workspace and unlock all 11 slash commands
58
- ${CYAN}status${RESET} Display active security posture, configured rules, and stack
59
- ${CYAN}audit${RESET} Execute static security AST audit on target project
60
- ${CYAN}report${RESET} Export OASIS SARIF v2.1.0 security telemetry
61
- ${CYAN}help${RESET} Show this interactive command guide
62
-
63
- ${BOLD}Options:${RESET}
64
- ${GRAY}--target <dir>${RESET} Target directory to analyze or scaffold ${DIM}(default: .)${RESET}
65
- ${GRAY}--force${RESET} Overwrite existing configuration and re-scaffold templates
50
+ ${CYAN}╭─────────────────────────────────────────────────────────────────────────╮${RESET}
51
+ ${CYAN}│${RESET} ${CYAN}│${RESET}
52
+ ${CYAN}│${RESET} ${BOLD}${WHITE}🛡️ T O R U S G U A R D C L I${RESET} ${GRAY}v0.9.5${RESET} ${CYAN}│${RESET}
53
+ ${CYAN}│${RESET} ${DIM}Autonomous Security Engine for AI-Built Applications${RESET} ${CYAN}│${RESET}
54
+ ${CYAN}│${RESET} ${CYAN}│${RESET}
55
+ ${CYAN}╰─────────────────────────────────────────────────────────────────────────╯${RESET}
56
+
57
+ ${BOLD}Usage:${RESET} ${GREEN}npx torusguard${RESET} ${WHITE}[command]${RESET} ${GRAY}[options]${RESET}
58
+
59
+ ${CYAN}┌─────────────────────────────────────────────────────────────────────────┐${RESET}
60
+ ${CYAN}│${RESET} ${BOLD}Commands${RESET} ${CYAN}│${RESET}
61
+ ${CYAN}├─────────────────────────────────────────────────────────────────────────┤${RESET}
62
+ ${CYAN}│${RESET} ${GREEN}init${RESET} Scaffold ${BOLD}.torusguard/${RESET} workspace + unlock 11 slash commands ${CYAN}│${RESET}
63
+ ${CYAN}│${RESET} ${GREEN}status${RESET} Display active security posture, rules, and stack info ${CYAN}│${RESET}
64
+ ${CYAN}│${RESET} ${GREEN}audit${RESET} Run static AST security scan on the target project ${CYAN}│${RESET}
65
+ ${CYAN}│${RESET} ${GREEN}report${RESET} Export OASIS SARIF v2.1.0 structured telemetry ${CYAN}│${RESET}
66
+ ${CYAN}│${RESET} ${GREEN}help${RESET} Show this interactive command guide ${CYAN}│${RESET}
67
+ ${CYAN}├─────────────────────────────────────────────────────────────────────────┤${RESET}
68
+ ${CYAN}│${RESET} ${BOLD}Options${RESET} ${CYAN}│${RESET}
69
+ ${CYAN}├─────────────────────────────────────────────────────────────────────────┤${RESET}
70
+ ${CYAN}│${RESET} ${GRAY}--target <dir>${RESET} Target directory to analyze or scaffold ${DIM}(default: .)${RESET} ${CYAN}│${RESET}
71
+ ${CYAN}│${RESET} ${GRAY}--force${RESET} Overwrite existing workspace and re-scaffold ${CYAN}│${RESET}
72
+ ${CYAN}└─────────────────────────────────────────────────────────────────────────┘${RESET}
73
+
74
+ ${BOLD}AI Chat Commands:${RESET}
75
+ ${DIM}In your AI IDE chat, use any of these slash commands:${RESET}
76
+ ${CYAN}/torusguard${RESET} Main orchestrator (status, audit, harden, etc.)
77
+ ${CYAN}/torusguard-audit${RESET} Static AST security scan
78
+ ${CYAN}/torusguard-harden${RESET} Generate governed fix patches
79
+ ${CYAN}/torusguard-apply${RESET} Apply patches with rollback snapshots
80
+ ${CYAN}/torusguard-report${RESET} Executive security posture report
81
+ ${CYAN}/torusguard-status${RESET} Read-only workspace diagnostic
82
+
83
+ ${DIM}Documentation:${RESET} ${CYAN}https://github.com/githubmofo/TorusGuard${RESET}
84
+ ${DIM}NPM Package:${RESET} ${CYAN}https://npmjs.com/package/torusguard${RESET}
66
85
  `);
67
86
  }
68
87
 
@@ -76,28 +95,45 @@ if (command === 'status') {
76
95
  if (fs.existsSync(cfgPath)) {
77
96
  try {
78
97
  const cfg = JSON.parse(fs.readFileSync(cfgPath, 'utf-8'));
98
+ const stackLang = cfg.detected_stack?.language || 'Not yet detected';
99
+ const stackFw = cfg.detected_stack?.framework || 'Not yet detected';
100
+ const stackDb = cfg.detected_stack?.data_layer || 'Not yet detected';
101
+ const stackStatus = cfg.detected_stack ? `${GREEN}Detected${RESET}` : `${YELLOW}Pending first audit${RESET}`;
102
+
79
103
  console.log(`
80
- ${CYAN}╭──────────────────────────────────────────────────────────────────────────╮${RESET}
81
- ${CYAN}│${RESET} ${BOLD}🛡️ TORUSGUARD ACTIVE SECURITY POSTURE${RESET} ${GRAY}v0.9.4${RESET} ${CYAN}│${RESET}
82
- ${CYAN}╰──────────────────────────────────────────────────────────────────────────╯${RESET}
83
-
84
- ${BOLD}▸ Workspace Location:${RESET} ${GREEN}${cwd}${RESET}
85
- ${BOLD}▸ Governance Mode:${RESET} ${GREEN}Full Local Governance (.torusguard/)${RESET}
86
-
87
- ${BOLD} Environment & Stack:${RESET}
88
- ${GRAY}⎿ Language:${RESET} ${BOLD}${cfg.detected_stack?.language || 'TypeScript'}${RESET}
89
- ${GRAY} Framework:${RESET} ${BOLD}${cfg.detected_stack?.framework || 'None (Generic Web)'}${RESET}
90
- ${GRAY}⎿ Data Layer:${RESET} ${BOLD}${cfg.detected_stack?.data_layer || 'None'}${RESET}
91
- ${GRAY}⎿ Rules Catalog:${RESET} ${GREEN}71 Canonical Security Rules Active${RESET}
92
-
93
- ${BOLD}⏺ Governance Telemetry:${RESET}
94
- ${GRAY}⎿ Severity Floor:${RESET} ${YELLOW}${cfg.severity_threshold || 'medium'}${RESET}
95
- ${GRAY}⎿ Runs Directory:${RESET} ${CYAN}${cfg.runs_dir || '.torusguard/runs'}${RESET}
96
- ${GRAY} Ponytail Bounds:${RESET} ${GREEN}≤ 35 additions, ≤ 25 deletions${RESET}
97
-
98
- ${CYAN}╭──────────────────────────────────────────────────────────────────────────╮${RESET}
99
- ${CYAN}│${RESET} ${BOLD}💡 Quick Action:${RESET} In your AI chat, run ${CYAN}/torusguard-audit${RESET} to scan. ${CYAN}│${RESET}
100
- ${CYAN}╰──────────────────────────────────────────────────────────────────────────╯${RESET}
104
+ ${CYAN}╭─────────────────────────────────────────────────────────────────────────╮${RESET}
105
+ ${CYAN}│${RESET} ${CYAN}│${RESET}
106
+ ${CYAN}│${RESET} ${BOLD}${WHITE}🛡️ TORUSGUARD SECURITY POSTURE${RESET} ${GRAY}v0.9.5${RESET} ${CYAN}│${RESET}
107
+ ${CYAN}│${RESET} ${CYAN}│${RESET}
108
+ ${CYAN}╰─────────────────────────────────────────────────────────────────────────╯${RESET}
109
+
110
+ ${BOLD}▸ Workspace:${RESET} ${GREEN}${cwd}${RESET}
111
+ ${BOLD} Governance:${RESET} ${GREEN}Full Local Governance (.torusguard/)${RESET}
112
+
113
+ ${CYAN}┌── Environment & Stack ──────────────────────────────────────────────────┐${RESET}
114
+ ${CYAN}│${RESET} Language: ${BOLD}${stackLang}${RESET}
115
+ ${CYAN}│${RESET} Framework: ${BOLD}${stackFw}${RESET}
116
+ ${CYAN}│${RESET} Data Layer: ${BOLD}${stackDb}${RESET}
117
+ ${CYAN}│${RESET} Stack Detection: ${stackStatus}
118
+ ${CYAN}└─────────────────────────────────────────────────────────────────────────┘${RESET}
119
+
120
+ ${CYAN}┌── Governance Telemetry ─────────────────────────────────────────────────┐${RESET}
121
+ ${CYAN}│${RESET} Rules Catalog: ${GREEN}71 Canonical Security Rules${RESET} (11 families)
122
+ ${CYAN}│${RESET} Severity Floor: ${YELLOW}${cfg.severity_threshold || 'medium'}${RESET}
123
+ ${CYAN}│${RESET} Runs Directory: ${DIM}${cfg.runs_dir || '.torusguard/runs'}${RESET}
124
+ ${CYAN}│${RESET} Ponytail Bounds: ${GREEN}<= 35 additions, <= 25 deletions${RESET}
125
+ ${CYAN}└─────────────────────────────────────────────────────────────────────────┘${RESET}
126
+
127
+ ${CYAN}┌── Rule Families ────────────────────────────────────────────────────────┐${RESET}
128
+ ${CYAN}│${RESET} ${YELLOW}TG-SEC${RESET} Secrets & Credentials ${YELLOW}TG-DB${RESET} Database Safety
129
+ ${CYAN}│${RESET} ${YELLOW}TG-INPUT${RESET} Input Validation ${YELLOW}TG-AUTH${RESET} Authentication
130
+ ${CYAN}│${RESET} ${YELLOW}TG-CLIENT${RESET} Client Bundle Leaks ${YELLOW}TG-DIFF${RESET} Diff Inspection
131
+ ${CYAN}│${RESET} ${YELLOW}TG-AGENT${RESET} AI Agent Security ${YELLOW}TG-EDGE${RESET} Serverless
132
+ ${CYAN}│${RESET} ${YELLOW}TG-SUPPLY${RESET} Supply Chain & CI/CD ${YELLOW}TG-SSRF${RESET} Outbound Net
133
+ ${CYAN}│${RESET} ${YELLOW}TG-BIZ${RESET} Business Logic
134
+ ${CYAN}└─────────────────────────────────────────────────────────────────────────┘${RESET}
135
+
136
+ ${DIM}Quick Action:${RESET} In your AI chat, run ${CYAN}/torusguard-audit${RESET} to scan.
101
137
  `);
102
138
  process.exit(0);
103
139
  } catch (e) {
@@ -105,8 +141,8 @@ if (command === 'status') {
105
141
  }
106
142
  } else {
107
143
  console.log(`
108
- ${YELLOW}Notice:${RESET} No .torusguard workspace found in current directory.
109
- Run ${GREEN}npx torusguard init${RESET} to scaffold full workspace governance.
144
+ ${YELLOW}⚠${RESET} No .torusguard workspace found in current directory.
145
+ Run ${GREEN}npx torusguard init${RESET} to scaffold full workspace governance.
110
146
  `);
111
147
  process.exit(0);
112
148
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "torusguard",
3
- "version": "0.9.4",
3
+ "version": "0.9.5",
4
4
  "description": "Security guardrails, governed remediation, and authorized runtime validation for AI-built web applications.",
5
5
  "main": "bin/torusguard.js",
6
6
  "bin": {
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: torusguard
3
- description: Security guardrails, governed remediation, and authorized runtime validation for AI-built web applications across Python and TypeScript.
4
- version: 0.9.4
3
+ description: "Autonomous security engine: 71 rules across 11 families, governed remediation (Ponytail Protocol), SARIF v2.1.0 exports, and 5-agent authority separation for Python & TypeScript web applications."
4
+ version: 0.9.5
5
5
  ---
6
6
 
7
7
  # TorusGuard Master Security Router
@@ -10,7 +10,6 @@ import sys
10
10
  import shutil
11
11
  import json
12
12
  import argparse
13
- import subprocess
14
13
  from pathlib import Path
15
14
 
16
15
  # Ensure UTF-8 stdout/stderr on Windows consoles
@@ -25,6 +24,19 @@ if sys.stderr and hasattr(sys.stderr, "reconfigure"):
25
24
  except Exception:
26
25
  pass
27
26
 
27
+ # ─── ANSI Color Helpers ───────────────────────────────────────────────────────
28
+ BOLD = "\033[1m"
29
+ DIM = "\033[2m"
30
+ RESET = "\033[0m"
31
+ CYAN = "\033[36m"
32
+ GREEN = "\033[32m"
33
+ YELLOW = "\033[33m"
34
+ WHITE = "\033[97m"
35
+ GRAY = "\033[90m"
36
+ RED = "\033[31m"
37
+ BG_GREEN = "\033[42m"
38
+ BG_CYAN = "\033[46m"
39
+
28
40
 
29
41
  def find_project_root(start_dir=None):
30
42
  """Detect project root directory by searching for standard repo root markers."""
@@ -45,6 +57,114 @@ def find_project_root(start_dir=None):
45
57
  return current
46
58
 
47
59
 
60
+ def print_header():
61
+ """Print the branded TorusGuard header card."""
62
+ print(f"""
63
+ {CYAN}╭─────────────────────────────────────────────────────────────────────────╮{RESET}
64
+ {CYAN}│{RESET} {CYAN}│{RESET}
65
+ {CYAN}│{RESET} {BOLD}{WHITE}🛡️ T O R U S G U A R D{RESET} {GRAY}v0.9.5{RESET} {CYAN}│{RESET}
66
+ {CYAN}│{RESET} {DIM}Autonomous Security Engine for AI-Built Applications{RESET} {CYAN}│{RESET}
67
+ {CYAN}│{RESET} {CYAN}│{RESET}
68
+ {CYAN}╰─────────────────────────────────────────────────────────────────────────╯{RESET}
69
+ """)
70
+
71
+
72
+ def print_step_1_assets(file_count):
73
+ """Print the enhanced Step 1 asset unpacking card."""
74
+ print(f""" {CYAN}┌─ {BOLD}Step 1/3{RESET} {CYAN}──────────────────────── {WHITE}Unpacking Governance Assets{RESET} {CYAN}──────┐{RESET}
75
+ {CYAN}│{RESET} {CYAN}│{RESET}
76
+ {CYAN}│{RESET} {GREEN}✔{RESET} Canonical security rules {DIM}71 rules across 11 families{RESET} {CYAN}│{RESET}
77
+ {CYAN}│{RESET} {GREEN}✔{RESET} JSON validation schemas {DIM}8 formal schemas{RESET} {CYAN}│{RESET}
78
+ {CYAN}│{RESET} {GREEN}✔{RESET} Specialist agent specifications {DIM}5 isolated agents{RESET} {CYAN}│{RESET}
79
+ {CYAN}│{RESET} {GREEN}✔{RESET} Workflow templates {DIM}11 slash commands{RESET} {CYAN}│{RESET}
80
+ {CYAN}│{RESET} {GREEN}✔{RESET} Framework reference guides {DIM}10 security guides{RESET} {CYAN}│{RESET}
81
+ {CYAN}│{RESET} {CYAN}│{RESET}
82
+ {CYAN}│{RESET} {BOLD}{WHITE}{file_count} files unpacked{RESET} {CYAN}│{RESET}
83
+ {CYAN}└───────────────────────────────────────────────────────────────────────┘{RESET}
84
+ """)
85
+
86
+
87
+ def print_step_2_profile(detected_stack=None):
88
+ """Print the security profile & coverage card (in-process stack alignment)."""
89
+ if detected_stack and detected_stack.get("framework") and detected_stack.get("framework") != "None":
90
+ fw = str(detected_stack.get("framework"))
91
+ lang = str(detected_stack.get("language", ""))
92
+ label = f"Auto-aligned stack: {fw} ({lang})"
93
+ pad = " " * max(0, 66 - len(label))
94
+ status_line = f" {CYAN}│{RESET} {GREEN}✔{RESET} {BOLD}Auto-aligned stack:{RESET} {WHITE}{fw}{RESET} {DIM}({lang}){RESET}{pad}{CYAN}│{RESET}"
95
+ else:
96
+ status_line = f" {CYAN}│{RESET} {DIM}ℹ Stack auto-detected on first /torusguard-audit run{RESET} {CYAN}│{RESET}"
97
+
98
+ print(f""" {CYAN}┌─ {BOLD}Step 2/3{RESET} {CYAN}──────────────────── {WHITE}Security Profile & Coverage{RESET} {CYAN}────────┐{RESET}
99
+ {CYAN}│{RESET} {CYAN}│{RESET}
100
+ {CYAN}│{RESET} {BOLD}Rule Families:{RESET} {CYAN}│{RESET}
101
+ {CYAN}│{RESET} {YELLOW}TG-SEC{RESET} Secrets & Credentials {YELLOW}TG-DB{RESET} Database Safety {CYAN}│{RESET}
102
+ {CYAN}│{RESET} {YELLOW}TG-INPUT{RESET} Input Validation {YELLOW}TG-AUTH{RESET} Authentication {CYAN}│{RESET}
103
+ {CYAN}│{RESET} {YELLOW}TG-CLIENT{RESET} Client Bundle Leaks {YELLOW}TG-DIFF{RESET} Diff Inspection {CYAN}│{RESET}
104
+ {CYAN}│{RESET} {YELLOW}TG-AGENT{RESET} AI Agent Security {YELLOW}TG-EDGE{RESET} Serverless {CYAN}│{RESET}
105
+ {CYAN}│{RESET} {YELLOW}TG-SUPPLY{RESET} Supply Chain & CI/CD {YELLOW}TG-SSRF{RESET} Outbound Net {CYAN}│{RESET}
106
+ {CYAN}│{RESET} {YELLOW}TG-BIZ{RESET} Business Logic {CYAN}│{RESET}
107
+ {CYAN}│{RESET} {CYAN}│{RESET}
108
+ {CYAN}│{RESET} {BOLD}Supported Stacks:{RESET} {CYAN}│{RESET}
109
+ {CYAN}│{RESET} {GREEN}Python{RESET} Django {DIM}·{RESET} FastAPI {DIM}·{RESET} Flask {DIM}·{RESET} DRF {DIM}·{RESET} SQLAlchemy {CYAN}│{RESET}
110
+ {CYAN}│{RESET} {GREEN}Node.js{RESET} Next.js {DIM}·{RESET} Express {DIM}·{RESET} React {DIM}·{RESET} Supabase {DIM}·{RESET} Firebase {CYAN}│{RESET}
111
+ {CYAN}│{RESET} {CYAN}│{RESET}
112
+ {status_line}
113
+ {CYAN}└───────────────────────────────────────────────────────────────────────┘{RESET}
114
+ """)
115
+
116
+
117
+ def print_step_3_bridges(registered_ides):
118
+ """Print the IDE command registration card."""
119
+ lines = ""
120
+ for r in registered_ides:
121
+ lines += f" {CYAN}│{RESET} {GREEN}✔{RESET} {r:<67} {CYAN}│{RESET}\n"
122
+
123
+ print(f""" {CYAN}┌─ {BOLD}Step 3/3{RESET} {CYAN}─────────────────── {WHITE}AI IDE Command Registration{RESET} {CYAN}─────────┐{RESET}
124
+ {CYAN}│{RESET} {CYAN}│{RESET}
125
+ {lines} {CYAN}│{RESET} {CYAN}│{RESET}
126
+ {CYAN}└───────────────────────────────────────────────────────────────────────┘{RESET}
127
+ """)
128
+
129
+
130
+ def print_success_card():
131
+ """Print the final success card with next steps."""
132
+ print(f""" {GREEN}╔═══════════════════════════════════════════════════════════════════════╗{RESET}
133
+ {GREEN}║{RESET} {GREEN}║{RESET}
134
+ {GREEN}║{RESET} {GREEN}{BOLD}✅ WORKSPACE INITIALIZED SUCCESSFULLY{RESET} {GREEN}║{RESET}
135
+ {GREEN}║{RESET} {GREEN}║{RESET}
136
+ {GREEN}╠═══════════════════════════════════════════════════════════════════════╣{RESET}
137
+ {GREEN}║{RESET} {GREEN}║{RESET}
138
+ {GREEN}║{RESET} {BOLD}Next Steps:{RESET} {GREEN}║{RESET}
139
+ {GREEN}║{RESET} {GREEN}║{RESET}
140
+ {GREEN}║{RESET} {CYAN}1.{RESET} In AI Chat {WHITE}/torusguard-audit{RESET} or {WHITE}/torusguard{RESET} {GREEN}║{RESET}
141
+ {GREEN}║{RESET} {CYAN}2.{RESET} In Terminal {WHITE}npx torusguard status{RESET} {GREEN}║{RESET}
142
+ {GREEN}║{RESET} {CYAN}3.{RESET} In CI/CD {WHITE}npx torusguard audit{RESET} {GREEN}║{RESET}
143
+ {GREEN}║{RESET} {GREEN}║{RESET}
144
+ {GREEN}║{RESET} {DIM}Docs{RESET} {CYAN}https://github.com/githubmofo/TorusGuard{RESET} {GREEN}║{RESET}
145
+ {GREEN}║{RESET} {DIM}NPM{RESET} {CYAN}https://npmjs.com/package/torusguard{RESET} {GREEN}║{RESET}
146
+ {GREEN}║{RESET} {GREEN}║{RESET}
147
+ {GREEN}╚═══════════════════════════════════════════════════════════════════════╝{RESET}
148
+ """)
149
+
150
+
151
+ def print_already_initialized(target_root, cfg):
152
+ """Print the already-initialized status card."""
153
+ print(f"""
154
+ {CYAN}╭─────────────────────────────────────────────────────────────────────────╮{RESET}
155
+ {CYAN}│{RESET} {BOLD}{WHITE}🛡️ TORUSGUARD WORKSPACE{RESET} {GREEN}[Active]{RESET} {CYAN}│{RESET}
156
+ {CYAN}╰─────────────────────────────────────────────────────────────────────────╯{RESET}
157
+
158
+ {BOLD}▸ Project Root:{RESET} {GREEN}{target_root}{RESET}
159
+ {BOLD}▸ Workspace:{RESET} {GREEN}.torusguard/{RESET} {DIM}(Already Initialized){RESET}
160
+ {BOLD}▸ Version:{RESET} {CYAN}{cfg.get('version', '0.9.5')}{RESET}
161
+ {BOLD}▸ Severity Floor:{RESET} {YELLOW}{cfg.get('severity_threshold', 'medium')}{RESET}
162
+
163
+ {DIM}To refresh templates or re-scaffold, run:{RESET}
164
+ {CYAN}npx torusguard init --force{RESET}
165
+ """)
166
+
167
+
48
168
  def scaffold_workspace(target_root=None, force=False, full_commands=False):
49
169
  """Scaffold the .torusguard workspace into the target project root."""
50
170
  target_root = Path(target_root or find_project_root()).resolve()
@@ -53,40 +173,25 @@ def scaffold_workspace(target_root=None, force=False, full_commands=False):
53
173
  payload_dir = script_dir / "payload"
54
174
 
55
175
  if torusguard_target.exists() and not force:
56
- print("""
57
- ╭──────────────────────────────────────────────────────────────────────────╮
58
- │ 🛡️ TORUSGUARD WORKSPACE STATUS [Active] │
59
- ╰──────────────────────────────────────────────────────────────────────────╯
60
- """)
61
- print(f" ▸ Project Root: {target_root}")
62
- print(f" ▸ Workspace: .torusguard/ (Already Initialized)")
63
176
  config_file = torusguard_target / "config" / "torusguard.json"
177
+ cfg = {}
64
178
  if config_file.exists():
65
179
  try:
66
180
  with open(config_file, "r", encoding="utf-8") as f:
67
181
  cfg = json.load(f)
68
- print(f" ▸ Version: {cfg.get('version', '0.9.3')}")
69
- print(f" ▸ Severity Floor: {cfg.get('severity_threshold', 'medium')}")
70
182
  except Exception:
71
183
  pass
72
- print("""
73
- 💡 Workspace already exists. To refresh templates or re-scaffold, run:
74
- npx torusguard init --force
75
- """)
184
+ print_already_initialized(target_root, cfg)
76
185
  return True
77
186
 
78
- print("""
79
- ╭──────────────────────────────────────────────────────────────────────────╮
80
- 🛡️ TORUSGUARD WORKSPACE INITIALIZATION v0.9.3 │
81
- Governed Remediation & AI Application Guardrails │
82
- ╰──────────────────────────────────────────────────────────────────────────╯
83
- """)
84
- print(f" ▸ Target Project: {target_root}")
85
- print(f" ▸ Destination: {torusguard_target}")
187
+ # ── Header ──────────────────────────────────────────────────────────────
188
+ print_header()
189
+ print(f" {BOLD}▸ Target Project:{RESET} {WHITE}{target_root}{RESET}")
190
+ print(f" {BOLD}▸ Destination:{RESET} {WHITE}{torusguard_target}{RESET}")
86
191
 
87
- # 1. Unpack Payload Template
192
+ # ── Step 1: Unpack Payload ──────────────────────────────────────────────
193
+ file_count = 93
88
194
  if payload_dir.is_dir():
89
- print("\n ▸ Step 1/3: Unpacking Offline Governance Assets...")
90
195
  try:
91
196
  if torusguard_target.exists() and force:
92
197
  shutil.rmtree(torusguard_target)
@@ -95,22 +200,25 @@ def scaffold_workspace(target_root=None, force=False, full_commands=False):
95
200
  torusguard_target,
96
201
  ignore=shutil.ignore_patterns("runs", "*.pyc", "__pycache__", ".git*")
97
202
  )
98
- print(" ✔ Copied canonical rules, schemas, scripts, and workflows (93 files)")
203
+ # Count actual files
204
+ file_count = sum(1 for _ in torusguard_target.rglob("*") if _.is_file())
99
205
  except Exception as e:
100
- print(f" Failed to unpack payload: {e}")
206
+ print(f"\n {RED}✖ Failed to unpack payload: {e}{RESET}")
101
207
  return False
102
208
  else:
103
209
  # Fallback: create base structure
104
- print("\n1. Bundled payload not found. Creating core skeleton...")
105
210
  subdirs = [
106
211
  "config", "agents", "workflows", "scripts", "templates",
107
212
  "schemas", "references", "rules/active", "runs"
108
213
  ]
109
214
  for s in subdirs:
110
215
  (torusguard_target / s).mkdir(parents=True, exist_ok=True)
111
- print(" [WARN] Bare skeleton created; full assets should be pulled from repository.")
216
+ file_count = 0
112
217
 
113
- # 2. Ensure runs and rules/active directories exist
218
+ print()
219
+ print_step_1_assets(file_count)
220
+
221
+ # ── Ensure runs and rules/active directories exist ──────────────────────
114
222
  runs_dir = torusguard_target / "runs"
115
223
  runs_dir.mkdir(parents=True, exist_ok=True)
116
224
  gitkeep_runs = runs_dir / ".gitkeep"
@@ -123,50 +231,51 @@ def scaffold_workspace(target_root=None, force=False, full_commands=False):
123
231
  if not gitkeep_rules.exists():
124
232
  gitkeep_rules.write_text("", encoding="utf-8")
125
233
 
126
- # 3. Stack Detection & Tailoring
127
- print("\n ▸ Step 2/3: Executing Stack Detection & Rule Alignment...")
234
+ # ── Step 2: Security Profile & Coverage (In-Process, Zero Subprocess) ──
235
+ # Execute stack detection in-process without spawning child processes (Socket.dev safe)
236
+ detected_stack = None
128
237
  stack_detect_script = torusguard_target / "scripts" / "stack_detect.py"
129
- detected_stack = {"language": "Unknown", "framework": "None", "data_layer": "None", "confidence": "Uncertain"}
130
-
131
- if stack_detect_script.exists():
238
+ if stack_detect_script.is_file():
132
239
  try:
133
- res = subprocess.run(
134
- [sys.executable, str(stack_detect_script), str(target_root), "--json"],
135
- capture_output=True,
136
- text=True,
137
- timeout=10
138
- )
139
- if res.returncode == 0 and res.stdout.strip():
140
- detected_stack = json.loads(res.stdout)
141
- print(f" ⎿ Language: {detected_stack.get('language')}")
142
- print(f" ⎿ Framework: {detected_stack.get('framework')}")
143
- print(f" ⎿ Data Layer: {detected_stack.get('data_layer')}")
144
- except Exception as e:
145
- print(f" ⚠ Stack detection warning: {e}")
240
+ import importlib.util
241
+ spec = importlib.util.spec_from_file_location("stack_detect", str(stack_detect_script))
242
+ if spec and spec.loader:
243
+ sd_mod = importlib.util.module_from_spec(spec)
244
+ spec.loader.exec_module(sd_mod)
245
+ if hasattr(sd_mod, "detect_stack"):
246
+ detected_stack = sd_mod.detect_stack(target_root)
247
+ except Exception:
248
+ detected_stack = None
146
249
 
147
- # 4. Update torusguard.json configuration
148
250
  config_file = torusguard_target / "config" / "torusguard.json"
149
251
  if config_file.exists():
150
252
  try:
151
253
  with open(config_file, "r", encoding="utf-8") as f:
152
254
  cfg = json.load(f)
153
- cfg["detected_stack"] = {
154
- "language": detected_stack.get("language"),
155
- "framework": detected_stack.get("framework"),
156
- "data_layer": detected_stack.get("data_layer")
157
- }
255
+ if detected_stack and detected_stack.get("framework") != "None":
256
+ cfg["detected_stack"] = {
257
+ "language": detected_stack.get("language"),
258
+ "framework": detected_stack.get("framework"),
259
+ "data_layer": detected_stack.get("data_layer")
260
+ }
261
+ else:
262
+ cfg["detected_stack"] = {
263
+ "language": "Unknown",
264
+ "framework": "None",
265
+ "data_layer": "None"
266
+ }
158
267
  with open(config_file, "w", encoding="utf-8") as f:
159
268
  json.dump(cfg, f, indent=2)
160
- print(" ✔ Configured .torusguard/config/torusguard.json (71 Rules Active)")
161
- except Exception as e:
162
- print(f" ⚠ Config update error: {e}")
269
+ except Exception:
270
+ pass
163
271
 
164
- # 5. Register Slash Commands for AI IDEs (.agent, .claude, .cursor)
165
- print("\n ▸ Step 3/3: Registering AI IDE Command Bridges...")
272
+ print_step_2_profile(detected_stack)
273
+
274
+ # ── Step 3: Register Slash Commands for AI IDEs ─────────────────────────
166
275
  registered_ides = []
167
276
  tg_workflow_content = """---
168
277
  description: TorusGuard Autonomous Security Command Engine — run static security audits, authorized runtime web validation, governed remediation, and SARIF exports.
169
- version: 0.9.2
278
+ version: 0.9.5
170
279
  tools: Read, Grep, Glob, Bash, Edit, Write
171
280
  agent: auditor
172
281
  ---
@@ -192,16 +301,16 @@ Parse the requested action from `$ARGUMENTS` (e.g. `audit`, `verify`, `web-valid
192
301
  agents_wf.mkdir(parents=True, exist_ok=True)
193
302
  (agents_wf / "torusguard.md").write_text(tg_workflow_content, encoding="utf-8")
194
303
  dest_workflow_dirs.append(agents_wf)
195
- registered_ides.append("Antigravity / Gemini (.agents/workflows/torusguard.md)")
304
+ registered_ides.append("Antigravity / Gemini .agents/workflows/torusguard.md")
196
305
 
197
306
  agent_wf = target_root / ".agent" / "workflows"
198
307
  agent_wf.mkdir(parents=True, exist_ok=True)
199
308
  (agent_wf / "torusguard.md").write_text(tg_workflow_content, encoding="utf-8")
200
309
  dest_workflow_dirs.append(agent_wf)
201
- registered_ides.append("Antigravity / Tribunal (.agent/workflows/torusguard.md)")
310
+ registered_ides.append("Tribunal Agent Kit .agent/workflows/torusguard.md")
202
311
 
203
312
  # When full_commands is requested (e.g. via NPM package npx torusguard init),
204
- # unlock and register all 11 individual slash commands (/torusguard-audit, /torusguard-harden, etc.)
313
+ # unlock and register all 11 individual slash commands
205
314
  if full_commands:
206
315
  src_wf = torusguard_target / "workflows"
207
316
  if src_wf.is_dir():
@@ -213,7 +322,7 @@ Parse the requested action from `$ARGUMENTS` (e.g. `audit`, `verify`, `web-valid
213
322
  for d in dest_workflow_dirs:
214
323
  shutil.copy2(wf_file, d / cmd_filename)
215
324
  count += 1
216
- registered_ides.append(f"Unlocked {count} Individual Slash Commands (/torusguard-audit, /torusguard-apply, etc.)")
325
+ registered_ides.append(f"{count} Slash Commands /torusguard-audit, -harden, -apply, ...")
217
326
 
218
327
  # Claude Code (.claude/commands)
219
328
  claude_dir = target_root / ".claude"
@@ -221,7 +330,7 @@ Parse the requested action from `$ARGUMENTS` (e.g. `audit`, `verify`, `web-valid
221
330
  claude_commands = claude_dir / "commands"
222
331
  claude_commands.mkdir(parents=True, exist_ok=True)
223
332
  (claude_commands / "torusguard.md").write_text(tg_workflow_content, encoding="utf-8")
224
- registered_ides.append("Claude Code (.claude/commands/torusguard.md)")
333
+ registered_ides.append("Claude Code .claude/commands/torusguard.md")
225
334
 
226
335
  # Cursor (.cursor/rules)
227
336
  cursor_dir = target_root / ".cursor"
@@ -229,7 +338,7 @@ Parse the requested action from `$ARGUMENTS` (e.g. `audit`, `verify`, `web-valid
229
338
  cursor_rules = cursor_dir / "rules"
230
339
  cursor_rules.mkdir(parents=True, exist_ok=True)
231
340
  (cursor_rules / "torusguard.mdc").write_text(tg_workflow_content, encoding="utf-8")
232
- registered_ides.append("Cursor (.cursor/rules/torusguard.mdc)")
341
+ registered_ides.append("Cursor .cursor/rules/torusguard.mdc")
233
342
 
234
343
  # Windsurf (.windsurfrules)
235
344
  if (target_root / ".windsurfrules").exists() or (target_root / ".windsurf").exists():
@@ -237,7 +346,7 @@ Parse the requested action from `$ARGUMENTS` (e.g. `audit`, `verify`, `web-valid
237
346
  current_content = windsurf_rules.read_text(encoding="utf-8") if windsurf_rules.exists() else ""
238
347
  if "TorusGuard" not in current_content:
239
348
  windsurf_rules.write_text(current_content + "\n\n" + tg_workflow_content, encoding="utf-8")
240
- registered_ides.append("Windsurf (.windsurfrules)")
349
+ registered_ides.append("Windsurf .windsurfrules")
241
350
 
242
351
  # VS Code / GitHub Copilot (.github/copilot-instructions.md)
243
352
  github_dir = target_root / ".github"
@@ -246,28 +355,19 @@ Parse the requested action from `$ARGUMENTS` (e.g. `audit`, `verify`, `web-valid
246
355
  current_content = copilot_file.read_text(encoding="utf-8") if copilot_file.exists() else ""
247
356
  if "TorusGuard" not in current_content:
248
357
  copilot_file.write_text(current_content + "\n\n# TorusGuard Security Instructions\n" + tg_workflow_content, encoding="utf-8")
249
- registered_ides.append("VS Code / Copilot (.github/copilot-instructions.md)")
358
+ registered_ides.append("VS Code / Copilot .github/copilot-instructions.md")
250
359
 
251
360
  # Universal AGENTS.md (Kimi, Codex, Open Agent Standard)
252
361
  agents_md = target_root / "AGENTS.md"
253
362
  current_agents = agents_md.read_text(encoding="utf-8") if agents_md.exists() else ""
254
363
  if "TorusGuard" not in current_agents:
255
364
  agents_md.write_text(current_agents + ("\n\n" if current_agents else "") + "# TorusGuard Security Guardrails\n\nRun `/torusguard audit` to scan the codebase or refer to `.torusguard/` for security guidelines.\n", encoding="utf-8")
256
- registered_ides.append("Universal Agent Standard (AGENTS.md for Kimi / Open Agents)")
365
+ registered_ides.append("Universal AGENTS.md Kimi / Open Agent Standard")
257
366
 
258
- for r in registered_ides:
259
- print(f" ✔ {r}")
367
+ print_step_3_bridges(registered_ides)
260
368
 
261
- print(f"""
262
- ╭──────────────────────────────────────────────────────────────────────────╮
263
- │ ✨ TorusGuard Workspace Initialized Successfully! │
264
- │ │
265
- │ 🚀 Next Steps: │
266
- │ 1. In AI Chat: Type `/torusguard-audit` or `/torusguard` to scan │
267
- │ 2. In Terminal: Run `npx torusguard status` for security posture │
268
- │ 3. In CI/CD: Run `npx torusguard audit` to generate SARIF data │
269
- ╰──────────────────────────────────────────────────────────────────────────╯
270
- """)
369
+ # ── Success Card ────────────────────────────────────────────────────────
370
+ print_success_card()
271
371
  return True
272
372
 
273
373
 
@@ -8,7 +8,7 @@
8
8
  "agents/validator.md": "79fc4431de5c5507f8730aee6c5c3e61fd238cbf8cf8c7c6aac462eee9761ed6",
9
9
  "config/scope.json": "b198a86186b4c6d5e1af516bf4e3a6afa8878e622ca1d57a5bf72d294f8c6f25",
10
10
  "config/slash-commands.json": "5390f0d26f8117a62e56c58147d3a0d2deab1a20956302b212703281d13fa84e",
11
- "config/torusguard.json": "218eeae10b538aca9b548d1b756d7d4f91a5b624e0bce07533f0c187860586e6",
11
+ "config/torusguard.json": "077bc6a948f9420aded8dba248577ff3ebf054cab64cf538a7a6d05223fe27bc",
12
12
  "references/django-security.md": "a15b7eb11b51dd1970d3d65544cf79ebea91fb99dc0e085e58a56532a718dce7",
13
13
  "references/drf-security.md": "c7a7af3acaef895bf4798590acc88b3a2e9831a49eb2d23b4d8f31540ab264cc",
14
14
  "references/express-security.md": "dff1db15e614d29d8c272f9da345b418077e62dc883fe210c7a50c552c76493f",
@@ -40,7 +40,7 @@
40
40
  "scripts/safety_gate.py": "3379b7534b2590cf563717a448983ad8ed7e8f174f0ad65683d33e8a10f51558",
41
41
  "scripts/sarif_exporter.py": "35c66637413afc4b72d5bd426638447c77231d2a8594dce5addceffd4803a20d",
42
42
  "scripts/stack_detect.py": "99b7bdf9829d58ff5b8c59afd6e8b6429bbb11d830ac73dec491101cbbc41574",
43
- "skills/torusguard/SKILL.md": "5282a9e73c2faad97f079ff527def34b96709615c0dd297fe9b1bb2894f03e20",
43
+ "skills/torusguard/SKILL.md": "31a115886ffb115f2b975c4d0670e780e11ea68201559b24b20d0d0ef456058f",
44
44
  "skills/torusguard/bootstrap.py": "7e348065a622089ab1d51e9bf4864e5b0022aaee1ccb2ecbf7057c14e792e2c7",
45
45
  "skills/torusguard/references/auth-and-sessions.md": "34c2843f8c0dbe3574e54f00a39a92a1f431527ec5f69b2d64c84240d424a39e",
46
46
  "skills/torusguard/references/business-logic-and-abuse.md": "0d6088936bc1a01023070332fccef0f2e0734358a5119379055f3d2895c22567",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "../schemas/torusguard-config.schema.json",
3
- "version": "0.9.4",
3
+ "version": "0.9.5",
4
4
  "product": "TorusGuard Security Skill Kit",
5
5
  "severity_threshold": "medium",
6
6
  "auto_detect_stack": true,
@@ -1,23 +1,27 @@
1
1
  ---
2
2
  name: torusguard
3
- description: Security guardrails, governed remediation, and authorized runtime validation for AI-built web applications across Python and TypeScript.
4
- version: 0.9.4
3
+ description: "Autonomous security engine: 71 rules across 11 families, governed remediation (Ponytail Protocol), SARIF v2.1.0 exports, and 5-agent authority separation for Python & TypeScript web applications."
4
+ version: 0.9.5
5
5
  ---
6
6
 
7
- # TorusGuard Master Router
7
+ # TorusGuard Master Security Router
8
8
 
9
- **Principle:** If the browser receives it, users can inspect it. Keep secrets, direct database access, and authorization on trusted server-side code.
9
+ **Principle:** If the browser receives it, users can inspect it. Keep secrets, database queries, and authorization strictly on trusted server-side code.
10
10
 
11
11
  ---
12
12
 
13
13
  ## ⚡ Workspace Bootstrap Check
14
- 1. **If `.torusguard/` exists:** Load matching specialist skill on demand per command.
15
- 2. **If `.torusguard/` is missing:** Run `python skills/torusguard/bootstrap.py --target .` or `/torusguard init`.
14
+ 1. **If `.torusguard/` exists on disk:** Full governance active. Route slash commands to local specialist workflows below.
15
+ 2. **If `.torusguard/` is absent (Autonomous AI Mode):** Operates standalone in any AI agent (Kimi, Antigravity, VS Code, Cursor). Apply in-memory security invariants:
16
+ - Server-side auth & tenant scoping (`.filter(tenant=...)`).
17
+ - Zero client-side secrets (`SUPABASE_SERVICE_ROLE_KEY`, live API keys).
18
+ - Ponytail Protocol patch limits ($\le 35$ additions, $\le 25$ deletions).
19
+ - *Upgrade:* Run `npx torusguard init` to unlock local `.torusguard/` run tracking & individual commands.
16
20
 
17
21
  ---
18
22
 
19
23
  ## Specialist Skill Routing (Lazy Loading)
20
- Load **only** the designated sub-skill when a slash command is executed to maintain strict 1,000–1,500 token budget:
24
+ Load **only** the designated sub-skill on demand to preserve the 1,000–1,500 token budget:
21
25
 
22
26
  | Command | Specialist Skill | Agent |
23
27
  | :--- | :--- | :--- |