diff --git a/internal/mcp/server.go b/internal/mcp/server.go index bdecdd0..625f190 100644 --- a/internal/mcp/server.go +++ b/internal/mcp/server.go @@ -921,6 +921,13 @@ func classifyAndGate(ctx context.Context, pool *db.Pool, agentID, targetID uuid. classID, actionCol, riskClass, classRoute, classReason, correlationID) // Link classification to execution. pool.Exec(ctx, `UPDATE executions SET classification_id = $2 WHERE entity_id = $1`, id, classID) + // Graph edge: classification —precedes→ execution (required by ontology). + pool.Exec(ctx, `INSERT INTO relationships (source_id, target_id, type, attributes, valid_from) + SELECT $1, $2, 'precedes', '{"by":"nomos"}'::jsonb, now() + WHERE NOT EXISTS ( + SELECT 1 FROM relationships + WHERE source_id = $1 AND target_id = $2 AND type = 'precedes' AND valid_to IS NULL)`, + classID, id) // Audit: record the execution creation with session_id for traceability. // Every run call, whether auto-run or queued-for-approval, gets an audit diff --git a/web/src/lib/apps.ts b/web/src/lib/apps.ts index 3ba1d6f..a3f7a3e 100644 --- a/web/src/lib/apps.ts +++ b/web/src/lib/apps.ts @@ -38,6 +38,7 @@ import TrendingUpIcon from '@lucide/svelte/icons/trending-up' import SettingsIcon from '@lucide/svelte/icons/settings' import EggIcon from '@lucide/svelte/icons/egg' import StoreIcon from '@lucide/svelte/icons/store' +import Share2Icon from '@lucide/svelte/icons/share-2' export type { AppManifest, AppPermission } @@ -180,6 +181,17 @@ export const builtinApps: AppDef[] = [ component: () => import('./mascot/MascotLayer.svelte'), docked: true, source: 'builtin' + }, + { + id: 'entity-graph', + title: 'Entity Graph', + icon: Share2Icon, + component: () => import('../pages/EntityGraph.svelte'), + width: 1100, + height: 750, + minWidth: 640, + minHeight: 420, + source: 'builtin' } ]