sinapse-ai 7.7.4 → 7.7.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.
- package/.codex/delegation-matrix.json +512 -0
- package/.codex/handoff-packet.schema.json +148 -0
- package/.codex/scripts/resolve-codex-delegation.js +205 -0
- package/.codex/tasks/route-sinapse-request.md +7 -5
- package/.sinapse-ai/data/entity-registry.yaml +783 -755
- package/.sinapse-ai/data/registry-update-log.jsonl +3 -0
- package/.sinapse-ai/infrastructure/scripts/validate-codex-delegation.js +292 -0
- package/.sinapse-ai/infrastructure/scripts/validate-codex-sync.js +3 -0
- package/.sinapse-ai/install-manifest.yaml +11 -7
- package/package.json +4 -1
- package/packages/installer/tests/unit/artifact-copy-pipeline/artifact-copy-pipeline.test.js +7 -2
|
@@ -567,3 +567,6 @@
|
|
|
567
567
|
{"timestamp":"2026-04-02T23:48:52.333Z","action":"add","path":".sinapse-ai/infrastructure/scripts/validate-codex-sync.js","trigger":"watcher"}
|
|
568
568
|
{"timestamp":"2026-04-02T23:48:52.333Z","action":"change","path":".sinapse-ai/infrastructure/scripts/validate-parity.js","trigger":"watcher"}
|
|
569
569
|
{"timestamp":"2026-04-02T23:48:52.333Z","action":"change","path":".sinapse-ai/infrastructure/scripts/validate-paths.js","trigger":"watcher"}
|
|
570
|
+
{"timestamp":"2026-04-03T00:26:52.858Z","action":"change","path":".sinapse-ai/infrastructure/scripts/validate-codex-command-registry.js","trigger":"watcher"}
|
|
571
|
+
{"timestamp":"2026-04-03T00:26:52.860Z","action":"add","path":".sinapse-ai/infrastructure/scripts/validate-codex-delegation.js","trigger":"watcher"}
|
|
572
|
+
{"timestamp":"2026-04-03T00:26:52.860Z","action":"change","path":".sinapse-ai/infrastructure/scripts/validate-codex-sync.js","trigger":"watcher"}
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const Ajv2020 = require('ajv/dist/2020');
|
|
7
|
+
const {
|
|
8
|
+
buildHandoffPacket,
|
|
9
|
+
loadDelegationMatrix,
|
|
10
|
+
} = require(path.join(__dirname, '..', '..', '..', '.codex', 'scripts', 'resolve-codex-delegation'));
|
|
11
|
+
const {
|
|
12
|
+
loadRegistry: loadCommandRegistryFile,
|
|
13
|
+
} = require('./validate-codex-command-registry');
|
|
14
|
+
|
|
15
|
+
const REQUIRED_ORCHESTRATORS = Object.freeze([
|
|
16
|
+
'sinapse-orqx',
|
|
17
|
+
'brand-orqx',
|
|
18
|
+
'commercial-orqx',
|
|
19
|
+
'content-orqx',
|
|
20
|
+
'copy-orqx',
|
|
21
|
+
'animations-orqx',
|
|
22
|
+
'design-orqx',
|
|
23
|
+
'finance-orqx',
|
|
24
|
+
'growth-orqx',
|
|
25
|
+
'paidmedia-orqx',
|
|
26
|
+
'product-orqx',
|
|
27
|
+
'research-orqx',
|
|
28
|
+
'claude-orqx',
|
|
29
|
+
'council-orqx',
|
|
30
|
+
'storytelling-orqx',
|
|
31
|
+
'cyber-orqx',
|
|
32
|
+
'cloning-orqx',
|
|
33
|
+
'courses-orqx',
|
|
34
|
+
'swarm-orqx',
|
|
35
|
+
]);
|
|
36
|
+
|
|
37
|
+
function parseArgs(argv = process.argv.slice(2)) {
|
|
38
|
+
const args = new Set(argv);
|
|
39
|
+
return {
|
|
40
|
+
quiet: args.has('--quiet') || args.has('-q'),
|
|
41
|
+
json: args.has('--json'),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function validateCodexDelegation(options = {}) {
|
|
46
|
+
const projectRoot = options.projectRoot || process.cwd();
|
|
47
|
+
const errors = [];
|
|
48
|
+
const warnings = [];
|
|
49
|
+
const requiredOrchestrators =
|
|
50
|
+
options.requiredOrchestrators === false
|
|
51
|
+
? null
|
|
52
|
+
: options.requiredOrchestrators || REQUIRED_ORCHESTRATORS;
|
|
53
|
+
|
|
54
|
+
let matrix;
|
|
55
|
+
try {
|
|
56
|
+
matrix = loadDelegationMatrix(projectRoot);
|
|
57
|
+
} catch (error) {
|
|
58
|
+
errors.push(`Unable to load Codex delegation matrix: ${error.message}`);
|
|
59
|
+
return {
|
|
60
|
+
ok: false,
|
|
61
|
+
errors,
|
|
62
|
+
warnings,
|
|
63
|
+
metrics: { orchestrators: 0, routes: 0 },
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const matrixPath = path.join(projectRoot, '.codex', 'delegation-matrix.json');
|
|
68
|
+
const schemaPath = path.join(projectRoot, matrix.handoffSchema || '.codex/handoff-packet.schema.json');
|
|
69
|
+
if (!fs.existsSync(schemaPath)) {
|
|
70
|
+
errors.push(`Missing handoff schema ${path.relative(projectRoot, schemaPath)}`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let schema = null;
|
|
74
|
+
if (fs.existsSync(schemaPath)) {
|
|
75
|
+
try {
|
|
76
|
+
schema = JSON.parse(fs.readFileSync(schemaPath, 'utf8'));
|
|
77
|
+
} catch (error) {
|
|
78
|
+
errors.push(`Unable to parse handoff schema: ${error.message}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const { registry: commandRegistry, error: commandRegistryError } = loadCommandRegistryFile(projectRoot);
|
|
83
|
+
if (commandRegistryError) {
|
|
84
|
+
errors.push(commandRegistryError);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const orchestrators = matrix.orchestrators || {};
|
|
88
|
+
const frameworkAgents = matrix.frameworkAgents || {};
|
|
89
|
+
const routes = matrix.routes || {};
|
|
90
|
+
|
|
91
|
+
if (requiredOrchestrators) {
|
|
92
|
+
for (const orchestratorId of requiredOrchestrators) {
|
|
93
|
+
if (!orchestrators[orchestratorId]) {
|
|
94
|
+
errors.push(`missing required orchestrator coverage: ${orchestratorId}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
for (const [orchestratorId, orchestratorSpec] of Object.entries(orchestrators)) {
|
|
100
|
+
const sourceOfTruth = path.join(projectRoot, orchestratorSpec.sourceOfTruth || '');
|
|
101
|
+
if (!fs.existsSync(sourceOfTruth)) {
|
|
102
|
+
errors.push(`${orchestratorId}: missing source of truth ${path.relative(projectRoot, sourceOfTruth)}`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (orchestratorSpec.squadDir) {
|
|
106
|
+
const squadDir = path.join(projectRoot, orchestratorSpec.squadDir);
|
|
107
|
+
if (!fs.existsSync(squadDir)) {
|
|
108
|
+
errors.push(`${orchestratorId}: missing squad dir ${path.relative(projectRoot, squadDir)}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (orchestratorSpec.tasksDir) {
|
|
113
|
+
const tasksDir = path.join(projectRoot, orchestratorSpec.tasksDir);
|
|
114
|
+
if (!fs.existsSync(tasksDir)) {
|
|
115
|
+
errors.push(`${orchestratorId}: missing tasks dir ${path.relative(projectRoot, tasksDir)}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
for (const routeId of orchestratorSpec.approvedRoutes || []) {
|
|
120
|
+
if (!routes[routeId]) {
|
|
121
|
+
errors.push(`${orchestratorId}: missing approved route ${routeId}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const routeAliases = new Map();
|
|
127
|
+
const ajv = schema ? new Ajv2020({ allErrors: true, strict: false }) : null;
|
|
128
|
+
const validatePacket = schema ? ajv.compile(schema) : null;
|
|
129
|
+
let routeCount = 0;
|
|
130
|
+
let validatorBackedCount = 0;
|
|
131
|
+
let shimCount = 0;
|
|
132
|
+
let exploratoryCount = 0;
|
|
133
|
+
|
|
134
|
+
for (const [routeId, routeSpec] of Object.entries(routes)) {
|
|
135
|
+
routeCount += 1;
|
|
136
|
+
if (routeSpec.classification === 'validator-backed') validatorBackedCount += 1;
|
|
137
|
+
if (routeSpec.classification === 'codex-only-shim') shimCount += 1;
|
|
138
|
+
if (routeSpec.classification === 'exploratory') exploratoryCount += 1;
|
|
139
|
+
|
|
140
|
+
if (!orchestrators[routeSpec.owner]) {
|
|
141
|
+
errors.push(`${routeId}: unknown route owner ${routeSpec.owner}`);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (!(matrix.routingClasses || []).includes(routeSpec.classification)) {
|
|
145
|
+
errors.push(`${routeId}: invalid classification ${routeSpec.classification}`);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (!(matrix.requestTypes || []).includes(routeSpec.requestType)) {
|
|
149
|
+
errors.push(`${routeId}: invalid request type ${routeSpec.requestType}`);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
for (const alias of [routeId, ...(routeSpec.aliases || [])]) {
|
|
153
|
+
const normalized = String(alias || '').trim().toLowerCase();
|
|
154
|
+
const owner = routeAliases.get(normalized);
|
|
155
|
+
if (owner && owner !== routeId) {
|
|
156
|
+
errors.push(`duplicate delegation route alias "${normalized}" claimed by ${owner} and ${routeId}`);
|
|
157
|
+
} else {
|
|
158
|
+
routeAliases.set(normalized, routeId);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
for (const resource of routeSpec.resources || []) {
|
|
163
|
+
const resourcePath = path.join(projectRoot, resource);
|
|
164
|
+
if (!fs.existsSync(resourcePath)) {
|
|
165
|
+
errors.push(`${routeId}: missing resource ${path.relative(projectRoot, resourcePath)}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (!Array.isArray(routeSpec.delegationChain) || routeSpec.delegationChain.length === 0) {
|
|
170
|
+
errors.push(`${routeId}: missing delegation chain`);
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (routeSpec.delegationChain[0].from !== routeSpec.owner) {
|
|
175
|
+
errors.push(`${routeId}: first delegation step must start from the route owner`);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
for (const [index, step] of routeSpec.delegationChain.entries()) {
|
|
179
|
+
const stepLabel = `${routeId}.step${index + 1}`;
|
|
180
|
+
|
|
181
|
+
if (step.fromType === 'orqx' && !orchestrators[step.from]) {
|
|
182
|
+
errors.push(`${stepLabel}: unknown from orchestrator ${step.from}`);
|
|
183
|
+
}
|
|
184
|
+
if (step.fromType === 'framework-agent' && !frameworkAgents[step.from]) {
|
|
185
|
+
errors.push(`${stepLabel}: unknown from framework agent ${step.from}`);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (step.toType === 'orqx') {
|
|
189
|
+
if (!orchestrators[step.to]) {
|
|
190
|
+
errors.push(`${stepLabel}: unknown target orchestrator ${step.to}`);
|
|
191
|
+
}
|
|
192
|
+
} else if (step.toType === 'framework-agent') {
|
|
193
|
+
if (!frameworkAgents[step.to]) {
|
|
194
|
+
errors.push(`${stepLabel}: unknown target framework agent ${step.to}`);
|
|
195
|
+
}
|
|
196
|
+
if (step.resolver !== 'command-registry') {
|
|
197
|
+
errors.push(`${stepLabel}: framework-agent steps must use resolver "command-registry"`);
|
|
198
|
+
}
|
|
199
|
+
const registryAgent = commandRegistry?.agents?.[frameworkAgents[step.to]?.registryAgentId || step.to];
|
|
200
|
+
if (!registryAgent) {
|
|
201
|
+
errors.push(`${stepLabel}: missing command registry entry for ${step.to}`);
|
|
202
|
+
} else if (!registryAgent.commands?.[step.command]) {
|
|
203
|
+
errors.push(`${stepLabel}: missing command registry command ${step.to}.${step.command}`);
|
|
204
|
+
}
|
|
205
|
+
} else if (step.toType === 'specialist') {
|
|
206
|
+
const specialistPath = step.path
|
|
207
|
+
? path.join(projectRoot, step.path)
|
|
208
|
+
: path.join(projectRoot, '.codex', 'agents', `${step.to}.md`);
|
|
209
|
+
if (!fs.existsSync(specialistPath)) {
|
|
210
|
+
errors.push(`${stepLabel}: missing specialist path ${path.relative(projectRoot, specialistPath)}`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (step.path) {
|
|
215
|
+
const stepPath = path.join(projectRoot, step.path);
|
|
216
|
+
if (!fs.existsSync(stepPath)) {
|
|
217
|
+
errors.push(`${stepLabel}: missing path ${path.relative(projectRoot, stepPath)}`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (step.task) {
|
|
222
|
+
const taskPath = path.join(projectRoot, step.task);
|
|
223
|
+
if (!fs.existsSync(taskPath)) {
|
|
224
|
+
errors.push(`${stepLabel}: missing task ${path.relative(projectRoot, taskPath)}`);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (validatePacket) {
|
|
230
|
+
const packet = buildHandoffPacket(routeId, projectRoot, matrix);
|
|
231
|
+
const valid = validatePacket(packet);
|
|
232
|
+
if (!valid) {
|
|
233
|
+
errors.push(
|
|
234
|
+
`${routeId}: handoff packet failed schema validation ${ajv.errorsText(validatePacket.errors, { separator: '; ' })}`,
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return {
|
|
241
|
+
ok: errors.length === 0,
|
|
242
|
+
errors,
|
|
243
|
+
warnings,
|
|
244
|
+
metrics: {
|
|
245
|
+
matrixPath: path.relative(projectRoot, matrixPath),
|
|
246
|
+
orchestrators: Object.keys(orchestrators).length,
|
|
247
|
+
routes: routeCount,
|
|
248
|
+
validatorBackedRoutes: validatorBackedCount,
|
|
249
|
+
codexOnlyShimRoutes: shimCount,
|
|
250
|
+
exploratoryRoutes: exploratoryCount,
|
|
251
|
+
},
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function formatHumanReport(result) {
|
|
256
|
+
if (result.ok) {
|
|
257
|
+
return `OK Codex delegation validation passed (orchestrators: ${result.metrics.orchestrators}, routes: ${result.metrics.routes})`;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return [
|
|
261
|
+
`X Codex delegation validation failed (${result.errors.length} issue(s))`,
|
|
262
|
+
...result.errors.map((error) => `- ${error}`),
|
|
263
|
+
].join('\n');
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function main() {
|
|
267
|
+
const args = parseArgs();
|
|
268
|
+
const result = validateCodexDelegation(args);
|
|
269
|
+
|
|
270
|
+
if (!args.quiet) {
|
|
271
|
+
if (args.json) {
|
|
272
|
+
console.log(JSON.stringify(result, null, 2));
|
|
273
|
+
} else {
|
|
274
|
+
console.log(formatHumanReport(result));
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (!result.ok) {
|
|
279
|
+
process.exitCode = 1;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if (require.main === module) {
|
|
284
|
+
main();
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
module.exports = {
|
|
288
|
+
parseArgs,
|
|
289
|
+
validateCodexDelegation,
|
|
290
|
+
formatHumanReport,
|
|
291
|
+
REQUIRED_ORCHESTRATORS,
|
|
292
|
+
};
|
|
@@ -6,6 +6,7 @@ const path = require('path');
|
|
|
6
6
|
const { spawnSync } = require('child_process');
|
|
7
7
|
const { loadCodexCatalogConfig } = require('./codex-parity/catalog');
|
|
8
8
|
const { validateCodexCommandRegistry } = require('./validate-codex-command-registry');
|
|
9
|
+
const { validateCodexDelegation } = require('./validate-codex-delegation');
|
|
9
10
|
const { validateCodexIntegration } = require('./validate-codex-integration');
|
|
10
11
|
const { validateCodexSkills } = require('./codex-skills-sync/validate');
|
|
11
12
|
const { validatePaths } = require('./validate-paths');
|
|
@@ -59,6 +60,7 @@ function validateCodexSync(options = {}, deps = {}) {
|
|
|
59
60
|
const config = loadCodexCatalogConfig(projectRoot);
|
|
60
61
|
const runLegacyValidate = deps.runLegacyCodexValidate || runLegacyCodexValidate;
|
|
61
62
|
const runCodexCommands = deps.validateCodexCommandRegistry || validateCodexCommandRegistry;
|
|
63
|
+
const runCodexDelegation = deps.validateCodexDelegation || validateCodexDelegation;
|
|
62
64
|
const runCodexIntegration = deps.validateCodexIntegration || validateCodexIntegration;
|
|
63
65
|
const runCodexSkills = deps.validateCodexSkills || validateCodexSkills;
|
|
64
66
|
const runPaths = deps.validatePaths || validatePaths;
|
|
@@ -71,6 +73,7 @@ function validateCodexSync(options = {}, deps = {}) {
|
|
|
71
73
|
const checks = [
|
|
72
74
|
normalizeCheck('codex-integration', runCodexIntegration({ projectRoot, quiet: true })),
|
|
73
75
|
normalizeCheck('codex-commands', runCodexCommands({ projectRoot, quiet: true })),
|
|
76
|
+
normalizeCheck('codex-delegation', runCodexDelegation({ projectRoot, quiet: true })),
|
|
74
77
|
normalizeCheck('codex-skills', runCodexSkills({ projectRoot, strict: true, quiet: true })),
|
|
75
78
|
normalizeCheck('paths', runPaths({ projectRoot, quiet: true })),
|
|
76
79
|
];
|
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
# - SHA256 hashes for change detection
|
|
8
8
|
# - File types for categorization
|
|
9
9
|
#
|
|
10
|
-
version: 7.7.
|
|
11
|
-
generated_at: "2026-04-03T00:
|
|
10
|
+
version: 7.7.5
|
|
11
|
+
generated_at: "2026-04-03T00:28:11.575Z"
|
|
12
12
|
generator: scripts/generate-install-manifest.js
|
|
13
|
-
file_count:
|
|
13
|
+
file_count: 1118
|
|
14
14
|
files:
|
|
15
15
|
- path: cli/commands/config/index.js
|
|
16
16
|
hash: sha256:66f111eceef0f60fa0a8904add783b615d55b01d5fe36408623c3dd828e702f6
|
|
@@ -1237,9 +1237,9 @@ files:
|
|
|
1237
1237
|
type: data
|
|
1238
1238
|
size: 9586
|
|
1239
1239
|
- path: data/entity-registry.yaml
|
|
1240
|
-
hash: sha256:
|
|
1240
|
+
hash: sha256:e3e57f3070134b76851762a0666b665228f061d3ff37ee513e7b6ae5dcef3b62
|
|
1241
1241
|
type: data
|
|
1242
|
-
size:
|
|
1242
|
+
size: 515807
|
|
1243
1243
|
- path: data/learned-patterns.yaml
|
|
1244
1244
|
hash: sha256:24ac0b160615583a0ff783d3da8af80b7f94191575d6db2054ec8e10a3f945dc
|
|
1245
1245
|
type: data
|
|
@@ -3432,14 +3432,18 @@ files:
|
|
|
3432
3432
|
hash: sha256:a37a4c5fc8a4c3a7ce7ba240aeea16abc0a75871751f66eeb84991604ff066bf
|
|
3433
3433
|
type: script
|
|
3434
3434
|
size: 7266
|
|
3435
|
+
- path: infrastructure/scripts/validate-codex-delegation.js
|
|
3436
|
+
hash: sha256:a71224ad31b3a28bcc26953f75bbd6387686b3b906404c833f52b8dfff306384
|
|
3437
|
+
type: script
|
|
3438
|
+
size: 9532
|
|
3435
3439
|
- path: infrastructure/scripts/validate-codex-integration.js
|
|
3436
3440
|
hash: sha256:c553cc493ddbfecf41b865f8a1075df56b6500c3b2b315bae8b7e7bcec4db85a
|
|
3437
3441
|
type: script
|
|
3438
3442
|
size: 4742
|
|
3439
3443
|
- path: infrastructure/scripts/validate-codex-sync.js
|
|
3440
|
-
hash: sha256:
|
|
3444
|
+
hash: sha256:31bcfc0cdf307e7c14064eaf0ddbf99a14344c21306937c9a7d9cc7ebba260f8
|
|
3441
3445
|
type: script
|
|
3442
|
-
size:
|
|
3446
|
+
size: 4679
|
|
3443
3447
|
- path: infrastructure/scripts/validate-output-pattern.js
|
|
3444
3448
|
hash: sha256:91111d656e8d7b38a20a1bda753e663b74318f75cdab2025c7e0b84c775fc83d
|
|
3445
3449
|
type: script
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sinapse-ai",
|
|
3
|
-
"version": "7.7.
|
|
3
|
+
"version": "7.7.5",
|
|
4
4
|
"description": "SINAPSE AI: Framework de orquestracao de IA — 18 squads, 175 agentes especializados",
|
|
5
5
|
"bin": {
|
|
6
6
|
"sinapse": "bin/sinapse.js",
|
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
".claude/hooks/",
|
|
23
23
|
".codex/catalog.json",
|
|
24
24
|
".codex/command-registry.json",
|
|
25
|
+
".codex/delegation-matrix.json",
|
|
26
|
+
".codex/handoff-packet.schema.json",
|
|
25
27
|
".codex/instructions.md",
|
|
26
28
|
".codex/agents/",
|
|
27
29
|
".codex/scripts/",
|
|
@@ -82,6 +84,7 @@
|
|
|
82
84
|
"validate:codex-sync": "node .sinapse-ai/infrastructure/scripts/validate-codex-sync.js",
|
|
83
85
|
"validate:codex-integration": "node .sinapse-ai/infrastructure/scripts/validate-codex-integration.js",
|
|
84
86
|
"validate:codex-commands": "node .sinapse-ai/infrastructure/scripts/validate-codex-command-registry.js",
|
|
87
|
+
"validate:codex-delegation": "node .sinapse-ai/infrastructure/scripts/validate-codex-delegation.js",
|
|
85
88
|
"sync:skills:codex": "node .sinapse-ai/infrastructure/scripts/codex-skills-sync/index.js",
|
|
86
89
|
"sync:skills:codex:global": "node .sinapse-ai/infrastructure/scripts/codex-skills-sync/index.js --global --global-only",
|
|
87
90
|
"validate:codex-skills": "node .sinapse-ai/infrastructure/scripts/codex-skills-sync/validate.js --strict",
|
|
@@ -193,12 +193,17 @@ describe('artifact-copy-pipeline (Story INS-4.3)', () => {
|
|
|
193
193
|
expect(config.timeout).toBe(10);
|
|
194
194
|
});
|
|
195
195
|
|
|
196
|
-
test('covers all
|
|
196
|
+
test('covers all known hooks', () => {
|
|
197
197
|
const keys = Object.keys(HOOK_EVENT_MAP);
|
|
198
|
-
expect(keys).toHaveLength(
|
|
198
|
+
expect(keys).toHaveLength(8);
|
|
199
199
|
expect(keys).toContain('synapse-engine.cjs');
|
|
200
200
|
expect(keys).toContain('code-intel-pretool.cjs');
|
|
201
201
|
expect(keys).toContain('precompact-session-digest.cjs');
|
|
202
|
+
expect(keys).toContain('enforce-architecture-first.cjs');
|
|
203
|
+
expect(keys).toContain('enforce-story-gate.cjs');
|
|
204
|
+
expect(keys).toContain('write-path-validation.cjs');
|
|
205
|
+
expect(keys).toContain('enforce-delegation.cjs');
|
|
206
|
+
expect(keys).toContain('secret-scanning.cjs');
|
|
202
207
|
});
|
|
203
208
|
|
|
204
209
|
test('DEFAULT_HOOK_CONFIG falls back to UserPromptSubmit', () => {
|