arkgate 2.7.0 → 2.8.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/CHANGELOG.md +45 -1
- package/README.md +8 -0
- package/bin/lib/agent-gates.mjs +48 -228
- package/bin/lib/architecture-scan.mjs +20 -0
- package/bin/lib/ast-scan.mjs +232 -4
- package/bin/lib/codex-home.mjs +320 -0
- package/bin/lib/doctor-plan.mjs +2 -0
- package/bin/lib/remediation.mjs +44 -12
- package/bin/lib/ts-resolve.mjs +5 -4
- package/dist/index.cjs +417 -338
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -9
- package/dist/index.d.ts +29 -9
- package/dist/index.js +417 -338
- package/dist/index.js.map +1 -1
- package/dist/nestjs/index.cjs +452 -373
- package/dist/nestjs/index.cjs.map +1 -1
- package/dist/nestjs/index.d.cts +1 -1
- package/dist/nestjs/index.d.ts +1 -1
- package/dist/nestjs/index.js +452 -373
- package/dist/nestjs/index.js.map +1 -1
- package/dist/runtime/index.cjs +417 -338
- package/dist/runtime/index.cjs.map +1 -1
- package/dist/runtime/index.d.cts +1 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +417 -338
- package/dist/runtime/index.js.map +1 -1
- package/dist/{types-CP3KkwZt.d.cts → types-CSJhEOk2.d.cts} +34 -0
- package/dist/{types-CP3KkwZt.d.ts → types-CSJhEOk2.d.ts} +34 -0
- package/docs/agent-guide.md +1 -1
- package/docs/ai-gates.md +41 -7
- package/docs/brownfield-adoption.md +7 -0
- package/docs/demos/03-copilot-autopilot.md +3 -2
- package/docs/enthusiast/reference-commands.md +2 -2
- package/docs/package-surface.md +1 -1
- package/docs/production-hardening.md +11 -4
- package/package.json +2 -1
- package/server.json +2 -2
- package/templates/skills/ark-explain.md +3 -2
- package/templates/skills/ark-loop.md +2 -1
package/dist/nestjs/index.js
CHANGED
|
@@ -81,41 +81,6 @@ function createAuditTrail(options = {}) {
|
|
|
81
81
|
);
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
// src/kernel/intent/validateIntentName.ts
|
|
85
|
-
var ALLOWED_PREFIXES = [
|
|
86
|
-
"Domain.",
|
|
87
|
-
"Application.",
|
|
88
|
-
"Adapter.",
|
|
89
|
-
"Workflow.",
|
|
90
|
-
"Job.",
|
|
91
|
-
"Presentation.",
|
|
92
|
-
"Reporting.",
|
|
93
|
-
"Metadata.",
|
|
94
|
-
"Security.",
|
|
95
|
-
"Audit.",
|
|
96
|
-
"Observability.",
|
|
97
|
-
"Kernel."
|
|
98
|
-
];
|
|
99
|
-
function validateIntentName(name) {
|
|
100
|
-
if (!name || typeof name !== "string") {
|
|
101
|
-
return { valid: false, reason: "Intent name must be a non-empty string" };
|
|
102
|
-
}
|
|
103
|
-
if (!ALLOWED_PREFIXES.some((p) => name.startsWith(p))) {
|
|
104
|
-
return {
|
|
105
|
-
valid: false,
|
|
106
|
-
reason: `Intent "${name}" must start with one of: ${ALLOWED_PREFIXES.join(", ")}`
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
const rest = name.slice(name.indexOf(".") + 1);
|
|
110
|
-
if (!rest || !/^[A-Za-z][A-Za-z0-9_.]*$/.test(rest)) {
|
|
111
|
-
return {
|
|
112
|
-
valid: false,
|
|
113
|
-
reason: `Intent "${name}" has an invalid segment after the layer prefix`
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
return { valid: true };
|
|
117
|
-
}
|
|
118
|
-
|
|
119
84
|
// src/kernel/policy/PolicyViolationError.ts
|
|
120
85
|
var PolicyViolationError = class extends Error {
|
|
121
86
|
violations;
|
|
@@ -382,12 +347,74 @@ var ObservedLayerFlowViolationError = class extends Error {
|
|
|
382
347
|
}
|
|
383
348
|
};
|
|
384
349
|
|
|
385
|
-
// src/kernel/
|
|
386
|
-
var
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
350
|
+
// src/kernel/intent/validateIntentName.ts
|
|
351
|
+
var ALLOWED_PREFIXES = [
|
|
352
|
+
"Domain.",
|
|
353
|
+
"Application.",
|
|
354
|
+
"Adapter.",
|
|
355
|
+
"Workflow.",
|
|
356
|
+
"Job.",
|
|
357
|
+
"Presentation.",
|
|
358
|
+
"Reporting.",
|
|
359
|
+
"Metadata.",
|
|
360
|
+
"Security.",
|
|
361
|
+
"Audit.",
|
|
362
|
+
"Observability.",
|
|
363
|
+
"Kernel."
|
|
364
|
+
];
|
|
365
|
+
function validateIntentName(name) {
|
|
366
|
+
if (!name || typeof name !== "string") {
|
|
367
|
+
return { valid: false, reason: "Intent name must be a non-empty string" };
|
|
368
|
+
}
|
|
369
|
+
if (!ALLOWED_PREFIXES.some((p) => name.startsWith(p))) {
|
|
370
|
+
return {
|
|
371
|
+
valid: false,
|
|
372
|
+
reason: `Intent "${name}" must start with one of: ${ALLOWED_PREFIXES.join(", ")}`
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
const rest = name.slice(name.indexOf(".") + 1);
|
|
376
|
+
if (!rest || !/^[A-Za-z][A-Za-z0-9_.]*$/.test(rest)) {
|
|
377
|
+
return {
|
|
378
|
+
valid: false,
|
|
379
|
+
reason: `Intent "${name}" has an invalid segment after the layer prefix`
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
return { valid: true };
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// src/kernel/event-bus/publishGuards.ts
|
|
386
|
+
function assertIntentAllowed(intentName, options) {
|
|
387
|
+
if (!options.strictRegistry && !options.validateIntentNaming) {
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
if (options.validateIntentNaming) {
|
|
391
|
+
const validation = validateIntentName(intentName);
|
|
392
|
+
if (!validation.valid) {
|
|
393
|
+
throw new InvalidIntentNameError(intentName, validation.reason);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
if (options.strictRegistry && options.intentRegistry && !options.intentRegistry.has(intentName)) {
|
|
397
|
+
throw new UnregisteredIntentError(intentName);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
function assertSourceAllowed(event, options) {
|
|
401
|
+
if (!options.requireKnownSource) return;
|
|
402
|
+
if (!event.metadata.source || event.metadata.source === "unknown") {
|
|
403
|
+
throw new UnknownEventSourceError(event.intent);
|
|
404
|
+
}
|
|
405
|
+
if (options.intentRegistry && !options.intentRegistry.has(event.metadata.source)) {
|
|
406
|
+
throw new UnknownEventSourceError(event.intent, event.metadata.source);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
function assertContractAllowed(event, options) {
|
|
410
|
+
if (!options.eventContracts) return;
|
|
411
|
+
const result = options.eventContracts.validate(event);
|
|
412
|
+
if (!result.ok && (options.strictEventContracts || result.contract)) {
|
|
413
|
+
throw new EventContractViolationError(event.intent, result.issues);
|
|
414
|
+
}
|
|
390
415
|
}
|
|
416
|
+
|
|
417
|
+
// src/kernel/event-bus/payloadPatch.ts
|
|
391
418
|
function isPlainRecord(value) {
|
|
392
419
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
393
420
|
return false;
|
|
@@ -458,29 +485,318 @@ function applyPayloadPatch(payload, patch) {
|
|
|
458
485
|
}
|
|
459
486
|
return mergeRecordPatch(payload, patch);
|
|
460
487
|
}
|
|
488
|
+
|
|
489
|
+
// src/kernel/event-bus/publishInterceptors.ts
|
|
490
|
+
async function applyInterceptors(event, deps) {
|
|
491
|
+
if (event.metadata.allowInterception === false) {
|
|
492
|
+
return event;
|
|
493
|
+
}
|
|
494
|
+
const matching = [...deps.interceptorsForIntent(event.intent)];
|
|
495
|
+
let current = event;
|
|
496
|
+
for (const registration of matching) {
|
|
497
|
+
const patches = [];
|
|
498
|
+
try {
|
|
499
|
+
await Promise.resolve(
|
|
500
|
+
registration.interceptor({
|
|
501
|
+
event: current,
|
|
502
|
+
intercept: (patch) => {
|
|
503
|
+
patches.push(patch);
|
|
504
|
+
}
|
|
505
|
+
})
|
|
506
|
+
);
|
|
507
|
+
if (patches.length === 0) {
|
|
508
|
+
continue;
|
|
509
|
+
}
|
|
510
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
511
|
+
let candidate = {
|
|
512
|
+
...current,
|
|
513
|
+
metadata: {
|
|
514
|
+
...current.metadata,
|
|
515
|
+
interceptions: [
|
|
516
|
+
...current.metadata.interceptions ?? [],
|
|
517
|
+
{ interceptorId: registration.interceptorId, timestamp }
|
|
518
|
+
]
|
|
519
|
+
}
|
|
520
|
+
};
|
|
521
|
+
for (const patch of patches) {
|
|
522
|
+
candidate = {
|
|
523
|
+
...candidate,
|
|
524
|
+
payload: applyPayloadPatch(candidate.payload, patch),
|
|
525
|
+
metadata: { ...candidate.metadata }
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
assertContractAllowed(candidate, {
|
|
529
|
+
eventContracts: deps.eventContracts,
|
|
530
|
+
strictEventContracts: deps.strictEventContracts
|
|
531
|
+
});
|
|
532
|
+
current = candidate;
|
|
533
|
+
registration.lastInterceptedAt = timestamp;
|
|
534
|
+
deps.appendTrace({
|
|
535
|
+
type: "event.intercepted",
|
|
536
|
+
timestamp,
|
|
537
|
+
intent: current.intent,
|
|
538
|
+
correlationId: current.metadata.correlationId,
|
|
539
|
+
traceId: current.metadata.traceId,
|
|
540
|
+
spanId: current.metadata.spanId,
|
|
541
|
+
details: {
|
|
542
|
+
registrationId: registration.registrationId,
|
|
543
|
+
interceptorId: registration.interceptorId,
|
|
544
|
+
patchesApplied: patches.length
|
|
545
|
+
}
|
|
546
|
+
});
|
|
547
|
+
await deps.recordAudit("event.intercepted", current, {
|
|
548
|
+
registrationId: registration.registrationId,
|
|
549
|
+
interceptorId: registration.interceptorId,
|
|
550
|
+
patchesApplied: patches.length
|
|
551
|
+
});
|
|
552
|
+
} catch (err) {
|
|
553
|
+
await recordInterceptorError(registration, current, err, deps);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
return current;
|
|
557
|
+
}
|
|
558
|
+
async function recordInterceptorError(interceptor, event, error, deps) {
|
|
559
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
560
|
+
deps.appendTrace({
|
|
561
|
+
type: "interceptor.error",
|
|
562
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
563
|
+
intent: event.intent,
|
|
564
|
+
correlationId: event.metadata.correlationId,
|
|
565
|
+
traceId: event.metadata.traceId,
|
|
566
|
+
spanId: event.metadata.spanId,
|
|
567
|
+
details: {
|
|
568
|
+
registrationId: interceptor.registrationId,
|
|
569
|
+
interceptorId: interceptor.interceptorId,
|
|
570
|
+
error: message
|
|
571
|
+
}
|
|
572
|
+
});
|
|
573
|
+
await deps.recordAudit("interceptor.error", event, {
|
|
574
|
+
registrationId: interceptor.registrationId,
|
|
575
|
+
interceptorId: interceptor.interceptorId,
|
|
576
|
+
error: message
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// src/kernel/event-bus/observedLayerFlow.ts
|
|
581
|
+
async function assertObservedLayerFlowAllowed(event, deps) {
|
|
582
|
+
if (deps.mode === "off" || !deps.architectureProfile) {
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
585
|
+
const source = event.metadata.source;
|
|
586
|
+
if (!source || source === "unknown") return;
|
|
587
|
+
const profile = deps.architectureProfile;
|
|
588
|
+
const fromLayer = profile.resolveLayer(source);
|
|
589
|
+
const toLayer = profile.resolveLayer(event.intent);
|
|
590
|
+
if (!fromLayer || !toLayer) return;
|
|
591
|
+
const blocked = profile.rules.find(
|
|
592
|
+
(rule) => !rule.allowed && rule.from === fromLayer && rule.to === toLayer
|
|
593
|
+
);
|
|
594
|
+
if (!blocked) return;
|
|
595
|
+
const severity = deps.mode;
|
|
596
|
+
const message = blocked.message ?? `Observed layer violation: "${source}" (${fromLayer}) must not produce "${event.intent}" (${toLayer}).`;
|
|
597
|
+
const details = {
|
|
598
|
+
source,
|
|
599
|
+
intent: event.intent,
|
|
600
|
+
fromLayer,
|
|
601
|
+
toLayer,
|
|
602
|
+
severity,
|
|
603
|
+
message,
|
|
604
|
+
rule: blocked
|
|
605
|
+
};
|
|
606
|
+
deps.appendTrace({
|
|
607
|
+
type: "layer.observedViolation",
|
|
608
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
609
|
+
intent: event.intent,
|
|
610
|
+
correlationId: event.metadata.correlationId,
|
|
611
|
+
traceId: event.metadata.traceId,
|
|
612
|
+
spanId: event.metadata.spanId,
|
|
613
|
+
details
|
|
614
|
+
});
|
|
615
|
+
await deps.recordAudit("layer.observedViolation", event, details);
|
|
616
|
+
if (severity === "hard") {
|
|
617
|
+
throw new ObservedLayerFlowViolationError(
|
|
618
|
+
source,
|
|
619
|
+
event.intent,
|
|
620
|
+
fromLayer,
|
|
621
|
+
toLayer,
|
|
622
|
+
message
|
|
623
|
+
);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
// src/kernel/event-bus/publishPolicy.ts
|
|
628
|
+
async function enforcePublishPolicy(event, deps) {
|
|
629
|
+
const ctx = deps.getPolicyContext(event);
|
|
630
|
+
let policyResult;
|
|
631
|
+
try {
|
|
632
|
+
policyResult = deps.policyEngine.enforce(ctx);
|
|
633
|
+
} catch (err) {
|
|
634
|
+
if (err instanceof PolicyViolationError) {
|
|
635
|
+
deps.appendTrace({
|
|
636
|
+
type: "policy.hardViolation",
|
|
637
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
638
|
+
intent: event.intent,
|
|
639
|
+
correlationId: event.metadata.correlationId,
|
|
640
|
+
traceId: event.metadata.traceId,
|
|
641
|
+
spanId: event.metadata.spanId,
|
|
642
|
+
details: { violations: err.violations }
|
|
643
|
+
});
|
|
644
|
+
await deps.recordAudit("policy.hardViolation", event, {
|
|
645
|
+
violations: err.violations
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
throw err;
|
|
649
|
+
}
|
|
650
|
+
if (policyResult.softViolations.length > 0) {
|
|
651
|
+
deps.appendTrace({
|
|
652
|
+
type: "policy.softViolation",
|
|
653
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
654
|
+
intent: event.intent,
|
|
655
|
+
correlationId: event.metadata.correlationId,
|
|
656
|
+
traceId: event.metadata.traceId,
|
|
657
|
+
spanId: event.metadata.spanId,
|
|
658
|
+
details: { violations: policyResult.softViolations }
|
|
659
|
+
});
|
|
660
|
+
await deps.recordAudit("policy.softViolation", event, {
|
|
661
|
+
violations: policyResult.softViolations
|
|
662
|
+
});
|
|
663
|
+
if (deps.onSoftViolation) {
|
|
664
|
+
await deps.safeHook(
|
|
665
|
+
() => deps.onSoftViolation(policyResult, event),
|
|
666
|
+
"onSoftViolation",
|
|
667
|
+
event
|
|
668
|
+
);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
// src/kernel/event-bus/publishRecording.ts
|
|
674
|
+
function appendHistory(buffers, record) {
|
|
675
|
+
buffers.history.push(record);
|
|
676
|
+
if (buffers.maxHistorySize !== void 0 && buffers.history.length > buffers.maxHistorySize) {
|
|
677
|
+
buffers.history.splice(0, buffers.history.length - buffers.maxHistorySize);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
function appendTrace(buffers, record) {
|
|
681
|
+
buffers.trace.push(record);
|
|
682
|
+
if (buffers.maxHistorySize !== void 0 && buffers.trace.length > buffers.maxHistorySize) {
|
|
683
|
+
buffers.trace.splice(0, buffers.trace.length - buffers.maxHistorySize);
|
|
684
|
+
}
|
|
685
|
+
for (const sink of buffers.traceSinks) {
|
|
686
|
+
try {
|
|
687
|
+
sink(record);
|
|
688
|
+
} catch {
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
async function recordAudit(buffers, type, event, details) {
|
|
693
|
+
if (!buffers.auditTrail) return;
|
|
694
|
+
try {
|
|
695
|
+
await buffers.auditTrail.record({
|
|
696
|
+
type,
|
|
697
|
+
source: event.metadata.source,
|
|
698
|
+
intent: event.intent,
|
|
699
|
+
correlationId: event.metadata.correlationId,
|
|
700
|
+
causationId: event.metadata.causationId,
|
|
701
|
+
subject: event.intent,
|
|
702
|
+
details
|
|
703
|
+
});
|
|
704
|
+
} catch (err) {
|
|
705
|
+
appendTrace(buffers, {
|
|
706
|
+
type: "hook.error",
|
|
707
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
708
|
+
intent: event.intent,
|
|
709
|
+
correlationId: event.metadata.correlationId,
|
|
710
|
+
traceId: event.metadata.traceId,
|
|
711
|
+
spanId: event.metadata.spanId,
|
|
712
|
+
details: {
|
|
713
|
+
hook: "auditTrail",
|
|
714
|
+
error: err instanceof Error ? err.message : String(err)
|
|
715
|
+
}
|
|
716
|
+
});
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
async function recordRawPublishDiagnostic(buffers, event) {
|
|
720
|
+
const details = {
|
|
721
|
+
intent: event.intent,
|
|
722
|
+
source: event.metadata.source,
|
|
723
|
+
suggestion: "Publish through a registered intent creator so strict registry, contracts, and agent tooling share one source of truth."
|
|
724
|
+
};
|
|
725
|
+
appendTrace(buffers, {
|
|
726
|
+
type: "event.rawPublish",
|
|
727
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
728
|
+
intent: event.intent,
|
|
729
|
+
correlationId: event.metadata.correlationId,
|
|
730
|
+
traceId: event.metadata.traceId,
|
|
731
|
+
spanId: event.metadata.spanId,
|
|
732
|
+
details
|
|
733
|
+
});
|
|
734
|
+
await recordAudit(buffers, "event.rawPublish", event, details);
|
|
735
|
+
}
|
|
736
|
+
async function recordSuccessfulPublish(buffers, event, subscribersNotified) {
|
|
737
|
+
const record = {
|
|
738
|
+
event,
|
|
739
|
+
publishedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
740
|
+
subscribersNotified
|
|
741
|
+
};
|
|
742
|
+
appendHistory(buffers, record);
|
|
743
|
+
await buffers.outbox?.enqueue(event);
|
|
744
|
+
appendTrace(buffers, {
|
|
745
|
+
type: "event.published",
|
|
746
|
+
timestamp: record.publishedAt,
|
|
747
|
+
intent: event.intent,
|
|
748
|
+
correlationId: event.metadata.correlationId,
|
|
749
|
+
traceId: event.metadata.traceId,
|
|
750
|
+
spanId: event.metadata.spanId,
|
|
751
|
+
details: { subscribersNotified }
|
|
752
|
+
});
|
|
753
|
+
await recordAudit(buffers, "event.published", event, {
|
|
754
|
+
subscribersNotified
|
|
755
|
+
});
|
|
756
|
+
return record;
|
|
757
|
+
}
|
|
758
|
+
function enrichMetadata(base, extra, instanceId) {
|
|
759
|
+
return {
|
|
760
|
+
...base,
|
|
761
|
+
...extra,
|
|
762
|
+
occurredAt: extra.occurredAt || base.occurredAt || (/* @__PURE__ */ new Date()).toISOString(),
|
|
763
|
+
source: extra.source || base.source || "unknown",
|
|
764
|
+
kernelInstanceId: extra.kernelInstanceId ?? base.kernelInstanceId ?? instanceId,
|
|
765
|
+
eventVersion: extra.eventVersion ?? base.eventVersion,
|
|
766
|
+
schemaVersion: extra.schemaVersion ?? base.schemaVersion,
|
|
767
|
+
allowInterception: extra.allowInterception ?? base.allowInterception,
|
|
768
|
+
interceptions: extra.interceptions ?? base.interceptions,
|
|
769
|
+
correlationId: extra.correlationId ?? base.correlationId,
|
|
770
|
+
causationId: extra.causationId ?? base.causationId,
|
|
771
|
+
traceId: extra.traceId ?? base.traceId,
|
|
772
|
+
spanId: extra.spanId ?? base.spanId,
|
|
773
|
+
parentSpanId: extra.parentSpanId ?? base.parentSpanId
|
|
774
|
+
};
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
// src/kernel/event-bus/EventBus.ts
|
|
778
|
+
var interceptorSequence = 0;
|
|
779
|
+
function nextInterceptorRegistrationId() {
|
|
780
|
+
interceptorSequence += 1;
|
|
781
|
+
return `interceptor-${Date.now()}-${interceptorSequence}`;
|
|
782
|
+
}
|
|
461
783
|
var EventBusImpl = class {
|
|
462
784
|
subscriptions = [];
|
|
463
785
|
subscriptionsByIntent = /* @__PURE__ */ new Map();
|
|
464
786
|
interceptors = [];
|
|
465
787
|
interceptorsByIntent = /* @__PURE__ */ new Map();
|
|
466
|
-
|
|
467
|
-
trace = [];
|
|
788
|
+
recording;
|
|
468
789
|
onPublish;
|
|
469
790
|
onSoftViolation;
|
|
470
791
|
onHandlerError;
|
|
471
|
-
auditTrail;
|
|
472
792
|
eventContracts;
|
|
473
793
|
strictEventContracts;
|
|
474
794
|
requireKnownSource;
|
|
475
795
|
architectureProfile;
|
|
476
796
|
enforceObservedLayerFlowMode;
|
|
477
|
-
outbox;
|
|
478
|
-
instanceId;
|
|
479
|
-
traceSinks;
|
|
480
797
|
rethrowHandlerErrors;
|
|
481
798
|
policyEngine;
|
|
482
799
|
getPolicyContext;
|
|
483
|
-
maxHistorySize;
|
|
484
800
|
intentRegistry;
|
|
485
801
|
dependencyGraph;
|
|
486
802
|
strictRegistry;
|
|
@@ -489,21 +805,25 @@ var EventBusImpl = class {
|
|
|
489
805
|
this.onPublish = options.onPublish;
|
|
490
806
|
this.onSoftViolation = options.onSoftViolation;
|
|
491
807
|
this.onHandlerError = options.onHandlerError;
|
|
492
|
-
this.auditTrail = options.auditTrail;
|
|
493
808
|
this.eventContracts = options.eventContracts;
|
|
494
809
|
this.strictEventContracts = options.strictEventContracts ?? false;
|
|
495
810
|
this.requireKnownSource = options.requireKnownSource ?? false;
|
|
496
811
|
this.architectureProfile = options.architectureProfile;
|
|
497
812
|
this.enforceObservedLayerFlowMode = options.enforceObservedLayerFlow ?? "off";
|
|
498
|
-
this.outbox = options.outbox;
|
|
499
|
-
this.instanceId = options.instanceId;
|
|
500
|
-
this.traceSinks = [...options.traceSinks ?? []];
|
|
501
813
|
this.rethrowHandlerErrors = options.rethrowHandlerErrors ?? false;
|
|
502
|
-
this.maxHistorySize = options.maxHistorySize;
|
|
503
814
|
this.intentRegistry = options.intentRegistry;
|
|
504
815
|
this.dependencyGraph = options.dependencyGraph;
|
|
505
816
|
this.strictRegistry = options.strictRegistry ?? options.intentRegistry !== void 0;
|
|
506
817
|
this.validateIntentNaming = options.validateIntentNaming ?? this.strictRegistry;
|
|
818
|
+
this.recording = {
|
|
819
|
+
history: [],
|
|
820
|
+
trace: [],
|
|
821
|
+
maxHistorySize: options.maxHistorySize,
|
|
822
|
+
traceSinks: [...options.traceSinks ?? []],
|
|
823
|
+
auditTrail: options.auditTrail,
|
|
824
|
+
outbox: options.outbox,
|
|
825
|
+
instanceId: options.instanceId
|
|
826
|
+
};
|
|
507
827
|
if (options.policyEngine) {
|
|
508
828
|
this.policyEngine = options.policyEngine;
|
|
509
829
|
} else if (options.policies && options.policies.length > 0) {
|
|
@@ -534,94 +854,77 @@ var EventBusImpl = class {
|
|
|
534
854
|
const created = creator(payload);
|
|
535
855
|
event = {
|
|
536
856
|
...created,
|
|
537
|
-
metadata:
|
|
857
|
+
metadata: enrichMetadata(
|
|
858
|
+
created.metadata,
|
|
859
|
+
extraMeta,
|
|
860
|
+
this.recording.instanceId
|
|
861
|
+
)
|
|
538
862
|
};
|
|
539
863
|
} else {
|
|
540
864
|
const rawEvent = eventOrCreator;
|
|
541
865
|
const extraMeta = metadata ?? payloadOrMeta ?? {};
|
|
542
866
|
event = {
|
|
543
867
|
...rawEvent,
|
|
544
|
-
metadata:
|
|
868
|
+
metadata: enrichMetadata(
|
|
869
|
+
rawEvent.metadata,
|
|
870
|
+
extraMeta,
|
|
871
|
+
this.recording.instanceId
|
|
872
|
+
)
|
|
545
873
|
};
|
|
546
874
|
}
|
|
547
875
|
if (rawPublish && this.strictRegistry) {
|
|
548
|
-
await this.
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
876
|
+
await recordRawPublishDiagnostic(this.recording, event);
|
|
877
|
+
}
|
|
878
|
+
assertIntentAllowed(event.intent, {
|
|
879
|
+
strictRegistry: this.strictRegistry,
|
|
880
|
+
validateIntentNaming: this.validateIntentNaming,
|
|
881
|
+
intentRegistry: this.intentRegistry
|
|
882
|
+
});
|
|
883
|
+
assertSourceAllowed(event, {
|
|
884
|
+
requireKnownSource: this.requireKnownSource,
|
|
885
|
+
intentRegistry: this.intentRegistry
|
|
886
|
+
});
|
|
887
|
+
assertContractAllowed(event, {
|
|
888
|
+
eventContracts: this.eventContracts,
|
|
889
|
+
strictEventContracts: this.strictEventContracts
|
|
890
|
+
});
|
|
891
|
+
event = await applyInterceptors(event, {
|
|
892
|
+
interceptorsForIntent: (intent) => this.interceptorsByIntent.get(intent) ?? [],
|
|
893
|
+
eventContracts: this.eventContracts,
|
|
894
|
+
strictEventContracts: this.strictEventContracts,
|
|
895
|
+
appendTrace: (r) => this.appendTrace(r),
|
|
896
|
+
recordAudit: (type, e, details) => this.recordAudit(type, e, details)
|
|
897
|
+
});
|
|
898
|
+
assertContractAllowed(event, {
|
|
899
|
+
eventContracts: this.eventContracts,
|
|
900
|
+
strictEventContracts: this.strictEventContracts
|
|
901
|
+
});
|
|
902
|
+
await assertObservedLayerFlowAllowed(event, {
|
|
903
|
+
mode: this.enforceObservedLayerFlowMode,
|
|
904
|
+
architectureProfile: this.architectureProfile,
|
|
905
|
+
appendTrace: (r) => this.appendTrace(r),
|
|
906
|
+
recordAudit: (type, e, details) => this.recordAudit(type, e, details)
|
|
907
|
+
});
|
|
556
908
|
this.dependencyGraph?.registerEventFlow(event.metadata.source, event.intent);
|
|
557
909
|
const matching = [...this.subscriptionsByIntent.get(event.intent) ?? []];
|
|
558
910
|
if (this.policyEngine) {
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
568
|
-
intent: event.intent,
|
|
569
|
-
correlationId: event.metadata.correlationId,
|
|
570
|
-
traceId: event.metadata.traceId,
|
|
571
|
-
spanId: event.metadata.spanId,
|
|
572
|
-
details: { violations: err.violations }
|
|
573
|
-
});
|
|
574
|
-
await this.recordAudit("policy.hardViolation", event, {
|
|
575
|
-
violations: err.violations
|
|
576
|
-
});
|
|
577
|
-
}
|
|
578
|
-
throw err;
|
|
579
|
-
}
|
|
580
|
-
if (policyResult.softViolations.length > 0) {
|
|
581
|
-
this.appendTrace({
|
|
582
|
-
type: "policy.softViolation",
|
|
583
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
584
|
-
intent: event.intent,
|
|
585
|
-
correlationId: event.metadata.correlationId,
|
|
586
|
-
traceId: event.metadata.traceId,
|
|
587
|
-
spanId: event.metadata.spanId,
|
|
588
|
-
details: { violations: policyResult.softViolations }
|
|
589
|
-
});
|
|
590
|
-
await this.recordAudit("policy.softViolation", event, {
|
|
591
|
-
violations: policyResult.softViolations
|
|
592
|
-
});
|
|
593
|
-
if (this.onSoftViolation) {
|
|
594
|
-
await this.safeHook(
|
|
595
|
-
() => this.onSoftViolation(policyResult, event),
|
|
596
|
-
"onSoftViolation",
|
|
597
|
-
event
|
|
598
|
-
);
|
|
599
|
-
}
|
|
600
|
-
}
|
|
911
|
+
await enforcePublishPolicy(event, {
|
|
912
|
+
policyEngine: this.policyEngine,
|
|
913
|
+
getPolicyContext: this.getPolicyContext,
|
|
914
|
+
appendTrace: (r) => this.appendTrace(r),
|
|
915
|
+
recordAudit: (type, e, details) => this.recordAudit(type, e, details),
|
|
916
|
+
onSoftViolation: this.onSoftViolation,
|
|
917
|
+
safeHook: (fn, name, e) => this.safeHook(fn, name, e)
|
|
918
|
+
});
|
|
601
919
|
}
|
|
602
|
-
|
|
920
|
+
await recordSuccessfulPublish(
|
|
921
|
+
this.recording,
|
|
603
922
|
event,
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
await this.outbox?.enqueue(event);
|
|
609
|
-
this.appendTrace({
|
|
610
|
-
type: "event.published",
|
|
611
|
-
timestamp: record.publishedAt,
|
|
612
|
-
intent: event.intent,
|
|
613
|
-
correlationId: event.metadata.correlationId,
|
|
614
|
-
traceId: event.metadata.traceId,
|
|
615
|
-
spanId: event.metadata.spanId,
|
|
616
|
-
details: { subscribersNotified: matching.length }
|
|
617
|
-
});
|
|
618
|
-
await this.recordAudit("event.published", event, {
|
|
619
|
-
subscribersNotified: matching.length
|
|
620
|
-
});
|
|
621
|
-
const notifications = matching.map(
|
|
622
|
-
(sub) => this.invokeHandler(sub, event)
|
|
923
|
+
matching.length
|
|
924
|
+
);
|
|
925
|
+
await Promise.all(
|
|
926
|
+
matching.map((sub) => this.invokeHandler(sub, event))
|
|
623
927
|
);
|
|
624
|
-
await Promise.all(notifications);
|
|
625
928
|
if (this.onPublish) {
|
|
626
929
|
await this.safeHook(
|
|
627
930
|
() => this.onPublish(event),
|
|
@@ -632,7 +935,11 @@ var EventBusImpl = class {
|
|
|
632
935
|
}
|
|
633
936
|
createPublisher(source) {
|
|
634
937
|
const sourceName = typeof source === "string" ? source : source.name;
|
|
635
|
-
|
|
938
|
+
assertIntentAllowed(sourceName, {
|
|
939
|
+
strictRegistry: this.strictRegistry,
|
|
940
|
+
validateIntentNaming: this.validateIntentNaming,
|
|
941
|
+
intentRegistry: this.intentRegistry
|
|
942
|
+
});
|
|
636
943
|
return {
|
|
637
944
|
source: sourceName,
|
|
638
945
|
publish: async (intent, payload, metadata = {}) => {
|
|
@@ -648,7 +955,11 @@ var EventBusImpl = class {
|
|
|
648
955
|
}
|
|
649
956
|
subscribe(intent, handler) {
|
|
650
957
|
const intentName = typeof intent === "string" ? intent : intent.name;
|
|
651
|
-
|
|
958
|
+
assertIntentAllowed(intentName, {
|
|
959
|
+
strictRegistry: this.strictRegistry,
|
|
960
|
+
validateIntentNaming: this.validateIntentNaming,
|
|
961
|
+
intentRegistry: this.intentRegistry
|
|
962
|
+
});
|
|
652
963
|
const sub = {
|
|
653
964
|
intentName,
|
|
654
965
|
handler
|
|
@@ -669,7 +980,11 @@ var EventBusImpl = class {
|
|
|
669
980
|
}
|
|
670
981
|
registerInterceptor(intent, interceptor, interceptorId) {
|
|
671
982
|
const intentName = typeof intent === "string" ? intent : intent.name;
|
|
672
|
-
|
|
983
|
+
assertIntentAllowed(intentName, {
|
|
984
|
+
strictRegistry: this.strictRegistry,
|
|
985
|
+
validateIntentNaming: this.validateIntentNaming,
|
|
986
|
+
intentRegistry: this.intentRegistry
|
|
987
|
+
});
|
|
673
988
|
const registration = {
|
|
674
989
|
registrationId: nextInterceptorRegistrationId(),
|
|
675
990
|
interceptorId: interceptorId ?? intentName,
|
|
@@ -708,174 +1023,22 @@ var EventBusImpl = class {
|
|
|
708
1023
|
}));
|
|
709
1024
|
}
|
|
710
1025
|
getHistory() {
|
|
711
|
-
return [...this.history];
|
|
1026
|
+
return [...this.recording.history];
|
|
712
1027
|
}
|
|
713
1028
|
clearHistory() {
|
|
714
|
-
this.history.length = 0;
|
|
1029
|
+
this.recording.history.length = 0;
|
|
715
1030
|
}
|
|
716
1031
|
getTrace() {
|
|
717
|
-
return [...this.trace];
|
|
1032
|
+
return [...this.recording.trace];
|
|
718
1033
|
}
|
|
719
1034
|
clearTrace() {
|
|
720
|
-
this.trace.length = 0;
|
|
721
|
-
}
|
|
722
|
-
assertIntentAllowed(intentName) {
|
|
723
|
-
if (!this.strictRegistry && !this.validateIntentNaming) {
|
|
724
|
-
return;
|
|
725
|
-
}
|
|
726
|
-
if (this.validateIntentNaming) {
|
|
727
|
-
const validation = validateIntentName(intentName);
|
|
728
|
-
if (!validation.valid) {
|
|
729
|
-
throw new InvalidIntentNameError(intentName, validation.reason);
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
if (this.strictRegistry && this.intentRegistry && !this.intentRegistry.has(intentName)) {
|
|
733
|
-
throw new UnregisteredIntentError(intentName);
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
assertSourceAllowed(event) {
|
|
737
|
-
if (!this.requireKnownSource) return;
|
|
738
|
-
if (!event.metadata.source || event.metadata.source === "unknown") {
|
|
739
|
-
throw new UnknownEventSourceError(event.intent);
|
|
740
|
-
}
|
|
741
|
-
if (this.intentRegistry && !this.intentRegistry.has(event.metadata.source)) {
|
|
742
|
-
throw new UnknownEventSourceError(event.intent, event.metadata.source);
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
assertContractAllowed(event) {
|
|
746
|
-
if (!this.eventContracts) return;
|
|
747
|
-
const result = this.eventContracts.validate(event);
|
|
748
|
-
if (!result.ok && (this.strictEventContracts || result.contract)) {
|
|
749
|
-
throw new EventContractViolationError(event.intent, result.issues);
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
/**
|
|
753
|
-
* Enforce the OBSERVED producer→event flow (metadata.source → intent) against the
|
|
754
|
-
* architecture profile's layer rules. This is the runtime counterpart to the
|
|
755
|
-
* declared-model layer policy: it checks what the system actually did, resolving both
|
|
756
|
-
* layers directly from the profile. It runs BEFORE the flow is recorded via
|
|
757
|
-
* registerEventFlow, so in hard mode a rejected flow leaves no edge in the graph.
|
|
758
|
-
*/
|
|
759
|
-
async assertObservedLayerFlowAllowed(event) {
|
|
760
|
-
if (this.enforceObservedLayerFlowMode === "off" || !this.architectureProfile) {
|
|
761
|
-
return;
|
|
762
|
-
}
|
|
763
|
-
const source = event.metadata.source;
|
|
764
|
-
if (!source || source === "unknown") return;
|
|
765
|
-
const profile = this.architectureProfile;
|
|
766
|
-
const fromLayer = profile.resolveLayer(source);
|
|
767
|
-
const toLayer = profile.resolveLayer(event.intent);
|
|
768
|
-
if (!fromLayer || !toLayer) return;
|
|
769
|
-
const blocked = profile.rules.find(
|
|
770
|
-
(rule) => !rule.allowed && rule.from === fromLayer && rule.to === toLayer
|
|
771
|
-
);
|
|
772
|
-
if (!blocked) return;
|
|
773
|
-
const severity = this.enforceObservedLayerFlowMode;
|
|
774
|
-
const message = blocked.message ?? `Observed layer violation: "${source}" (${fromLayer}) must not produce "${event.intent}" (${toLayer}).`;
|
|
775
|
-
const details = {
|
|
776
|
-
source,
|
|
777
|
-
intent: event.intent,
|
|
778
|
-
fromLayer,
|
|
779
|
-
toLayer,
|
|
780
|
-
severity,
|
|
781
|
-
message,
|
|
782
|
-
rule: blocked
|
|
783
|
-
};
|
|
784
|
-
this.appendTrace({
|
|
785
|
-
type: "layer.observedViolation",
|
|
786
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
787
|
-
intent: event.intent,
|
|
788
|
-
correlationId: event.metadata.correlationId,
|
|
789
|
-
traceId: event.metadata.traceId,
|
|
790
|
-
spanId: event.metadata.spanId,
|
|
791
|
-
details
|
|
792
|
-
});
|
|
793
|
-
await this.recordAudit("layer.observedViolation", event, details);
|
|
794
|
-
if (severity === "hard") {
|
|
795
|
-
throw new ObservedLayerFlowViolationError(source, event.intent, fromLayer, toLayer, message);
|
|
796
|
-
}
|
|
1035
|
+
this.recording.trace.length = 0;
|
|
797
1036
|
}
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
intent: event.intent,
|
|
801
|
-
source: event.metadata.source,
|
|
802
|
-
suggestion: "Publish through a registered intent creator so strict registry, contracts, and agent tooling share one source of truth."
|
|
803
|
-
};
|
|
804
|
-
this.appendTrace({
|
|
805
|
-
type: "event.rawPublish",
|
|
806
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
807
|
-
intent: event.intent,
|
|
808
|
-
correlationId: event.metadata.correlationId,
|
|
809
|
-
traceId: event.metadata.traceId,
|
|
810
|
-
spanId: event.metadata.spanId,
|
|
811
|
-
details
|
|
812
|
-
});
|
|
813
|
-
await this.recordAudit("event.rawPublish", event, details);
|
|
1037
|
+
appendTrace(record) {
|
|
1038
|
+
appendTrace(this.recording, record);
|
|
814
1039
|
}
|
|
815
|
-
async
|
|
816
|
-
|
|
817
|
-
return event;
|
|
818
|
-
}
|
|
819
|
-
const matching = [...this.interceptorsByIntent.get(event.intent) ?? []];
|
|
820
|
-
let current = event;
|
|
821
|
-
for (const registration of matching) {
|
|
822
|
-
const patches = [];
|
|
823
|
-
try {
|
|
824
|
-
await Promise.resolve(
|
|
825
|
-
registration.interceptor({
|
|
826
|
-
event: current,
|
|
827
|
-
intercept: (patch) => {
|
|
828
|
-
patches.push(patch);
|
|
829
|
-
}
|
|
830
|
-
})
|
|
831
|
-
);
|
|
832
|
-
if (patches.length === 0) {
|
|
833
|
-
continue;
|
|
834
|
-
}
|
|
835
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
836
|
-
let candidate = {
|
|
837
|
-
...current,
|
|
838
|
-
metadata: {
|
|
839
|
-
...current.metadata,
|
|
840
|
-
interceptions: [
|
|
841
|
-
...current.metadata.interceptions ?? [],
|
|
842
|
-
{ interceptorId: registration.interceptorId, timestamp }
|
|
843
|
-
]
|
|
844
|
-
}
|
|
845
|
-
};
|
|
846
|
-
for (const patch of patches) {
|
|
847
|
-
candidate = {
|
|
848
|
-
...candidate,
|
|
849
|
-
payload: applyPayloadPatch(candidate.payload, patch),
|
|
850
|
-
metadata: { ...candidate.metadata }
|
|
851
|
-
};
|
|
852
|
-
}
|
|
853
|
-
this.assertContractAllowed(candidate);
|
|
854
|
-
current = candidate;
|
|
855
|
-
registration.lastInterceptedAt = timestamp;
|
|
856
|
-
this.appendTrace({
|
|
857
|
-
type: "event.intercepted",
|
|
858
|
-
timestamp,
|
|
859
|
-
intent: current.intent,
|
|
860
|
-
correlationId: current.metadata.correlationId,
|
|
861
|
-
traceId: current.metadata.traceId,
|
|
862
|
-
spanId: current.metadata.spanId,
|
|
863
|
-
details: {
|
|
864
|
-
registrationId: registration.registrationId,
|
|
865
|
-
interceptorId: registration.interceptorId,
|
|
866
|
-
patchesApplied: patches.length
|
|
867
|
-
}
|
|
868
|
-
});
|
|
869
|
-
await this.recordAudit("event.intercepted", current, {
|
|
870
|
-
registrationId: registration.registrationId,
|
|
871
|
-
interceptorId: registration.interceptorId,
|
|
872
|
-
patchesApplied: patches.length
|
|
873
|
-
});
|
|
874
|
-
} catch (err) {
|
|
875
|
-
await this.recordInterceptorError(registration, current, err);
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
return current;
|
|
1040
|
+
async recordAudit(type, event, details) {
|
|
1041
|
+
await recordAudit(this.recording, type, event, details);
|
|
879
1042
|
}
|
|
880
1043
|
async invokeHandler(sub, event) {
|
|
881
1044
|
try {
|
|
@@ -928,90 +1091,6 @@ var EventBusImpl = class {
|
|
|
928
1091
|
});
|
|
929
1092
|
}
|
|
930
1093
|
}
|
|
931
|
-
async recordInterceptorError(interceptor, event, error) {
|
|
932
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
933
|
-
this.appendTrace({
|
|
934
|
-
type: "interceptor.error",
|
|
935
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
936
|
-
intent: event.intent,
|
|
937
|
-
correlationId: event.metadata.correlationId,
|
|
938
|
-
traceId: event.metadata.traceId,
|
|
939
|
-
spanId: event.metadata.spanId,
|
|
940
|
-
details: {
|
|
941
|
-
registrationId: interceptor.registrationId,
|
|
942
|
-
interceptorId: interceptor.interceptorId,
|
|
943
|
-
error: message
|
|
944
|
-
}
|
|
945
|
-
});
|
|
946
|
-
await this.recordAudit("interceptor.error", event, {
|
|
947
|
-
registrationId: interceptor.registrationId,
|
|
948
|
-
interceptorId: interceptor.interceptorId,
|
|
949
|
-
error: message
|
|
950
|
-
});
|
|
951
|
-
}
|
|
952
|
-
appendHistory(record) {
|
|
953
|
-
this.history.push(record);
|
|
954
|
-
if (this.maxHistorySize !== void 0 && this.history.length > this.maxHistorySize) {
|
|
955
|
-
this.history.splice(0, this.history.length - this.maxHistorySize);
|
|
956
|
-
}
|
|
957
|
-
}
|
|
958
|
-
appendTrace(record) {
|
|
959
|
-
this.trace.push(record);
|
|
960
|
-
if (this.maxHistorySize !== void 0 && this.trace.length > this.maxHistorySize) {
|
|
961
|
-
this.trace.splice(0, this.trace.length - this.maxHistorySize);
|
|
962
|
-
}
|
|
963
|
-
for (const sink of this.traceSinks) {
|
|
964
|
-
try {
|
|
965
|
-
sink(record);
|
|
966
|
-
} catch {
|
|
967
|
-
}
|
|
968
|
-
}
|
|
969
|
-
}
|
|
970
|
-
async recordAudit(type, event, details) {
|
|
971
|
-
if (!this.auditTrail) return;
|
|
972
|
-
try {
|
|
973
|
-
await this.auditTrail.record({
|
|
974
|
-
type,
|
|
975
|
-
source: event.metadata.source,
|
|
976
|
-
intent: event.intent,
|
|
977
|
-
correlationId: event.metadata.correlationId,
|
|
978
|
-
causationId: event.metadata.causationId,
|
|
979
|
-
subject: event.intent,
|
|
980
|
-
details
|
|
981
|
-
});
|
|
982
|
-
} catch (err) {
|
|
983
|
-
this.appendTrace({
|
|
984
|
-
type: "hook.error",
|
|
985
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
986
|
-
intent: event.intent,
|
|
987
|
-
correlationId: event.metadata.correlationId,
|
|
988
|
-
traceId: event.metadata.traceId,
|
|
989
|
-
spanId: event.metadata.spanId,
|
|
990
|
-
details: {
|
|
991
|
-
hook: "auditTrail",
|
|
992
|
-
error: err instanceof Error ? err.message : String(err)
|
|
993
|
-
}
|
|
994
|
-
});
|
|
995
|
-
}
|
|
996
|
-
}
|
|
997
|
-
enrichMetadata(base, extra) {
|
|
998
|
-
return {
|
|
999
|
-
...base,
|
|
1000
|
-
...extra,
|
|
1001
|
-
occurredAt: extra.occurredAt || base.occurredAt || (/* @__PURE__ */ new Date()).toISOString(),
|
|
1002
|
-
source: extra.source || base.source || "unknown",
|
|
1003
|
-
kernelInstanceId: extra.kernelInstanceId ?? base.kernelInstanceId ?? this.instanceId,
|
|
1004
|
-
eventVersion: extra.eventVersion ?? base.eventVersion,
|
|
1005
|
-
schemaVersion: extra.schemaVersion ?? base.schemaVersion,
|
|
1006
|
-
allowInterception: extra.allowInterception ?? base.allowInterception,
|
|
1007
|
-
interceptions: extra.interceptions ?? base.interceptions,
|
|
1008
|
-
correlationId: extra.correlationId ?? base.correlationId,
|
|
1009
|
-
causationId: extra.causationId ?? base.causationId,
|
|
1010
|
-
traceId: extra.traceId ?? base.traceId,
|
|
1011
|
-
spanId: extra.spanId ?? base.spanId,
|
|
1012
|
-
parentSpanId: extra.parentSpanId ?? base.parentSpanId
|
|
1013
|
-
};
|
|
1014
|
-
}
|
|
1015
1094
|
};
|
|
1016
1095
|
function createEventBus(options) {
|
|
1017
1096
|
return new EventBusImpl(options);
|
|
@@ -1625,7 +1704,7 @@ var elevenLayerProfile = createArchitectureProfile({
|
|
|
1625
1704
|
var MANIFEST_SCHEMA_VERSION = "1.0";
|
|
1626
1705
|
|
|
1627
1706
|
// src/version.ts
|
|
1628
|
-
var version = "2.
|
|
1707
|
+
var version = "2.8.1";
|
|
1629
1708
|
|
|
1630
1709
|
// src/kernel/manifest/createArkManifest.ts
|
|
1631
1710
|
function policyId(name) {
|