sinapse-ai 1.9.0 → 1.10.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 (94) hide show
  1. package/.claude/rules/mandatory-delegation.md +1 -1
  2. package/.codex/delegation-matrix.json +4 -3
  3. package/.codex/delegation-parity.json +4 -3
  4. package/.codex/instructions.md +2 -2
  5. package/.sinapse-ai/constitution.md +2 -2
  6. package/.sinapse-ai/core/doctor/checks/git-hooks.js +76 -10
  7. package/.sinapse-ai/core/execution/subagent-dispatcher.js +1 -1
  8. package/.sinapse-ai/core/synapse/engine.js +15 -0
  9. package/.sinapse-ai/data/entity-registry.yaml +13 -13
  10. package/.sinapse-ai/development/agents/snps-orqx.md +4 -4
  11. package/.sinapse-ai/git-hooks/lib/secret-scanner-core.js +76 -4
  12. package/.sinapse-ai/git-hooks/pre-push +7 -1
  13. package/.sinapse-ai/install-manifest.yaml +9 -9
  14. package/AGENTS.md +4 -4
  15. package/CHANGELOG.md +1257 -0
  16. package/README.en.md +4 -3
  17. package/README.md +5 -6
  18. package/bin/commands/install.js +6 -3
  19. package/bin/commands/uninstall.js +2 -2
  20. package/bin/sinapse.js +20 -0
  21. package/bin/utils/secret-scanner-core.js +76 -4
  22. package/docs/agent-reference-guide.md +1 -1
  23. package/docs/framework/architecture-overview.md +4 -4
  24. package/docs/framework/guiding-principles.md +9 -9
  25. package/docs/getting-started.md +1 -1
  26. package/docs/guides/agent-reference.md +1 -1
  27. package/docs/guides/codex-config.md +4 -5
  28. package/docs/pt/architecture/sub-orqx-pattern.md +20 -18
  29. package/package.json +8 -2
  30. package/packages/installer/src/installer/git-hooks-installer.js +3 -1
  31. package/packages/installer/src/installer/sinapse-ai-installer.js +32 -7
  32. package/packages/installer/src/wizard/ide-config-generator.js +9 -1
  33. package/packages/installer/src/wizard/index.js +3 -4
  34. package/scripts/regenerate-orqx-stubs.ps1 +0 -1
  35. package/scripts/sync-counts.js +10 -2
  36. package/scripts/sync-squad-yaml-components.js +108 -6
  37. package/scripts/validate-article-vii.js +68 -7
  38. package/scripts/validate-squad-orqx.js +19 -9
  39. package/sinapse/agents/sinapse-orqx.md +4 -4
  40. package/sinapse/agents/snps-orqx.md +4 -4
  41. package/sinapse/knowledge-base/routing-catalog.md +1 -1
  42. package/sinapse/tasks/diagnose-and-route.md +1 -1
  43. package/sinapse/tasks/squad-status-report.md +1 -1
  44. package/squads/claude-code-mastery/agents/claude-mastery-chief.md +1 -1
  45. package/squads/claude-code-mastery/agents/hooks-architect.md +60 -68
  46. package/squads/claude-code-mastery/knowledge-base/swarm-orchestration-patterns.md +1 -1
  47. package/squads/claude-code-mastery/tasks/audit-setup.md +1 -1
  48. package/squads/claude-code-mastery/workflows/optimization-cycle.yaml +4 -4
  49. package/squads/claude-code-mastery/workflows/project-setup-cycle.yaml +4 -4
  50. package/squads/squad-animations/README.md +1 -1
  51. package/squads/squad-cloning/README.md +1 -1
  52. package/squads/squad-commercial/README.md +1 -1
  53. package/squads/squad-content/README.md +1 -1
  54. package/squads/squad-copy/README.md +1 -1
  55. package/squads/squad-council/README.md +1 -1
  56. package/squads/squad-courses/README.md +1 -1
  57. package/squads/squad-cybersecurity/README.md +1 -1
  58. package/squads/squad-design/README.md +1 -1
  59. package/squads/squad-finance/README.md +1 -1
  60. package/squads/squad-growth/README.md +1 -1
  61. package/squads/squad-paidmedia/README.md +1 -1
  62. package/squads/squad-product/README.md +1 -1
  63. package/squads/squad-research/README.md +1 -1
  64. package/squads/squad-storytelling/README.md +1 -1
  65. package/.sinapse-ai/core/memory/__tests__/active-modules.verify.js +0 -265
  66. package/.sinapse-ai/core/permissions/__tests__/permission-mode.test.js +0 -293
  67. package/.sinapse-ai/infrastructure/tests/project-status-loader.test.js +0 -569
  68. package/.sinapse-ai/infrastructure/tests/regression-suite-v2.md +0 -622
  69. package/.sinapse-ai/infrastructure/tests/validate-module.js +0 -98
  70. package/.sinapse-ai/infrastructure/tests/worktree-manager.test.js +0 -620
  71. package/.sinapse-ai/workflow-intelligence/__tests__/confidence-scorer.test.js +0 -335
  72. package/.sinapse-ai/workflow-intelligence/__tests__/integration.test.js +0 -340
  73. package/.sinapse-ai/workflow-intelligence/__tests__/suggestion-engine.test.js +0 -438
  74. package/.sinapse-ai/workflow-intelligence/__tests__/wave-analyzer.test.js +0 -448
  75. package/.sinapse-ai/workflow-intelligence/__tests__/workflow-registry.test.js +0 -303
  76. package/packages/installer/src/__tests__/performance-benchmark.js +0 -383
  77. package/packages/installer/tests/integration/environment-configuration.test.js +0 -332
  78. package/packages/installer/tests/integration/wizard-detection.test.js +0 -352
  79. package/packages/installer/tests/unit/artifact-copy-pipeline/artifact-copy-pipeline.test.js +0 -402
  80. package/packages/installer/tests/unit/claude-md-template-v5/claude-md-template-v5.test.js +0 -193
  81. package/packages/installer/tests/unit/config-validator.test.js +0 -315
  82. package/packages/installer/tests/unit/detection/detect-project-type.test.js +0 -539
  83. package/packages/installer/tests/unit/doctor/doctor-checks.test.js +0 -675
  84. package/packages/installer/tests/unit/doctor/doctor-orchestrator.test.js +0 -192
  85. package/packages/installer/tests/unit/entity-registry-bootstrap.test.js +0 -192
  86. package/packages/installer/tests/unit/env-template.test.js +0 -187
  87. package/packages/installer/tests/unit/generate-settings-json/generate-settings-json.test.js +0 -310
  88. package/packages/installer/tests/unit/git-hooks-installer.test.js +0 -262
  89. package/packages/installer/tests/unit/ide-sync-integration/ide-sync-integration.test.js +0 -231
  90. package/packages/installer/tests/unit/merger/env-merger.test.js +0 -191
  91. package/packages/installer/tests/unit/merger/markdown-merger.test.js +0 -262
  92. package/packages/installer/tests/unit/merger/strategies.test.js +0 -154
  93. package/packages/installer/tests/unit/merger/yaml-merger.test.js +0 -328
  94. package/packages/sinapse-install/tests/unit/chrome-brain.smoke.test.js +0 -66
