@gcunharodrigues/wrxn 0.2.0 → 0.2.1

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/lib/executor.cjs CHANGED
@@ -80,7 +80,7 @@ const EXECUTORS = {
80
80
  instructions: [
81
81
  'You are the devops integration executor — the ONLY executor authorized to push. Integrate the',
82
82
  'reviewed + security-passed + qa-walked track to the trunk: verify the review marker (review-<id>.md)',
83
- '+ a green suite exist, THEN push (AIOX_ACTIVE_AGENT=devops). This is the single path through the push gate.',
83
+ '+ a green suite exist, then authorize the push by setting WRXN_ACTIVE_AGENT to devops under the `env` key of .claude/settings.local.json (an inline command-scoped assignment never reaches the gate hook), push, then REMOVE WRXN_ACTIVE_AGENT from .claude/settings.local.json — a persistent flag defeats the anti-accidental-push gate. This is the single path through the push gate.',
84
84
  ],
85
85
  artifact: 'authorized-push',
86
86
  canPush: true,
@@ -0,0 +1,100 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ /**
7
+ * 002 — seeded-file honesty migration (foundation-honesty-06).
8
+ *
9
+ * Managed payload reaches existing installs on `wrxn update`, but SEEDED files are never overwritten
10
+ * (operator-owned) — so two artifacts seeded before 0.2.1 keep their stale wording forever unless a
11
+ * migration corrects them:
12
+ * - .synapse/routing's ROUTING_RULE_0 still asserts a fictional "devops role" authority.
13
+ * - docs/agents/domain.md still points at the deleted CONTEXT-MAP.md context.
14
+ * Each file is rewritten in place ONLY while it still carries its known-stale marker, so an operator
15
+ * who already customized it (or whose install is already honest) is never clobbered. The two branches
16
+ * are independent and neither ever crashes on a missing file.
17
+ *
18
+ * The honest content is EMBEDDED below as frozen 0.2.1 constants: a migration is a historical
19
+ * transform of the 0.2.1 release, not a re-read of the evolving template (ctx carries no pkgRoot, by
20
+ * design). Idempotency falls out of the gate — after the rewrite the stale markers ("devops role",
21
+ * "CONTEXT-MAP.md") are gone, so a second run is a no-op. Runs via `wrxn update` once the install
22
+ * reaches 0.2.1.
23
+ */
24
+
25
+ // The honest ROUTING_RULE_0 — mirrors the seeded `.synapse/routing` template (issue 04 confirmation-
26
+ // gate wording, minus the constitution citation the managed `global` GLOBAL_RULE_0 carries).
27
+ const HONEST_ROUTING_RULE_0 =
28
+ 'ROUTING_RULE_0=git push, PR creation, and release tags are deliberate acts held behind a confirmation flag (anti-accidental-push) — they run only once the session sets WRXN_ACTIVE_AGENT=devops in .claude/settings.local.json; `devops` is a dispatch-phase label, not an authority.';
29
+
30
+ // The honest domain glossary — frozen verbatim from the post-issue-05 payload docs/agents/domain.md.
31
+ const HONEST_DOMAIN_MD = `# Domain Docs
32
+
33
+ How the engineering skills should consume this repo's domain documentation when exploring the codebase.
34
+
35
+ ## Before exploring, read these
36
+
37
+ - **\`CONTEXT.md\`** at the repo root — the domain glossary, the canonical vocabulary for this project.
38
+ - **\`docs/adr/\`** — Architecture Decision Records. Read the ADRs that touch the area you're about to work in.
39
+
40
+ If either doesn't exist yet, **proceed silently**. Don't flag its absence; don't suggest creating it upfront. The producer skill (\`grill-with-docs\`) creates them lazily — \`CONTEXT.md\` when the first term is resolved, an ADR when a hard-to-reverse decision is actually made.
41
+
42
+ ## File structure
43
+
44
+ A fresh install ships neither file. They appear at the repo root as the project's language and decisions accumulate:
45
+
46
+ \`\`\`
47
+ /
48
+ ├── CONTEXT.md ← domain glossary (created lazily by grill-with-docs)
49
+ └── docs/
50
+ └── adr/ ← one file per decision, named NNNN-<slug>.md
51
+ \`\`\`
52
+
53
+ ## Use the glossary's vocabulary
54
+
55
+ When your output names a domain concept (in an issue title, a refactor proposal, a hypothesis, a test name), use the term as defined in \`CONTEXT.md\`. Don't drift to synonyms the glossary explicitly avoids.
56
+
57
+ If the concept you need isn't in the glossary yet, that's a signal — either you're inventing language the project doesn't use (reconsider) or there's a real gap (note it for \`grill-with-docs\`).
58
+
59
+ ## Flag ADR conflicts
60
+
61
+ If your output contradicts an existing ADR, surface it explicitly rather than silently overriding:
62
+
63
+ > _Contradicts ADR-0007 — but worth reopening because…_
64
+ `;
65
+
66
+ module.exports = {
67
+ id: '002',
68
+ version: '0.2.1',
69
+ up(ctx) {
70
+ const target = ctx.target;
71
+
72
+ // 1. routing: replace ONLY a ROUTING_RULE_0 line still carrying the stale "devops role" authority
73
+ // wording. Comments and any operator-added ROUTING_RULE_N lines are preserved verbatim; the
74
+ // split/join round-trip keeps the trailing newline. No stale line → routing left untouched.
75
+ const routingPath = path.join(target, '.synapse', 'routing');
76
+ if (fs.existsSync(routingPath)) {
77
+ const lines = fs.readFileSync(routingPath, 'utf8').split('\n');
78
+ let changed = false;
79
+ const out = lines.map((line) => {
80
+ if (line.startsWith('ROUTING_RULE_0=') && line.includes('devops role')) {
81
+ changed = true;
82
+ return HONEST_ROUTING_RULE_0;
83
+ }
84
+ return line;
85
+ });
86
+ if (changed) fs.writeFileSync(routingPath, out.join('\n'));
87
+ }
88
+
89
+ // 2. domain.md: overwrite the whole glossary with the honest content ONLY while it still names the
90
+ // deleted CONTEXT-MAP.md context. An honest or operator-customized file (marker absent) is left
91
+ // untouched. Missing file → nothing to do.
92
+ const domainPath = path.join(target, 'docs', 'agents', 'domain.md');
93
+ if (fs.existsSync(domainPath)) {
94
+ const body = fs.readFileSync(domainPath, 'utf8');
95
+ if (body.includes('CONTEXT-MAP.md')) {
96
+ fs.writeFileSync(domainPath, HONEST_DOMAIN_MD);
97
+ }
98
+ }
99
+ },
100
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gcunharodrigues/wrxn",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "WRXN Kernel — installable AI operating system. Two profiles (project | workspace), pull-based updates, managed/seeded/state file classes.",
5
5
  "bin": {
6
6
  "wrxn": "bin/wrxn.cjs"
@@ -5,7 +5,10 @@ Project-local preferences live in the seeded `constitution.local.md` addendum, n
5
5
 
6
6
  ## Article I — Agent Authority (NON-NEGOTIABLE)
7
7
 
8
- - `git push`, PR creation, and release tags are EXCLUSIVE to the devops role.
8
+ - `git push`, PR creation, and release tags are deliberate acts, held behind a
9
+ confirmation flag to prevent an accidental push: the op proceeds only once the session
10
+ confirms intent by setting `WRXN_ACTIVE_AGENT=devops` in the machine-local
11
+ `.claude/settings.local.json`. `devops` here is a dispatch-phase label, not an authority grant.
9
12
  - An agent acts only within its scope; it delegates when out of scope and never assumes
10
13
  another agent's authority.
11
14
 
@@ -2,9 +2,10 @@
2
2
  'use strict';
3
3
 
4
4
  // WRXN managed hook — Constitution Article I (Agent Authority).
5
- // PreToolUse:Bash gate: a remote git op (push / PR / tag push) is allowed only when
6
- // the session declares the devops role via WRXN_ACTIVE_AGENT=devops. A bare push runs
7
- // as @unknown and is denied. Fails OPEN on any internal error (never over-blocks).
5
+ // PreToolUse:Bash gate: a remote git op (push / PR / tag push) is a deliberate act, held
6
+ // behind a confirmation flag to prevent an accidental push. The op proceeds only once the
7
+ // session confirms intent by setting WRXN_ACTIVE_AGENT=devops in .claude/settings.local.json;
8
+ // an unconfirmed op is denied. Fails OPEN on any internal error (never over-blocks).
8
9
  //
9
10
  // Contract: reads a PreToolUse hook event as JSON on stdin, writes a decision to stdout.
10
11
  // allow → {} (exit 0)
@@ -33,13 +34,13 @@ function main() {
33
34
  }
34
35
 
35
36
  if (process.env.WRXN_ACTIVE_AGENT === 'devops') {
36
- return emit({}); // authorized
37
+ return emit({}); // confirmed
37
38
  }
38
39
 
39
40
  return emit({
40
41
  decision: 'block',
41
42
  reason:
42
- 'Remote git op is devops-exclusive (Constitution Art. I). Re-run with WRXN_ACTIVE_AGENT=devops, or delegate to the devops role.',
43
+ 'Remote git ops (push / PR / tag) are held behind a deliberate-push confirmation flag, to prevent an accidental push. To confirm intent, set WRXN_ACTIVE_AGENT=devops in .claude/settings.local.json (machine-local), then retry.',
43
44
  });
44
45
  }
45
46
 
@@ -1,21 +1,30 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
3
 
4
- // WRXN session-end hook — the episodic writer (wrxn-kernel-10).
4
+ // WRXN session-end hook — the episodic writer + session janitor (wrxn-kernel-10, foundation-honesty-02).
5
5
  // SessionEnd. Writes a dated session page into the install's own wiki sessions tier from the
6
- // captured turn trail, then clears the trail. CONTINUITY DOCTRINE: this writer touches ONLY
7
- // dated session pages it NEVER writes the continuity baton (.wrxn/continuity/latest.md).
8
- // That slot has a single writer (the handoff skill); keeping the paths disjoint is the
9
- // structural fix for the clobber observed live 2026-06-12.
6
+ // captured turn trail, then reaps the session's scratch state. Hygiene (foundation-honesty-02):
7
+ // - skip-empty: a session that captured no turns writes NO page;
8
+ // - reap: the consumed trail AND the first-touch marker (.wrxn/history/<sid>.touched, written by
9
+ // code-intel-push) are removed so .wrxn/history/ can't grow without bound;
10
+ // - bound: the sessions tier is capped (WRXN_SESSIONS_MAX, default 50) — oldest pages rotate out.
11
+ // CONTINUITY DOCTRINE: this writer touches ONLY the sessions tier + the session's own history
12
+ // scratch — it NEVER writes OR deletes the continuity baton (.wrxn/continuity/latest.md). That slot
13
+ // has a single writer (the handoff skill); keeping the paths disjoint is the structural fix for the
14
+ // clobber observed live 2026-06-12.
10
15
  //
11
16
  // Self-contained: ships into installs, MUST NOT import the kernel lib (node stdlib only).
12
17
  // Fail-open + side-effect-only: emits nothing useful, never blocks; any fault exits 0 silently.
13
18
  //
14
- // Contract: SessionEnd event JSON on stdin → exit 0. Side effect: a sessions/<date>-<sid>.md page.
19
+ // Contract: SessionEnd event JSON on stdin → exit 0. Side effect: a sessions/<date>-<sid>.md page
20
+ // for a non-empty session, plus reaping of that session's trail + touched marker.
15
21
 
16
22
  const fs = require('fs');
17
23
  const path = require('path');
18
24
 
25
+ // Bound the sessions tier to the most-recent N pages (override: WRXN_SESSIONS_MAX).
26
+ const DEFAULT_SESSIONS_MAX = 50;
27
+
19
28
  function done() {
20
29
  process.exit(0);
21
30
  }
@@ -64,6 +73,32 @@ function readTrail(root, sid) {
64
73
  return { turns, trail };
65
74
  }
66
75
 
76
+ // Best-effort removal — `force` ignores a missing file; any other fault is swallowed (fail-open).
77
+ function rmQuiet(p) {
78
+ try {
79
+ fs.rmSync(p, { force: true });
80
+ } catch {
81
+ /* best-effort cleanup, never block session close */
82
+ }
83
+ }
84
+
85
+ // Bound the sessions tier: keep at most `max` most-recent dated pages, reaping the oldest. Dated
86
+ // `YYYY-MM-DD-…` slugs sort chronologically, so the oldest are the lexicographically-first ones.
87
+ // Cap = WRXN_SESSIONS_MAX (env) or DEFAULT_SESSIONS_MAX. Self-contained: never throws.
88
+ function capSessions(dir) {
89
+ const max = Number(process.env.WRXN_SESSIONS_MAX) || DEFAULT_SESSIONS_MAX;
90
+ if (!Number.isFinite(max) || max <= 0) return;
91
+ let pages;
92
+ try {
93
+ pages = fs.readdirSync(dir).filter((f) => /^\d{4}-\d{2}-\d{2}-.+\.md$/.test(f)).sort();
94
+ } catch {
95
+ return;
96
+ }
97
+ for (let i = 0; i < pages.length - max; i++) {
98
+ rmQuiet(path.join(dir, pages[i]));
99
+ }
100
+ }
101
+
67
102
  function main() {
68
103
  let event = {};
69
104
  try {
@@ -76,52 +111,57 @@ function main() {
76
111
  const root = findInstallRoot();
77
112
  if (!root) done();
78
113
 
79
- const sid = oneLine(event.session_id || 'session');
80
- const reason = oneLine(event.reason || 'unknown');
81
- const date = nowISO().slice(0, 10); // YYYY-MM-DD
82
- const slug = `${date}-${safeId(event.session_id)}`;
83
-
84
114
  const { turns, trail } = readTrail(root, event.session_id);
85
- const trailLines = turns.length
86
- ? turns.map((t, i) => {
87
- const tab = t.indexOf('\t');
88
- const line = tab > -1 ? t.slice(tab + 1) : t;
89
- return `${i + 1}. ${line}`;
90
- })
91
- : ['_(no turns captured)_'];
92
-
93
- const page = [
94
- '---',
95
- `name: ${slug}`,
96
- `description: Session ${sid} ${turns.length} turn(s), ended ${reason}`,
97
- 'tier: sessions',
98
- 'source: session-end-hook',
99
- '---',
100
- '',
101
- `# Session ${date} (${sid})`,
102
- '',
103
- `- Ended: ${reason}`,
104
- `- Turns: ${turns.length}`,
105
- '',
106
- '## Turn trail',
107
- ...trailLines,
108
- '',
109
- ].join('\n');
110
-
111
- const dir = path.join(root, '.wrxn', 'wiki', 'sessions');
112
- try {
113
- fs.mkdirSync(dir, { recursive: true });
114
- fs.writeFileSync(path.join(dir, `${slug}.md`), page);
115
- // Consume the trail so the next session starts clean.
115
+
116
+ // Skip-empty: a session that captured no turns leaves NO page — the first half of bounding the
117
+ // sessions tier. Only write the page (and only then consume its trail) when there is activity.
118
+ if (turns.length) {
119
+ const sid = oneLine(event.session_id || 'session');
120
+ const reason = oneLine(event.reason || 'unknown');
121
+ const date = nowISO().slice(0, 10); // YYYY-MM-DD
122
+ const slug = `${date}-${safeId(event.session_id)}`;
123
+
124
+ const trailLines = turns.map((t, i) => {
125
+ const tab = t.indexOf('\t');
126
+ const line = tab > -1 ? t.slice(tab + 1) : t;
127
+ return `${i + 1}. ${line}`;
128
+ });
129
+
130
+ const page = [
131
+ '---',
132
+ `name: ${slug}`,
133
+ `description: Session ${sid} — ${turns.length} turn(s), ended ${reason}`,
134
+ 'tier: sessions',
135
+ 'source: session-end-hook',
136
+ '---',
137
+ '',
138
+ `# Session ${date} (${sid})`,
139
+ '',
140
+ `- Ended: ${reason}`,
141
+ `- Turns: ${turns.length}`,
142
+ '',
143
+ '## Turn trail',
144
+ ...trailLines,
145
+ '',
146
+ ].join('\n');
147
+
148
+ const dir = path.join(root, '.wrxn', 'wiki', 'sessions');
116
149
  try {
117
- fs.rmSync(trail, { force: true });
150
+ fs.mkdirSync(dir, { recursive: true });
151
+ fs.writeFileSync(path.join(dir, `${slug}.md`), page);
152
+ rmQuiet(trail); // consume the trail only after its page has landed
153
+ capSessions(dir); // rotation: bound the sessions tier (reap the oldest beyond the cap)
118
154
  } catch {
119
- /* trail cleanup is best-effort */
155
+ /* page write failed → fail-open; leave the trail intact for no-loss */
120
156
  }
121
- } catch {
122
- /* page write failed fail-open, never block session close */
157
+ } else {
158
+ rmQuiet(trail); // empty session: nothing to write; drop any stray empty trail file
123
159
  }
124
160
 
161
+ // The first-touch gate marker (written by code-intel-push) is pure per-session scratch — always
162
+ // reap it so .wrxn/history/ can't grow without bound. NEVER touches the continuity baton.
163
+ rmQuiet(path.join(root, '.wrxn', 'history', `${safeId(event.session_id)}.touched`));
164
+
125
165
  done();
126
166
  }
127
167
 
@@ -1,132 +1,133 @@
1
1
  ---
2
2
  name: synapse
3
- description: "This skill should be used when users want to understand the SYNAPSE context engine, manage domains, configure context rules, or troubleshoot rule injection. Use when asked about SYNAPSE architecture, domain management, star-commands, context brackets, or the 8-layer processing pipeline."
3
+ description: "Use when someone wants to understand the SYNAPSE context engine, manage its rule domains, tune the token budget or handoff threshold, or troubleshoot why a rule did or didn't inject. Covers the real engine: the three layers (constitution / always-on / keyword-recall), the flat token budget, and the non-blocking handoff directive."
4
4
  ---
5
5
 
6
- # SYNAPSE Context Engine
6
+ # SYNAPSE context engine
7
7
 
8
- ## Overview
8
+ ## What it is
9
9
 
10
- SYNAPSE (Synkra Adaptive Processing & State Engine) is the unified context engine for AIOX. It injects contextual rules into every prompt via an 8-layer processing pipeline, adapting to context window usage through bracket-aware filtering.
10
+ SYNAPSE is the per-prompt context-injection engine. On every `UserPromptSubmit` it assembles the
11
+ install's active rule domains into a single `<synapse-rules>` block and returns it as
12
+ `additionalContext`, so each prompt carries the constitution plus the operational rules that apply.
11
13
 
12
- **What it does:**
13
- - Injects rules per-prompt via Claude Code's `UserPromptSubmit` hook
14
- - Processes 8 layers (L0 Constitution through L7 Star-Commands) sequentially
15
- - Adapts injection volume based on context brackets (FRESH/MODERATE/DEPLETED/CRITICAL)
16
- - Integrates with agent state (active agent, workflow, task, squad)
17
- - Outputs `<synapse-rules>` XML block appended to each prompt
14
+ It is one self-contained hook — `.claude/hooks/synapse-engine.cjs` — that ships into an install and
15
+ reads only the install's own files (`.claude/constitution.md`, the `.synapse/` domains, and the
16
+ `wrxn.install.json` receipt that marks the install root). It imports nothing from the kernel package.
17
+ It is **fail-open**: any fault (unparseable input, missing file, assembly error) emits an empty
18
+ envelope and injects nothing the engine never blocks a prompt.
18
19
 
19
- **What it replaces:** SYNAPSE replaces the legacy CARL system with full feature parity plus 8 new capabilities including agent-scoped domains, workflow activation, and CRUD management commands.
20
+ ## The three layers
20
21
 
21
- **Architecture model:** Open Core the 8-layer engine lives in `aiox-core` (open source), memory integration is feature-gated in `aiox-pro`.
22
+ SYNAPSE assembles each prompt from three layers, in this order:
22
23
 
23
- ## Quick Start
24
+ | Layer | Source | Fires |
25
+ |-------|--------|-------|
26
+ | **L0 — Constitution** | `.claude/constitution.md` | Always. Never trimmed by the budget. |
27
+ | **L1 — Always-on domains** | `.synapse/<domain>` where `<DOMAIN>_ALWAYS_ON=true` | Every prompt. (Seeded: `global`, `pipeline`.) |
28
+ | **L6 — Keyword-recall domains** | `.synapse/<domain>` with a `<DOMAIN>_RECALL=word,...` list | Only when a trigger word appears in the prompt. (Seeded: `routing`.) |
24
29
 
25
- ### Verify SYNAPSE is Active
30
+ The constitution is rendered from `constitution.md` (article headings + their bullets) and sits
31
+ outside the token budget — it is always kept. Every other active domain contributes a numbered rules
32
+ section. See [the layer model](references/layers.md).
26
33
 
27
- SYNAPSE runs automatically via the Claude Code hook. To check status:
34
+ ## How a domain is defined
28
35
 
29
- ```
30
- *synapse status
31
- ```
36
+ Domains are registered in `.synapse/manifest` (flat `KEY=VALUE`) and their rules live in a sibling
37
+ file `.synapse/<domain>` (lowercased) as `<DOMAIN>_RULE_<N>=text` lines:
32
38
 
33
- This shows: active domains, current bracket, session info, and loaded layers.
39
+ ```
40
+ # .synapse/manifest
41
+ GLOBAL_STATE=active
42
+ GLOBAL_ALWAYS_ON=true
34
43
 
35
- ### Basic Commands
44
+ # .synapse/global
45
+ GLOBAL_RULE_0=git push, PR creation, and release tags are deliberate acts held behind a confirmation flag (anti-accidental-push) — `devops` is a dispatch-phase label, not an authority.
46
+ GLOBAL_RULE_1=The unit of work is an issue with explicit acceptance criteria.
47
+ ```
36
48
 
37
- | Command | What it does |
38
- |---------|-------------|
39
- | `*synapse status` | Show current engine state |
40
- | `*synapse domains` | List all registered domains |
41
- | `*synapse debug` | Show detailed debug info (manifest parse, load times, rule counts) |
42
- | `*synapse help` | Show all available synapse commands |
43
- | `*brief` | Switch to brief response mode |
44
- | `*dev` | Switch to developer mode (code-focused) |
45
- | `*review` | Switch to code review mode |
49
+ A domain loads only when `<DOMAIN>_STATE=active`. An always-on domain sets `_ALWAYS_ON=true`; a
50
+ keyword domain sets `_RECALL=word1,word2`. See [the manifest format](references/manifest.md) and
51
+ [domains & rule files](references/domains.md).
46
52
 
47
- ### Create a Custom Domain
53
+ ## The token budget
48
54
 
49
- ```
50
- *synapse create
51
- ```
55
+ Everything except the constitution is trimmable. A single flat budget (`RULES_BUDGET_TOKENS`,
56
+ default 600; override `WRXN_RULES_BUDGET`) caps the trimmable sections; when the assembled rules
57
+ exceed it, whole sections are dropped lowest-priority-first and a visible `[SYNAPSE-RULES-TRIM]`
58
+ marker records what was dropped. One budget, applied flat. See
59
+ [token budget & handoff](references/brackets.md).
52
60
 
53
- This walks you through creating a new domain file + manifest entry. See [references/domains.md](references/domains.md) for the full domain guide.
61
+ ## The handoff directive
54
62
 
55
- ## Architecture
63
+ When real consumed context reaches the handoff threshold (`HANDOFF_PCT`, default 0.40; override
64
+ `WRXN_HANDOFF_PCT`) of the model window, SYNAPSE appends a **non-blocking** `[HANDOFF REQUIRED]`
65
+ directive: finish the current request, run the handoff skill to write the baton, then `/clear` and
66
+ resume in a fresh session. It never refuses work. The math runs on real token usage (resident tokens
67
+ from the transcript ÷ the resolved model window), not an assumed window. See
68
+ [token budget & handoff](references/brackets.md).
56
69
 
57
- SYNAPSE operates as a 4-layer architecture:
70
+ ## Output shape
58
71
 
59
72
  ```
60
- .claude/hooks/synapse-engine.js # Layer 1: Hook Entry (~50 lines)
61
- |
62
- v imports
63
- .aiox-core/core/synapse/ # Layer 2: Engine Modules
64
- |-- engine.js # SynapseEngine class
65
- |-- layers/ # 8 layer processors (L0-L7)
66
- |-- session/session-manager.js # Session state (JSON v2.0)
67
- |-- domain/domain-loader.js # Manifest + domain parser
68
- |-- context/context-tracker.js # Bracket calculation
69
- |-- memory/memory-bridge.js # Pro-gated MIS consumer
70
- |-- output/formatter.js # <synapse-rules> XML
71
- |
72
- v reads/writes
73
- .synapse/ # Layer 3: Runtime Data
74
- |-- manifest # Central domain registry (KEY=VALUE)
75
- |-- constitution, global, context # Core domains (L0, L1)
76
- |-- agent-*, workflow-* # Scoped domains (L2, L3)
77
- |-- commands # Star-command definitions (L7)
78
- |-- sessions/, cache/ # Session state (gitignored)
79
- |
80
- v user-invoked
81
- .claude/commands/synapse/ # Layer 4: CRUD Commands + Skill Docs
82
- |-- manager.md # Router/dispatcher
83
- |-- tasks/ (6 tasks) # create, add, edit, toggle, command, suggest
84
- ```
73
+ <synapse-rules>
85
74
 
86
- **Key principle:** SYNAPSE is a **consumer** of existing systems (UAP for session state, MIS for memories). It never rewrites code from other epics.
75
+ [CONSTITUTION] (NON-NEGOTIABLE)
76
+ Article I — Agent Authority (NON-NEGOTIABLE)
77
+ git push, PR creation, and release tags are deliberate acts held behind a confirmation flag (anti-accidental-push) — `devops` is a dispatch-phase label, not an authority.
78
+ ...
87
79
 
88
- ## References
80
+ [GLOBAL]
81
+ 1. git push, PR creation, and release tags are deliberate acts held behind a confirmation flag ...
82
+ 2. The unit of work is an issue with explicit acceptance criteria ...
89
83
 
90
- ### Reference Guides
84
+ [RECALL: routing]
85
+ 1. git push, PR creation, and release tags are deliberate acts held behind a confirmation flag ...
91
86
 
92
- | Guide | Description |
93
- |-------|-------------|
94
- | [domains.md](references/domains.md) | Domain types (L0-L7), KEY=VALUE format, creation guide |
95
- | [commands.md](references/commands.md) | Star-commands, *synapse sub-commands, CRUD operations |
96
- | [manifest.md](references/manifest.md) | Manifest format specification, all valid keys |
97
- | [brackets.md](references/brackets.md) | Context bracket system, token budgets, layer activation |
98
- | [layers.md](references/layers.md) | 8-layer processor architecture, priority, conflict resolution |
87
+ [SYNAPSE-RULES-TRIM] ROUTING dropped over the 600-token rules budget
99
88
 
100
- ### Assets (Templates)
89
+ [HANDOFF REQUIRED]
90
+ Context is at ~42% of the model window (>= the 40% handoff threshold). NON-BLOCKING — do NOT stop work:
91
+ 1. Finish the current request.
92
+ 2. Run the handoff skill to write the baton (a compact handoff document).
93
+ 3. Tell the operator to /clear and open a fresh session, where the baton injects on resume.
101
94
 
102
- Templates for creating custom domains and manifest entries are maintained at:
95
+ </synapse-rules>
96
+ ```
103
97
 
104
- - **Domain template:** `.claude/commands/synapse/templates/domain-template`
105
- - **Manifest entry template:** `.claude/commands/synapse/templates/manifest-entry-template`
98
+ The trim marker appears only when a section was dropped; the handoff directive only at/above the
99
+ threshold. When no domains are active the engine injects nothing.
106
100
 
107
- See [assets/README.md](assets/README.md) for details.
101
+ ## Configuration
108
102
 
109
- ### CRUD Commands
103
+ | Knob | Where | Effect |
104
+ |------|-------|--------|
105
+ | `RULES_BUDGET_TOKENS` | `.synapse/manifest` | Trimmable-rules token ceiling (default 600). |
106
+ | `HANDOFF_PCT` | `.synapse/manifest` | Handoff threshold as a window fraction (default 0.40). |
107
+ | `CONTEXT_WINDOW` | `.synapse/manifest` | Pin the model window (tokens) for the handoff math. |
108
+ | `WRXN_RULES_BUDGET` | env | Overrides `RULES_BUDGET_TOKENS`. |
109
+ | `WRXN_HANDOFF_PCT` | env | Overrides `HANDOFF_PCT`. |
110
+ | `WRXN_CONTEXT_WINDOW` | env | Forces the model window unconditionally. |
110
111
 
111
- For domain management operations, use the SYNAPSE manager:
112
+ See [invocation & configuration](references/commands.md).
112
113
 
113
- | Command | Purpose |
114
- |---------|---------|
115
- | `*synapse create` | Create new domain + manifest entry |
116
- | `*synapse add` | Add rule to existing domain |
117
- | `*synapse edit` | Edit or remove rule by index |
118
- | `*synapse toggle` | Toggle domain active/inactive |
119
- | `*synapse command` | Create new star-command |
120
- | `*synapse suggest` | Suggest best domain for a rule |
114
+ ## References
121
115
 
122
- Full details: [references/commands.md](references/commands.md)
116
+ | Guide | Covers |
117
+ |-------|--------|
118
+ | [The layer model](references/layers.md) | the L0/L1/L6 assembly, ordering, constitution rendering, output format |
119
+ | [The manifest format](references/manifest.md) | the `.synapse/manifest` keys and scalars |
120
+ | [Domains & rule files](references/domains.md) | the seeded domains, the `RULE_N` format, adding a domain |
121
+ | [Token budget & handoff](references/brackets.md) | the flat budget governor + the non-blocking handoff |
122
+ | [Invocation & configuration](references/commands.md) | how the hook is wired, the env/manifest knobs, troubleshooting |
123
+ | [Templates](assets/README.md) | domain-file and manifest-entry templates |
123
124
 
124
- ## Key Files
125
+ ## Key files
125
126
 
126
127
  | File | Purpose |
127
128
  |------|---------|
128
- | `.claude/hooks/synapse-engine.js` | Hook entry point (UserPromptSubmit) |
129
- | `.aiox-core/core/synapse/engine.js` | SynapseEngine orchestrator |
130
- | `.synapse/manifest` | Domain registry (KEY=VALUE) |
131
- | `.synapse/commands` | Star-command definitions |
132
- | `.claude/commands/synapse/manager.md` | CRUD command router |
129
+ | `.claude/hooks/synapse-engine.cjs` | The engine (UserPromptSubmit hook). |
130
+ | `.claude/constitution.md` | L0 source — the non-negotiable articles. |
131
+ | `.synapse/manifest` | Domain registry + budget/handoff scalars. |
132
+ | `.synapse/global`, `.synapse/pipeline` | Seeded always-on (L1) domains. |
133
+ | `.synapse/routing` | Seeded keyword-recall (L6) domain. |
@@ -1,50 +1,34 @@
1
- # SYNAPSE Assets
1
+ # SYNAPSE templates
2
2
 
3
- Templates for creating custom SYNAPSE domains and manifest entries.
3
+ Templates for adding a SYNAPSE domain by hand. There is no interactive creator — a domain is two
4
+ edits: a rule file in `.synapse/` and a registry entry in `.synapse/manifest`. See
5
+ [domains & rule files](../references/domains.md) and [the manifest format](../references/manifest.md).
4
6
 
5
- ## Templates Location
6
-
7
- Templates are maintained as the single source of truth in the CRUD commands directory:
8
-
9
- | Template | Location |
10
- |----------|----------|
11
- | **Domain template** | `.claude/commands/synapse/templates/domain-template` |
12
- | **Manifest entry template** | `.claude/commands/synapse/templates/manifest-entry-template` |
13
-
14
- These templates are used by the `*synapse create` command to scaffold new domains.
15
-
16
- ## Usage
17
-
18
- To create a new domain using these templates, run:
7
+ ## Domain rule file — `.synapse/<name>`
19
8
 
20
9
  ```
21
- *synapse create
10
+ # Domain: <name> (<always-on L1 | keyword-recall L6>) — <one-line description>
11
+ <NAME>_RULE_0=<first rule>
12
+ <NAME>_RULE_1=<second rule>
22
13
  ```
23
14
 
24
- Or reference the templates directly when creating domains manually.
15
+ `<NAME>` is the uppercase prefix; the file is named for its lowercase form. Rules are numbered
16
+ ascending from 0.
25
17
 
26
- ## Template Formats
18
+ ## Manifest entry — `.synapse/manifest`
27
19
 
28
- ### Domain Template
20
+ Always-on (loads on every prompt):
29
21
 
30
22
  ```
31
- # ==========================================
32
- # SYNAPSE Domain: {DOMAIN_NAME}
33
- # Created: {CURRENT_DATE}
34
- # Description: {DESCRIPTION}
35
- # ==========================================
36
-
37
- # Rules
38
- {DOMAIN_KEY}_RULE_0={FIRST_RULE}
23
+ <NAME>_STATE=active
24
+ <NAME>_ALWAYS_ON=true
39
25
  ```
40
26
 
41
- ### Manifest Entry Template
27
+ Keyword-recall (loads only when a trigger word appears in the prompt):
42
28
 
43
29
  ```
44
- # Layer 6: {domain-name}
45
- {DOMAIN_KEY}_STATE=active
46
- {DOMAIN_KEY}_RECALL={KEYWORDS}
47
- {DOMAIN_KEY}_EXCLUDE=
30
+ <NAME>_STATE=active
31
+ <NAME>_RECALL=word1,word2
48
32
  ```
49
33
 
50
- For the complete KEY=VALUE format specification, see [../references/manifest.md](../references/manifest.md).
34
+ Set `<NAME>_STATE=inactive` (or remove the entry) to stop loading the domain.