septum 0.1.7 → 0.1.8
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/README.md +36 -55
- package/package.json +3 -2
- package/src/cli/commands/check.ts +2 -0
- package/src/cli/commands/hook.ts +59 -12
- package/src/cli/commands/init.ts +440 -121
- package/src/cli/commands/sync.ts +27 -17
- package/src/cli/commands/topology.ts +89 -47
- package/src/cli/index.ts +5 -67
- package/src/cli/scaffold/harness-config.ts +697 -0
- package/src/cli/templates/hooks.ts +6 -6
- package/src/cli/templates/rules.ts +8 -8
- package/src/cli/templates/skill.ts +11 -18
- package/src/cli/ui/prompts.ts +122 -0
- package/src/core/boundary/staged-auditor.ts +5 -2
- package/src/core/database/client.ts +8 -0
- package/src/core/database/repositories/dependency.repository.ts +77 -13
- package/src/core/database/repositories/domain.repository.ts +86 -33
- package/src/core/database/repositories/symbol.repository.ts +128 -117
- package/src/core/database/repository.ts +17 -5
- package/src/core/database/schema.ts +1 -1
- package/src/core/discovery/topology-detector.ts +71 -19
- package/src/core/ingestion/pipeline.ts +228 -94
- package/src/core/parser/extractors/laravel-semantic.ts +9 -8
- package/src/core/parser/extractors/mcp-cli-semantic.ts +56 -16
- package/src/core/parser/extractors/nestjs-semantic.ts +3 -2
- package/src/core/parser/schema/providers/laravel-migration-provider.ts +4 -3
- package/src/core/parser/schema/providers/prisma-schema-provider.ts +2 -1
- package/src/core/resolver/call-graph-tracer.ts +4 -3
- package/src/core/resolver/path-resolver.ts +57 -4
- package/src/core/resources/ignore.ts +35 -0
- package/src/core/resources/limits.ts +14 -0
- package/src/core/resources/source-files.ts +62 -0
- package/src/core/resources/work-queue.ts +74 -0
- package/src/core/session/session-manager.ts +19 -6
- package/src/core/telemetry/telemetry.ts +12 -1
- package/src/core/topology/environment-detector.ts +21 -11
- package/src/mcp/schemas.ts +381 -8
- package/src/mcp/server.ts +321 -535
- package/src/mcp/tools/boundary.ts +17 -0
- package/src/mcp/tools/check-boundary.ts +83 -11
- package/src/mcp/tools/domain.ts +40 -0
- package/src/mcp/tools/feature.ts +67 -0
- package/src/mcp/tools/get-domain-catalog.ts +9 -6
- package/src/mcp/tools/get-environment-topology.ts +2 -2
- package/src/mcp/tools/get-feature-context.ts +9 -12
- package/src/mcp/tools/get-symbol-impact.ts +5 -2
- package/src/mcp/tools/get-symbol.ts +2 -1
- package/src/mcp/tools/locate-symbol.ts +3 -3
- package/src/mcp/tools/register-domain.ts +25 -9
- package/src/mcp/tools/register-feature.ts +34 -17
- package/src/mcp/tools/slice.ts +15 -0
- package/src/mcp/tools/symbol.ts +82 -0
- package/src/mcp/workspace-manager.ts +159 -0
- package/src/mcp/workspace-watcher.ts +202 -0
- package/src/types/index.ts +1 -0
- package/src/cli/commands/ingest.ts +0 -29
- package/src/cli/commands/locate.ts +0 -61
- package/src/cli/commands/query.ts +0 -104
- package/src/cli/commands/slice.ts +0 -50
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> **Deterministic Bounded-Context & Anti-Poisoning Architecture Guard for AI Coding Agents.**
|
|
4
4
|
|
|
5
|
-
[](package.json)
|
|
6
6
|
[](https://bun.sh)
|
|
7
7
|
[](https://modelcontextprotocol.io/)
|
|
8
8
|
[-003B57?logo=sqlite)](https://sqlite.org/)
|
|
@@ -28,16 +28,26 @@ bun add -g septum
|
|
|
28
28
|
|
|
29
29
|
### 1. Initialize in Any Project
|
|
30
30
|
|
|
31
|
+
Run `septum init` in your project root:
|
|
32
|
+
|
|
31
33
|
```bash
|
|
32
34
|
septum init
|
|
33
35
|
# or zero-install via bunx:
|
|
34
36
|
bunx septum init
|
|
35
37
|
```
|
|
36
|
-
*Auto-detects project topology (Monorepos, Laravel, Next.js, Go, NestJS), registers domains, and ingests AST symbols into `.septum/septum.db`.*
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
Septum automatically:
|
|
40
|
+
1. **Detects Architecture & Topology:** Discovers bounded domains across Monorepos, Laravel, Next.js, Go, NestJS, and more.
|
|
41
|
+
2. **Builds AST Symbol SSOT:** Ingests symbols, interfaces, and dependencies into `.septum/septum.db`.
|
|
42
|
+
3. **Scaffolds AI Agent Harnesses:** Interactively configures MCP servers, guardrail rules, and pre-write boundary hooks for your favorite agent environments:
|
|
43
|
+
- **Claude Code** (`.mcp.json`, `.claude/settings.json`)
|
|
44
|
+
- **Antigravity** (`.gemini/`)
|
|
45
|
+
- **Cursor** (`.cursor/mcp.json`, `.cursor/hooks.json`)
|
|
46
|
+
- **Opencode** (`opencode.json`)
|
|
47
|
+
|
|
48
|
+
### 2. Manual MCP Client Configuration (Optional)
|
|
39
49
|
|
|
40
|
-
|
|
50
|
+
If your MCP client is not configured via `septum init`, add Septum manually (`mcp.json` or `claude_desktop_config.json`):
|
|
41
51
|
|
|
42
52
|
```json
|
|
43
53
|
{
|
|
@@ -57,15 +67,12 @@ Add Septum to your MCP client (`mcp.json` or `claude_desktop_config.json`):
|
|
|
57
67
|
|
|
58
68
|
| Command | Description |
|
|
59
69
|
|---|---|
|
|
60
|
-
| `septum init` | Detect topology, scaffold boundary guards, and build initial catalog |
|
|
61
|
-
| `septum
|
|
62
|
-
| `septum
|
|
63
|
-
| `septum
|
|
64
|
-
| `septum
|
|
65
|
-
| `septum
|
|
66
|
-
| `septum slice <route\|intent>` | Trace end-to-end vertical execution slice for route/intent |
|
|
67
|
-
| `septum topology [action]` | Inspect 6-layer environment topology plane & distributed nodes |
|
|
68
|
-
| `septum feature status\|clear` | Manage active feature lease and editing scope |
|
|
70
|
+
| `septum init [--force]` | Detect topology, scaffold boundary guards, and build initial catalog. `--force` regenerates Septum-owned hooks and harness artifacts while strictly preserving SQLite DB, manual domain policies, and user Git hooks |
|
|
71
|
+
| `septum sync [--json]` | AST synchronization and catalog update into `.septum/septum.db` (full or incremental) |
|
|
72
|
+
| `septum check [--strict] [--staged] [--feature <name>] [--json]` | CI/CD gate & pre-commit hook: verify boundary integrity & fail on cross-domain violations |
|
|
73
|
+
| `septum feature [status|clear] [--force]` | View or release active feature lease and editing scope (`--force` for other owner's session) |
|
|
74
|
+
| `septum hook [subhook]` | Internal pre-tool guardrail hook (e.g. pre-write, post-write) for AI agent tools |
|
|
75
|
+
| `septum topology [subcommand]` | Inspect 6-layer environment topology plane & distributed nodes (`env` alias available). Subcommands: `resolve <layer> <platform>`, `add-node`, `remove-node`, `clear` |
|
|
69
76
|
| `septum serve` | Launch stdio MCP server for AI coding agents |
|
|
70
77
|
|
|
71
78
|
---
|
|
@@ -74,29 +81,22 @@ Add Septum to your MCP client (`mcp.json` or `claude_desktop_config.json`):
|
|
|
74
81
|
|
|
75
82
|
All tools expose typed schemas automatically via the Model Context Protocol:
|
|
76
83
|
|
|
77
|
-
- **
|
|
78
|
-
-
|
|
79
|
-
-
|
|
80
|
-
-
|
|
81
|
-
- **
|
|
82
|
-
-
|
|
83
|
-
-
|
|
84
|
-
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
cd septum
|
|
94
|
-
bun install
|
|
95
|
-
|
|
96
|
-
# Run test suite & build
|
|
97
|
-
bun test
|
|
98
|
-
bun run build
|
|
99
|
-
```
|
|
84
|
+
- **Domain Catalog, Registration & Environment Topology (`septum_domain`):**
|
|
85
|
+
- `action: "catalog"`: Whole-project macro architecture map and file connections in < 400 tokens (`detail_level: "compact" | "full"`).
|
|
86
|
+
- `action: "register"`: Dynamically registers or updates bounded-context domains with allowed/forbidden dependencies and layer archetypes.
|
|
87
|
+
- `action: "topology"`: Maps and verifies the 6-layer production architecture (Edge/WAF, Gateway/Web Server, Host, Runtime, Storage/Cache, Telemetry) and distributed nodes with cross-layer invariants.
|
|
88
|
+
- **Unified Symbol Engine (`septum_symbol`):**
|
|
89
|
+
- `action: "locate"`: Fast fuzzy search and error log resolution to pinpoint symbols across workspaces.
|
|
90
|
+
- `action: "inspect"`: Deep inspection of physical coordinates, declarations, and full typed signatures.
|
|
91
|
+
- `action: "impact"`: Refactoring blast radius, call graphs, and inbound/outbound dependency analysis.
|
|
92
|
+
- `action: "hotspots"`: God function and Single Responsibility Principle (SRP) detector ranked by physical lines, cyclomatic nesting depth, and composite risk score.
|
|
93
|
+
- **Omni-Trigger Vertical Slice Tracer (`septum_slice`):**
|
|
94
|
+
- Traces end-to-end execution flow (*Ingress ➔ Validation ➔ Controller ➔ Service ➔ Repository ➔ Entity*) from route URIs, controller actions, or high-level intent across HTTP routes, queue jobs, console commands, and events up to 8 levels deep.
|
|
95
|
+
- **Architecture Guard & Circular Dependency Gate (`septum_boundary`):**
|
|
96
|
+
- Validates proposed edits, additions, and imports against domain rules and feature touchpoints before files are modified on disk (`scope: "file"`).
|
|
97
|
+
- Audits staged files (`scope: "staged"`), domain boundaries (`scope: "domain"`), or the entire repository (`scope: "all"`) for cross-domain leaks and dependency cycles.
|
|
98
|
+
- **Active Touchpoint & Scope Lock Engine (`septum_feature`):**
|
|
99
|
+
- Locks active feature task context, touchpoints, and contracts (`action: "lock"` / `action: "get"` / `action: "release"`) via `.septum/session.json` to eliminate AI context drift and unintended edits.
|
|
100
100
|
|
|
101
101
|
---
|
|
102
102
|
|
|
@@ -104,22 +104,3 @@ bun run build
|
|
|
104
104
|
|
|
105
105
|
[MIT](LICENSE) © shironim
|
|
106
106
|
|
|
107
|
-
## Reliability and Scope
|
|
108
|
-
|
|
109
|
-
`septum check --strict` enables strict dependency rules before evaluating the codebase. A full check synchronizes the index first. CLI and MCP staged checks read Git index blobs, so unstaged edits cannot hide a violation in the proposed commit. Staged checks also evaluate dependency cycles using indexed dependencies with staged imports overlaid.
|
|
110
|
-
|
|
111
|
-
Domain ownership uses the most specific normalized root in both full and single-file ingestion. Feature touchpoints are normalized against the workspace; `/*` permits immediate children and `/**` permits descendants.
|
|
112
|
-
|
|
113
|
-
Each active MCP workspace has a watcher. Changes to multiple files are batched without dropping earlier paths; deletion and directory moves reconcile the catalog. If a native watcher is unavailable, Septum falls back to polling and synchronizes before answering queries. Catalog responses expose `index_status.watcher_mode` and `index_status.unsupported_files`. Single-file updates invalidate cached execution slices; the next trace rebuilds them.
|
|
114
|
-
|
|
115
|
-
Tree-sitter grammars are runtime dependencies and are embedded in compiled executables. The active extractors cover TypeScript/JavaScript, PHP/Blade, Python, Go, and script extraction from Vue/Svelte/Astro. Rust, Java, C#, and Ruby do not yet have active extractors. Unsupported files are reported explicitly; an incomplete audit does not receive a clean approval. Unindexed symbols return `risk_level: "unknown"`.
|
|
116
|
-
|
|
117
|
-
Feature sessions have a single owner per workspace. The default owner is the MCP process; set `SEPTUM_SESSION_ID` when several commands intentionally share the same owner. Another owner cannot replace or release the active session. Use `septum feature clear --force` for explicit recovery after a process exits or for a legacy session without ownership metadata.
|
|
118
|
-
|
|
119
|
-
Run the real-server integration checks with Python 3:
|
|
120
|
-
|
|
121
|
-
```bash
|
|
122
|
-
bun run test:integration
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
These checks exercise live rule changes, Git staged blobs, multiple workspaces, rapid edits, directory moves, and unsupported-file diagnostics. The normal `bun test` suite includes a standalone-binary regression for forbidden multiline imports.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "septum",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "Deterministic Bounded-Context, Structural File Catalog & Anti-Poisoning Partition for AI Agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"test": "bun test",
|
|
20
20
|
"build": "bun build ./bin/septum.ts --compile --outfile dist/septum",
|
|
21
21
|
"typecheck": "tsc --noEmit",
|
|
22
|
-
"test:integration": "python3 tests/integration/mcp-reliability.py"
|
|
22
|
+
"test:integration": "python3 tests/integration/mcp-reliability.py",
|
|
23
|
+
"postinstall": "bun run scripts/postinstall.ts || true"
|
|
23
24
|
},
|
|
24
25
|
"dependencies": {
|
|
25
26
|
"@modelcontextprotocol/sdk": "^1.5.0",
|
|
@@ -41,6 +41,8 @@ export async function handleCheckCommand(
|
|
|
41
41
|
if (unsupported.length > 0) {
|
|
42
42
|
throw new Error(`Cannot complete boundary audit: unsupported source files: ${unsupported.join(", ")}`);
|
|
43
43
|
}
|
|
44
|
+
const skipped = JSON.parse(repo.getMeta("skipped_files") || "[]") as {path: string}[];
|
|
45
|
+
if (skipped.length) throw new Error(`Cannot complete boundary audit: files exceed resource limits: ${skipped.map(file => file.path).join(", ")}`);
|
|
44
46
|
violations = evaluator.auditCodebase(config);
|
|
45
47
|
}
|
|
46
48
|
|
package/src/cli/commands/hook.ts
CHANGED
|
@@ -7,8 +7,14 @@ import { SeptumRepository } from "../../core/database/repository.ts";
|
|
|
7
7
|
import { ASTParserEngine } from "../../core/parser/tree-sitter.ts";
|
|
8
8
|
import { SessionManager } from "../../core/session/session-manager.ts";
|
|
9
9
|
|
|
10
|
+
interface ToolCallInfo {
|
|
11
|
+
name?: string;
|
|
12
|
+
args?: Record<string, unknown>;
|
|
13
|
+
}
|
|
14
|
+
|
|
10
15
|
export interface ToolPayload {
|
|
11
16
|
tool_name?: string;
|
|
17
|
+
toolCall?: ToolCallInfo;
|
|
12
18
|
tool_input?: {
|
|
13
19
|
TargetFile?: string;
|
|
14
20
|
file_path?: string;
|
|
@@ -30,8 +36,13 @@ export interface ToolPayload {
|
|
|
30
36
|
CodeContent?: string;
|
|
31
37
|
}
|
|
32
38
|
|
|
39
|
+
let configuredExitCode = 1;
|
|
40
|
+
|
|
33
41
|
export async function handleHookCommand(args: string[]): Promise<void> {
|
|
34
42
|
const subHook = args[1] || "pre-write";
|
|
43
|
+
if (args.includes("--exit-code-2") || args.includes("--claude") || args.includes("--cursor")) {
|
|
44
|
+
configuredExitCode = 2;
|
|
45
|
+
}
|
|
35
46
|
|
|
36
47
|
if (subHook === "pre-write") {
|
|
37
48
|
await runPreWriteHook();
|
|
@@ -40,6 +51,34 @@ export async function handleHookCommand(args: string[]): Promise<void> {
|
|
|
40
51
|
}
|
|
41
52
|
}
|
|
42
53
|
|
|
54
|
+
function blockHook(db: SeptumDatabase | null, reason: string): never {
|
|
55
|
+
if (db) {
|
|
56
|
+
try {
|
|
57
|
+
db.close();
|
|
58
|
+
} catch {
|
|
59
|
+
// ignore
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Print readable error to stderr for humans and Claude/Cursor/Codex
|
|
64
|
+
console.error(reason);
|
|
65
|
+
|
|
66
|
+
// Print JSON contract to stdout for Antigravity hook engine
|
|
67
|
+
try {
|
|
68
|
+
process.stdout.write(
|
|
69
|
+
JSON.stringify({
|
|
70
|
+
decision: "deny",
|
|
71
|
+
reason: reason.trim(),
|
|
72
|
+
}) + "\n"
|
|
73
|
+
);
|
|
74
|
+
} catch {
|
|
75
|
+
// ignore
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Exit code: 1 by default (Unix standard), or 2 if specified for Claude Code / Cursor hooks
|
|
79
|
+
process.exit(configuredExitCode);
|
|
80
|
+
}
|
|
81
|
+
|
|
43
82
|
async function runPreWriteHook(): Promise<void> {
|
|
44
83
|
// If .septum/septum.db does not exist, pass through
|
|
45
84
|
const dbPath = path.resolve(process.cwd(), ".septum", "septum.db");
|
|
@@ -62,7 +101,11 @@ async function runPreWriteHook(): Promise<void> {
|
|
|
62
101
|
}
|
|
63
102
|
|
|
64
103
|
const toolInput: Record<string, any> =
|
|
65
|
-
payload.tool_input ||
|
|
104
|
+
payload.tool_input ||
|
|
105
|
+
payload.arguments ||
|
|
106
|
+
payload.toolCall?.args ||
|
|
107
|
+
(payload as Record<string, any>) ||
|
|
108
|
+
{};
|
|
66
109
|
const targetFile: string | undefined =
|
|
67
110
|
toolInput.TargetFile || toolInput.file_path || toolInput.filePath || toolInput.path;
|
|
68
111
|
const chunkContent = Array.isArray(toolInput.ReplacementChunks)
|
|
@@ -115,15 +158,14 @@ async function runPreWriteHook(): Promise<void> {
|
|
|
115
158
|
}
|
|
116
159
|
|
|
117
160
|
if (!hasConsulted) {
|
|
118
|
-
|
|
161
|
+
blockHook(
|
|
162
|
+
db,
|
|
119
163
|
`\n[SEPTUM GATE 3 VIOLATION - Mandatory Consultation Required]\n` +
|
|
120
164
|
`✕ Operation blocked: You are attempting to write to domain '${sourceDomain}' (${targetFile}) ` +
|
|
121
165
|
`without inspecting its authoritative symbol & file-connection catalog first.\n` +
|
|
122
|
-
`▶ REQUIRED ACTION: Call tool '
|
|
123
|
-
`or '
|
|
166
|
+
`▶ REQUIRED ACTION: Call tool 'septum_domain({ action: "catalog", domain: "${sourceDomain}", detail_level: "compact" })' ` +
|
|
167
|
+
`or 'septum_feature({ action: "get" })' before writing code.\n`
|
|
124
168
|
);
|
|
125
|
-
db.close();
|
|
126
|
-
process.exit(1);
|
|
127
169
|
}
|
|
128
170
|
}
|
|
129
171
|
|
|
@@ -145,14 +187,13 @@ async function runPreWriteHook(): Promise<void> {
|
|
|
145
187
|
);
|
|
146
188
|
|
|
147
189
|
if (touchpointViolations.length > 0) {
|
|
148
|
-
|
|
190
|
+
blockHook(
|
|
191
|
+
db,
|
|
149
192
|
`\n[SEPTUM GATE 1 VIOLATION - Scope Touchpoint Lock]\n` +
|
|
150
193
|
`✕ Operation blocked: File '${targetFile}' is outside the declared allowed_touchpoints for feature '${activeFeatureKey}'.\n` +
|
|
151
194
|
`▶ REASON: ${touchpointViolations[0].message}\n` +
|
|
152
195
|
`▶ REQUIRED ACTION: Only modify files declared in allowed_touchpoints for this feature.\n`
|
|
153
196
|
);
|
|
154
|
-
db.close();
|
|
155
|
-
process.exit(1);
|
|
156
197
|
}
|
|
157
198
|
}
|
|
158
199
|
|
|
@@ -176,7 +217,8 @@ async function runPreWriteHook(): Promise<void> {
|
|
|
176
217
|
|
|
177
218
|
if (boundaryViolations.length > 0) {
|
|
178
219
|
const v = boundaryViolations[0];
|
|
179
|
-
|
|
220
|
+
blockHook(
|
|
221
|
+
db,
|
|
180
222
|
`\n[SEPTUM GATE 2 VIOLATION - Forbidden Cross-Domain Import]\n` +
|
|
181
223
|
`✕ Operation blocked: Proposed code imports forbidden domain '${v.target_domain}' from '${v.source_domain}'.\n` +
|
|
182
224
|
`▶ OFFENDING IMPORT: ${v.imported_target}\n` +
|
|
@@ -184,12 +226,17 @@ async function runPreWriteHook(): Promise<void> {
|
|
|
184
226
|
`▶ MESSAGE: ${v.message}\n` +
|
|
185
227
|
`▶ REQUIRED ACTION: Decouple this dependency. Use an authorized Interface, Event, or Shared Kernel.\n`
|
|
186
228
|
);
|
|
187
|
-
db.close();
|
|
188
|
-
process.exit(1);
|
|
189
229
|
}
|
|
190
230
|
}
|
|
191
231
|
|
|
192
232
|
db.close();
|
|
233
|
+
|
|
234
|
+
// If running in Antigravity or standard JSON IPC mode, emit allow decision
|
|
235
|
+
try {
|
|
236
|
+
process.stdout.write(JSON.stringify({ decision: "allow" }) + "\n");
|
|
237
|
+
} catch {
|
|
238
|
+
// ignore
|
|
239
|
+
}
|
|
193
240
|
process.exit(0);
|
|
194
241
|
} catch (err) {
|
|
195
242
|
db.close();
|