@@ -320,14 +320,13 @@ function llmLabel(selectedLLM) {
320
320
  }
321
321
 
322
322
  /**
323
- * 19 orqx agent definitions to install globally.
323
+ * 18 orqx agent definitions to install globally (17 squad orqx + 1 master).
324
324
  * Each entry maps agent-id to its squad directory name.
325
325
  */
326
326
  const GLOBAL_AGENTS = [
327
327
  { id: 'sinapse-orqx', squad: 'sinapse' },
328
328
  { id: 'animations-orqx', squad: 'squad-animations' },
329
329
  { id: 'brand-orqx', squad: 'squad-brand' },
330
- { id: 'claude-orqx', squad: 'squad-claude' },
331
330
  { id: 'cloning-orqx', squad: 'squad-cloning' },
332
331
  { id: 'commercial-orqx', squad: 'squad-commercial' },
333
332
  { id: 'content-orqx', squad: 'squad-content' },
@@ -342,7 +341,7 @@ const GLOBAL_AGENTS = [
342
341
  { id: 'product-orqx', squad: 'squad-product' },
343
342
  { id: 'research-orqx', squad: 'squad-research' },
344
343
  { id: 'storytelling-orqx', squad: 'squad-storytelling' },
345
- { id: 'swarm-orqx', squad: 'squad-claude' },
344
+ { id: 'swarm-orqx', squad: 'claude-code-mastery' },
346
345
  ];
347
346
 
348
347
  /**
@@ -381,7 +380,7 @@ function buildAgentTemplate(agentId, squadName, homedir) {
381
380
  }
382
381
 
383
382
  /**
384
- * Install 19 global orqx agent definitions to ~/.claude/agents/
383
+ * Install 18 global orqx agent definitions to ~/.claude/agents/
385
384
  * Each file is a small markdown that points to the full agent definition
386
385
  * inside the user's ~/.sinapse/{squad}/ directory.
387
386
  *
@@ -9,7 +9,6 @@ $ErrorActionPreference = 'Stop'
9
9
  $mapping = @(
10
10
  @{ id = 'animations-orqx'; squad = 'squad-animations' }
11
11
  @{ id = 'brand-orqx'; squad = 'squad-brand' }
12
- @{ id = 'claude-orqx'; squad = 'squad-claude' }
13
12
  @{ id = 'cloning-orqx'; squad = 'squad-cloning' }
14
13
  @{ id = 'commercial-orqx'; squad = 'squad-commercial' }
15
14
  @{ id = 'content-orqx'; squad = 'squad-content' }
@@ -28,6 +28,11 @@ function countMatching(dir, predicate) {
28
28
  let count = 0;
29
29
  for (const entry of entries) {
30
30
  const full = path.join(dir, entry.name);
31
+ // Never count anything under a _deprecated/ folder — those entities are
32
+ // retired (e.g. squads/claude-code-mastery/_deprecated/claude-orqx.md).
33
+ if (entry.name === '_deprecated' || full.includes(`${path.sep}_deprecated${path.sep}`)) {
34
+ continue;
35
+ }
31
36
  if (entry.isDirectory()) {
32
37
  count += countMatching(full, predicate);
33
38
  } else if (predicate(full, entry.name)) {
@@ -52,8 +57,11 @@ function isTaskFile(fullPath, filename) {
52
57
  return fullPath.includes(`${path.sep}tasks${path.sep}`);
53
58
  }
54
59
 
55
- function isOrqxFile(_fullPath, filename) {
56
- return filename.endsWith('-orqx.md');
60
+ function isOrqxFile(fullPath, filename) {
61
+ // Only count orqx personas that live under a squad's agents/ directory.
62
+ // Guards against stray/retired orqx files outside the canonical location.
63
+ if (!filename.endsWith('-orqx.md')) return false;
64
+ return fullPath.includes(`${path.sep}agents${path.sep}`);
57
65
  }
58
66
 
59
67
  function countSquadDirs() {
@@ -15,9 +15,18 @@
15
15
  * `components.agents` block based on disk reality, restoring manifest
16
16
  * as a reliable source of truth.
17
17
  *
18
+ * --check mode (E8 / auditoria-pos-190):
19
+ * Beyond detecting a MISSING block, --check now RECONCILES the declared
20
+ * agents list against the actual `.md` files on disk. It fails (exit 1) when:
21
+ * - a squad.yaml is missing the components.agents block (needs-update), OR
22
+ * - the declared list diverges from disk (drift): a declared agent has no
23
+ * file, or an agent file is not declared.
24
+ * Inline `# comments` after a filename are stripped before comparison, so a
25
+ * `- foo.md # Persona — Role` entry reconciles cleanly against `foo.md`.
26
+ *
18
27
  * Usage:
19
28
  * node scripts/sync-squad-yaml-components.js # apply changes
20
- * node scripts/sync-squad-yaml-components.js --check # report only, no write
29
+ * node scripts/sync-squad-yaml-components.js --check # report + reconcile, no write
21
30
  */
22
31
 
23
32
  'use strict';
@@ -64,6 +73,61 @@ function hasComponentsAgents(yamlContent) {
64
73
  return false;
65
74
  }
66
75
 
76
+ // parseDeclaredAgents extracts the filenames declared under components.agents.
77
+ // It tolerates inline `# comments` after each filename (several squad.yaml files
78
+ // annotate entries like `- brand-auditor.md # Sentinel — Guardian`). Returns a
79
+ // sorted array of bare filenames, or null if no components.agents block exists.
80
+ function parseDeclaredAgents(yamlContent) {
81
+ const lines = yamlContent.split('\n');
82
+ let inAgents = false;
83
+ let found = false;
84
+ const agents = [];
85
+ for (let i = 0; i < lines.length; i++) {
86
+ const line = lines[i];
87
+ if (!inAgents) {
88
+ if (/^components:\s*$/.test(line)) {
89
+ // scan forward for the agents: sub-key (block style)
90
+ for (let j = i + 1; j < lines.length; j++) {
91
+ if (/^ {2}agents:/.test(lines[j])) {
92
+ inAgents = true;
93
+ found = true;
94
+ i = j; // continue after the agents: header
95
+ break;
96
+ }
97
+ // a new top-level key ends the components: block
98
+ if (/^\S/.test(lines[j]) && !/^\s*#/.test(lines[j])) break;
99
+ }
100
+ }
101
+ continue;
102
+ }
103
+ // Inside the agents list: collect ` - name.md` items, stop at dedent.
104
+ const itemMatch = line.match(/^ {4}-\s*(.+?)\s*$/);
105
+ if (itemMatch) {
106
+ // strip an inline comment (`# ...`) and surrounding quotes/whitespace
107
+ let value = itemMatch[1].replace(/\s+#.*$/, '').trim();
108
+ value = value.replace(/^["']|["']$/g, '').trim();
109
+ if (value) agents.push(value);
110
+ continue;
111
+ }
112
+ // blank line inside the list is tolerated; anything else dedented ends it
113
+ if (line.trim() === '') continue;
114
+ if (!/^ {4}/.test(line)) break;
115
+ }
116
+ if (!found) return null;
117
+ return agents.sort();
118
+ }
119
+
120
+ // reconcileAgents compares the declared list against disk reality.
121
+ // Returns { declaredOnly, diskOnly } arrays (empty when in sync).
122
+ function reconcileAgents(declared, diskFiles) {
123
+ const declaredSet = new Set(declared);
124
+ const diskSet = new Set(diskFiles);
125
+ return {
126
+ declaredOnly: declared.filter((f) => !diskSet.has(f)), // declared, no file
127
+ diskOnly: diskFiles.filter((f) => !declaredSet.has(f)), // file, not declared
128
+ };
129
+ }
130
+
67
131
  function buildComponentsBlock(agentFiles) {
68
132
  const lines = ['', '# ════════════════════════════════════════════════════', '# COMPONENTS — declared agents (synced from filesystem)', '# ════════════════════════════════════════════════════', 'components:', ' agents:'];
69
133
  for (const file of agentFiles) {
@@ -83,6 +147,20 @@ function processSquad(squadName) {
83
147
  return { squadName, status: 'no-agents', changes: 0 };
84
148
  }
85
149
  if (hasComponentsAgents(content)) {
150
+ // Block is present — in --check mode, reconcile the declared list vs disk.
151
+ if (CHECK_ONLY) {
152
+ const declared = parseDeclaredAgents(content) || [];
153
+ const { declaredOnly, diskOnly } = reconcileAgents(declared, agents);
154
+ if (declaredOnly.length > 0 || diskOnly.length > 0) {
155
+ return {
156
+ squadName,
157
+ status: 'drift',
158
+ changes: declaredOnly.length + diskOnly.length,
159
+ declaredOnly,
160
+ diskOnly,
161
+ };
162
+ }
163
+ }
86
164
  return { squadName, status: 'already-declared', changes: 0 };
87
165
  }
88
166
  if (CHECK_ONLY) {
@@ -100,11 +178,13 @@ function run() {
100
178
  let updated = 0;
101
179
  let alreadyDeclared = 0;
102
180
  let needsUpdate = 0;
181
+ let drift = 0;
103
182
  let other = 0;
104
183
  for (const r of results) {
105
184
  if (r.status === 'updated') updated++;
106
185
  else if (r.status === 'already-declared') alreadyDeclared++;
107
186
  else if (r.status === 'needs-update') needsUpdate++;
187
+ else if (r.status === 'drift') drift++;
108
188
  else other++;
109
189
  }
110
190
 
@@ -114,17 +194,32 @@ function run() {
114
194
  for (const r of results) {
115
195
  const marker = r.status === 'updated' ? 'UPDATED'
116
196
  : r.status === 'needs-update' ? 'NEEDS UPDATE'
197
+ : r.status === 'drift' ? 'DRIFT'
117
198
  : r.status === 'already-declared' ? 'ok'
118
199
  : r.status.toUpperCase();
119
200
  console.log(` ${marker.padEnd(14)} ${r.squadName} (${r.changes} agent(s))`);
201
+ if (r.status === 'drift') {
202
+ if (r.declaredOnly.length > 0) {
203
+ console.log(` declared but no file: ${r.declaredOnly.join(', ')}`);
204
+ }
205
+ if (r.diskOnly.length > 0) {
206
+ console.log(` file but not declared: ${r.diskOnly.join(', ')}`);
207
+ }
208
+ }
120
209
  }
121
210
  console.log('');
122
- console.log(`Summary: ${alreadyDeclared} already declared, ${updated} updated, ${needsUpdate} need update, ${other} other`);
211
+ console.log(`Summary: ${alreadyDeclared} already declared, ${updated} updated, ${needsUpdate} need update, ${drift} drift, ${other} other`);
123
212
 
124
- if (CHECK_ONLY && needsUpdate > 0) {
213
+ if (CHECK_ONLY && (needsUpdate > 0 || drift > 0)) {
125
214
  console.error('');
126
- console.error('FAIL: some squad.yaml files are missing components.agents.');
127
- console.error('Run `node scripts/sync-squad-yaml-components.js` to apply.');
215
+ if (needsUpdate > 0) {
216
+ console.error('FAIL: some squad.yaml files are missing components.agents.');
217
+ console.error('Run `node scripts/sync-squad-yaml-components.js` to apply.');
218
+ }
219
+ if (drift > 0) {
220
+ console.error('FAIL: some squad.yaml components.agents lists diverge from disk.');
221
+ console.error('Reconcile the declared list with the actual files in squads/{squad}/agents/.');
222
+ }
128
223
  return 1;
129
224
  }
130
225
  return 0;
@@ -134,4 +229,11 @@ if (require.main === module) {
134
229
  process.exit(run());
135
230
  }
136
231
 
137
- module.exports = { run, listSquads, listAgentFiles, hasComponentsAgents };
232
+ module.exports = {
233
+ run,
234
+ listSquads,
235
+ listAgentFiles,
236
+ hasComponentsAgents,
237
+ parseDeclaredAgents,
238
+ reconcileAgents,
239
+ };
@@ -31,6 +31,29 @@ const path = require('path');
31
31
  const { collectCounts } = require('./sync-counts.js');
32
32
 
33
33
  const ROOT = path.resolve(__dirname, '..');
34
+ const CONSTITUTION = path.join(ROOT, '.sinapse-ai', 'constitution.md');
35
+
36
+ /**
37
+ * Count Constitution articles + NON-NEGOTIABLE ones from the canonical source.
38
+ * Articles are `### <Roman>. <Title>` headings; NON-NEGOTIABLE ones carry the
39
+ * `(NON-NEGOTIABLE)` marker in the heading. This is what was drifting in the
40
+ * README ("10 articles" while the constitution had 11) with no guard — now there
41
+ * is one.
42
+ * @returns {{articles:number, nonNegotiable:number}}
43
+ */
44
+ function collectConstitutionCounts() {
45
+ let articles = 0;
46
+ let nonNegotiable = 0;
47
+ try {
48
+ const md = fs.readFileSync(CONSTITUTION, 'utf8');
49
+ const headings = md.match(/^###\s+[IVXLC]+\.\s.*$/gm) || [];
50
+ articles = headings.length;
51
+ nonNegotiable = headings.filter((h) => /\(NON-NEGOTIABLE\)/.test(h)).length;
52
+ } catch {
53
+ // Missing/unreadable constitution → leave zeros; the guards below are no-ops.
54
+ }
55
+ return { articles, nonNegotiable };
56
+ }
34
57
 
35
58
  const TARGETS = [
36
59
  { file: 'README.md', label: 'README PT' },
@@ -44,12 +67,14 @@ const TARGETS = [
44
67
  * Build the set of expected numeric tokens that MUST appear consistently.
45
68
  * Returns an object describing canonical counts and a regex helper.
46
69
  */
47
- function buildExpectations(counts) {
70
+ function buildExpectations(counts, constitution = { articles: 0, nonNegotiable: 0 }) {
48
71
  return {
49
72
  squads: counts.squads,
50
73
  agents: counts.totalAgents,
51
74
  orqx: counts.totalOrqx,
52
75
  tasks: counts.tasks,
76
+ articles: constitution.articles,
77
+ nonNegotiable: constitution.nonNegotiable,
53
78
  };
54
79
  }
55
80
 
@@ -89,6 +114,39 @@ function findDrift(content, expected) {
89
114
  }
90
115
  }
91
116
 
117
+ // Constitution total articles: "<N> artigos"/"<N> articles" NOT immediately
118
+ // part of a NON-NEGOTIABLE clause, plus the shields.io badge
119
+ // "Constitution-<N>%20articles". Guards the exact drift that slipped through
120
+ // before (README said "10 articles" while the constitution had 11).
121
+ if (expected.articles) {
122
+ const artRe = /\b(\d{1,2})\s+(?:artigos|articles)\b(?![^.\n]{0,40}NON-NEGOTIABLE)/gi;
123
+ for (const m of content.matchAll(artRe)) {
124
+ const n = parseInt(m[1], 10);
125
+ if (n !== expected.articles && n >= 5) {
126
+ findings.push({ kind: 'articles', found: n, expected: expected.articles, snippet: m[0].trim() });
127
+ }
128
+ }
129
+ const badgeRe = /Constitution-(\d{1,2})%20articles/gi;
130
+ for (const m of content.matchAll(badgeRe)) {
131
+ const n = parseInt(m[1], 10);
132
+ if (n !== expected.articles) {
133
+ findings.push({ kind: 'articles (badge)', found: n, expected: expected.articles, snippet: m[0] });
134
+ }
135
+ }
136
+ }
137
+
138
+ // Constitution NON-NEGOTIABLE article count: "<N> (desses|of those) artigos
139
+ // sao/are NON-NEGOTIABLE".
140
+ if (expected.nonNegotiable) {
141
+ const nnRe = /\b(\d{1,2})\s+(?:(?:desses|de|of\s+those)\s+)?(?:artigos|articles)\s+(?:sao|são|are)\s+NON-NEGOTIABLE/gi;
142
+ for (const m of content.matchAll(nnRe)) {
143
+ const n = parseInt(m[1], 10);
144
+ if (n !== expected.nonNegotiable) {
145
+ findings.push({ kind: 'NON-NEGOTIABLE articles', found: n, expected: expected.nonNegotiable, snippet: m[0].trim() });
146
+ }
147
+ }
148
+ }
149
+
92
150
  return findings;
93
151
  }
94
152
 
@@ -112,14 +170,17 @@ function main() {
112
170
  const fixMode = args.includes('--fix');
113
171
 
114
172
  const counts = collectCounts();
115
- const expected = buildExpectations(counts);
173
+ const constitution = collectConstitutionCounts();
174
+ const expected = buildExpectations(counts, constitution);
116
175
 
117
176
  console.log('Article VII (Metrics Accuracy) — validacao de drift');
118
177
  console.log('Numeros canonicos (de .sinapse-ai/constitution.md):');
119
- console.log(` squads ${expected.squads}`);
120
- console.log(` agentes ${expected.agents}`);
121
- console.log(` orqx ${expected.orqx}`);
122
- console.log(` tasks ${expected.tasks}`);
178
+ console.log(` squads ${expected.squads}`);
179
+ console.log(` agentes ${expected.agents}`);
180
+ console.log(` orqx ${expected.orqx}`);
181
+ console.log(` tasks ${expected.tasks}`);
182
+ console.log(` artigos ${expected.articles}`);
183
+ console.log(` NON-NEGOTIABLE ${expected.nonNegotiable}`);
123
184
  console.log('');
124
185
 
125
186
  const allDrifts = [];
@@ -173,4 +234,4 @@ if (require.main === module) {
173
234
  main();
174
235
  }
175
236
 
176
- module.exports = { findDrift, buildExpectations, TARGETS };
237
+ module.exports = { findDrift, buildExpectations, collectConstitutionCounts, TARGETS };
@@ -10,11 +10,16 @@
10
10
  *
11
11
  * Checks per orqx file:
12
12
  * 1. File exists at squads/{squad}/agents/{name}-orqx.md
13
- * 2. Contains a YAML code block with `agent:` mapping
14
- * 3. agent.name is a non-empty string
15
- * 4. agent.id is a non-empty string and matches `{squad}/{name}-orqx`
16
- * 5. agent.title is a non-empty string
17
- * 6. persona.role exists
13
+ * 2. Contains a recognized identity block (YAML / frontmatter / Markdown)
14
+ * 3. At least one of agent.name / agent.id / agent.title is present
15
+ * 4. agent.id (when declared) matches `{squad}/{name}-orqx` OR the bare
16
+ * `{name}-orqx` file-base — anything else is a HARD ERROR (id-mismatch)
17
+ * 5. persona.role (or a Role/Papel section) exists — a missing role is a
18
+ * HARD ERROR (persona-role)
19
+ *
20
+ * Rationale (E8 / auditoria-pos-190): id-mismatch and persona-role were
21
+ * previously `warn` only and never blocked, so a malformed orqx (wrong id /
22
+ * no role) passed the gate silently. They now block (exit 1).
18
23
  *
19
24
  * Squad-level checks:
20
25
  * - Every directory under squads/ that has agents/ MUST have at least
@@ -193,22 +198,27 @@ function validateOrqxFile(filePath) {
193
198
  return findings;
194
199
  }
195
200
 
196
- // ID match is a soft check Markdown format often uses bare ID like
197
- // "design-orqx" without the squad prefix. Warn but don't error.
201
+ // ID match is now a HARD check. The tolerance stays: an orqx may declare its id
202
+ // as the squad-prefixed "{squad}/{name}-orqx" OR the bare file-base "{name}-orqx"
203
+ // (Markdown format often omits the squad prefix). Anything else is a real
204
+ // divergence — a malformed orqx that would be reached under the wrong id — and
205
+ // is an ERROR, not a soft warning.
198
206
  if (data.agent.id && data.agent.id !== expectedId) {
199
207
  const fileBaseId = path.basename(filePath, '.md');
200
208
  if (data.agent.id !== fileBaseId) {
201
209
  findings.push({
202
- level: 'warn',
210
+ level: 'error',
203
211
  rule: 'id-mismatch',
204
212
  message: `agent.id="${data.agent.id}" does not match "${expectedId}" or "${fileBaseId}"`,
205
213
  });
206
214
  }
207
215
  }
208
216
 
217
+ // persona.role is now REQUIRED. An orqx with no role declared is malformed —
218
+ // the orchestrator persona is undefined. ERROR, not warning.
209
219
  if (!data.persona || !data.persona.role) {
210
220
  findings.push({
211
- level: 'warn',
221
+ level: 'error',
212
222
  rule: 'persona-role',
213
223
  message: 'persona.role / Role section is missing',
214
224
  });
@@ -360,8 +360,8 @@ routing_table:
360
360
 
361
361
  - squad: claude-code-mastery
362
362
  prefix: claude
363
- orchestrator: claude-orqx (Nucleus)
364
- invocation: "/claude:agents:claude-orqx"
363
+ orchestrator: swarm-orqx (Nexus)
364
+ invocation: "/claude:agents:swarm-orqx"
365
365
  domain: "Claude Code mastery, prompt engineering, MCP, automacao, hooks, skills, plugins, agent teams, context engineering"
366
366
  agents: 11
367
367
  tasks: 51
@@ -652,7 +652,7 @@ relationships:
652
652
  context: "All product strategy, discovery, roadmap"
653
653
  - agent: research-orqx (Prism)
654
654
  context: "All market research, competitive intelligence"
655
- - agent: claude-orqx (Nucleus)
655
+ - agent: swarm-orqx (Nexus)
656
656
  context: "All Claude Code mastery, prompt engineering, MCP"
657
657
  - agent: council-orqx (Zenith)
658
658
  context: "All strategic counsel, mental models, advisory"
@@ -766,7 +766,7 @@ Imperator can provide ecosystem-wide insights by combining capabilities across s
766
766
  | 9 | paidmedia | pm | Apex | Midia paga, Meta/Google Ads |
767
767
  | 10 | product | product | Vector | Produto, discovery, roadmap |
768
768
  | 11 | research | research | Prism | Pesquisa, inteligencia competitiva |
769
- | 12 | claude | claude | Nucleus | Claude Code, prompt engineering |
769
+ | 12 | claude-code-mastery | claude | Nexus | Claude Code, prompt engineering |
770
770
  | 13 | council | council | Zenith | Conselho estrategico, advisory |
771
771
  | 14 | storytelling | narrative | Arc | Storytelling, pitch, apresentacao |
772
772
  | 15 | cybersecurity | cyber | Fortress | Cybersecurity, compliance, pentest |
@@ -267,8 +267,8 @@ routing_table:
267
267
 
268
268
  - squad: claude-code-mastery
269
269
  prefix: claude
270
- orchestrator: claude-orqx (Nucleus)
271
- invocation: "/claude:agents:claude-orqx"
270
+ orchestrator: swarm-orqx (Nexus)
271
+ invocation: "/claude:agents:swarm-orqx"
272
272
  domain: "Claude Code mastery, prompt engineering, MCP, automacao, hooks, skills, plugins, agent teams, context engineering"
273
273
  agents: 11
274
274
  tasks: 51
@@ -559,7 +559,7 @@ relationships:
559
559
  context: "All product strategy, discovery, roadmap"
560
560
  - agent: research-orqx (Prism)
561
561
  context: "All market research, competitive intelligence"
562
- - agent: claude-orqx (Nucleus)
562
+ - agent: swarm-orqx (Nexus)
563
563
  context: "All Claude Code mastery, prompt engineering, MCP"
564
564
  - agent: council-orqx (Zenith)
565
565
  context: "All strategic counsel, mental models, advisory"
@@ -657,7 +657,7 @@ Imperator can provide ecosystem-wide insights by combining capabilities across s
657
657
  | 9 | paidmedia | pm | Apex | Midia paga, Meta/Google Ads |
658
658
  | 10 | product | product | Vector | Produto, discovery, roadmap |
659
659
  | 11 | research | research | Prism | Pesquisa, inteligencia competitiva |
660
- | 12 | claude | claude | Nucleus | Claude Code, prompt engineering |
660
+ | 12 | claude-code-mastery | claude | Nexus | Claude Code, prompt engineering |
661
661
  | 13 | council | council | Zenith | Conselho estrategico, advisory |
662
662
  | 14 | storytelling | narrative | Arc | Storytelling, pitch, apresentacao |
663
663
  | 15 | cybersecurity | cyber | Fortress | Cybersecurity, compliance, pentest |
@@ -17,7 +17,7 @@
17
17
  | 9 | squad-paidmedia | pm | paidmedia-orqx (Apex) | `/pm:agents:paidmedia-orqx` |
18
18
  | 10 | squad-product | product | product-orqx (Vector) | `/product:agents:product-orqx` |
19
19
  | 11 | squad-research | research | research-orqx (Prism) | `/research:agents:research-orqx` |
20
- | 12 | claude-code-mastery | claude | claude-orqx (Orion) | `/claude:agents:claude-orqx` |
20
+ | 12 | claude-code-mastery | claude | swarm-orqx (Nexus) | `/claude:agents:swarm-orqx` |
21
21
  | 13 | squad-council | council | council-orqx (Zenith) | `/council:agents:council-orqx` |
22
22
  | 14 | squad-storytelling | narrative | storytelling-orqx (Arc) | `/narrative:agents:storytelling-orqx` |
23
23
  | 15 | squad-cybersecurity | cyber | cyber-orqx (Fortress) | `/cyber:agents:cyber-orqx` |
@@ -63,7 +63,7 @@ Mapear contra a routing table:
63
63
  | Midia paga/ads | paid-media | pm | Apex | `/pm:agents:paidmedia-orqx` |
64
64
  | Produto/discovery | product-systems | product | Vector | `/product:agents:product-orqx` |
65
65
  | Pesquisa/competitivo | research-intelligence | research | Prism | `/research:agents:research-orqx` |
66
- | Claude Code/prompts | claude-mastery | claude | Orion | `/claude:agents:claude-orqx` |
66
+ | Claude Code/prompts | claude-mastery | claude | Nexus | `/claude:agents:swarm-orqx` |
67
67
  | Estrategia/advisory | strategic-council | council | Zenith | `/council:agents:council-orqx` |
68
68
  | Narrativa/pitch | narrative-masters | narrative | Arc | `/narrative:agents:storytelling-orqx` |
69
69
  | Seguranca/compliance | cyber-defense | cyber | Fortress | `/cyber:agents:cyber-orqx` |
@@ -111,7 +111,7 @@ QUICK ACCESS — HOW TO INVOKE:
111
111
  /pm:agents:paidmedia-orqx → Midia Paga
112
112
  /product:agents:product-orqx → Produto
113
113
  /research:agents:research-orqx → Pesquisa
114
- /claude:agents:claude-orqx → Claude Mastery
114
+ /claude:agents:swarm-orqx → Claude Mastery
115
115
  /council:agents:council-orqx → Conselho
116
116
  /narrative:agents:storytelling-orqx → Narrativa
117
117
  /cyber:agents:cyber-orqx → Seguranca
@@ -195,7 +195,7 @@ sinapse_awareness:
195
195
  - 14 workflow definitions in .sinapse-ai/development/workflows/
196
196
  - L1-L4 boundary protection model
197
197
  - Entity registry with 740+ entities
198
- - Python hook system in .sinapse-ai/monitor/hooks/
198
+ - Hook system: runtime grounding hooks in .sinapse-ai/hooks/ (wired via .claude/settings.json) + git hooks in .sinapse-ai/git-hooks/ (core.hooksPath)
199
199
  - Template engine with Handlebars (.hbs)
200
200
  - Quality gates (Layer 1-4: pre-commit, CI, pre-push, deployment)
201
201
  - CLI: sinapse doctor, sinapse graph, sinapse workers, sinapse manifest, etc.