diff --git a/.changeset/reaudit-crossrepo.md b/.changeset/reaudit-crossrepo.md new file mode 100644 index 0000000000..89d0dcba9f --- /dev/null +++ b/.changeset/reaudit-crossrepo.md @@ -0,0 +1,4 @@ +--- +--- + +fix(spec): cross-repo liveness re-audit — reclassify 16 props dead→live (objectui authoring UI) and flag the dead-surface plan as invalidated. The 2026-06 audits missed objectui's metadata-admin authoring layer; verified each correction by reading the consumer code in both repos. Repo-internal tooling/docs; no package impact. diff --git a/docs/audits/2026-06-dead-surface-disposition-plan.md b/docs/audits/2026-06-dead-surface-disposition-plan.md index d73a90c831..017a57a578 100644 --- a/docs/audits/2026-06-dead-surface-disposition-plan.md +++ b/docs/audits/2026-06-dead-surface-disposition-plan.md @@ -1,5 +1,9 @@ # Dead-surface disposition plan (spec liveness) +> ## ⚠️ CORRECTION (2026-06-16) — this plan is substantially invalidated; do NOT prune from it +> The "dead" verdicts were seeded from audits that **only checked the framework runtime + end-user renderers and MISSED objectui's metadata-admin authoring UI** (`../objectui/packages/app-shell/src/views/metadata-admin/`, which renders/edits nearly every authorable prop). A cross-repo re-audit (reading the actual consumer code in BOTH repos) found **~25 props this plan called "dead" are actually objectui-live** — pruning them would break the authoring UI / detail rendering. Reclassified `dead→live` in the ledgers: field `externalId`/`currencyConfig`/`searchable` + the 6 master-detail overrides; tool `category`/`requiresConfirmation`/`active`/`builtIn`; skill `triggerPhrases`/`permissions`; action `execute`/`shortcut`/`bulkEnabled`/`disabled`; flow `status`/`active`/`nodes.boundaryConfig`; agent `knowledge`; role `parent`; permission `isProfile`. +> **Only ~42 props are confirmed dead in BOTH repos** (the genuine prune candidates — dominated by the 24 object-level props, which also hit `NoExcessObjectKeys` TS-strict cross-package coupling). Merged prunes #1945/#1946 were re-verified against objectui and are safe. **Any further pruning MUST verify each prop against framework AND objectui first.** The sections below are kept for history but their per-prop "prune" verdicts are unreliable. + **Date**: 2026-06-16 · **Input**: the spec-liveness gate (`packages/spec/liveness/`) over 10 governed metadata types. **Builds on**: [ADR-0049](../adr/0049-no-unenforced-security-properties.md) (security enforce-or-remove). **Purpose**: turn the gate's measurement into an executable decision — for each of the **89 `dead` properties**, recommend **enforce / wire-rename / prune / mark-experimental / defer / objectui** with rationale, cost and risk. > The gate already proves these properties have no framework runtime consumer. This document decides what to *do* about each. It makes recommendations; the team owns execution (especially spec removals and runtime enforcement). diff --git a/packages/spec/liveness/action.json b/packages/spec/liveness/action.json index 61d18af860..8f82b13b17 100644 --- a/packages/spec/liveness/action.json +++ b/packages/spec/liveness/action.json @@ -2,36 +2,140 @@ "type": "action", "_note": "ActionSchema. Seeded from docs/audits/2026-06-actionschema-property-liveness.md. Renderers live in objectui (evidence cited as prose, not framework paths); framework-side: service-ai action-tools, runtime body-runner/http-dispatcher. Containers (params/resultDialog/ai/aria) classified at top level — no divergent sub-statuses in the audit.", "props": { - "name": { "status": "live", "evidence": "objectui action renderers + runtime dispatcher" }, - "label": { "status": "live", "note": "display." }, - "objectName": { "status": "live", "evidence": "packages/services/service-ai/src/tools/action-tools.ts:535", "note": "action dispatch + AI bridge." }, - "icon": { "status": "live", "note": "objectui renderers." }, - "locations": { "status": "live", "note": "objectui — where the action is surfaced." }, - "component": { "status": "live", "note": "objectui visual component override." }, - "type": { "status": "live", "evidence": "packages/runtime/src/http-dispatcher.ts", "note": "api/script/flow wired; url thinner; modal PARTIAL (maps to serverActionHandler, not a real modal); form DEAD (no consumer)." }, - "target": { "status": "live", "evidence": "packages/runtime/src/http-dispatcher.ts", "note": "URL/script/flow/endpoint + ${param}/${ctx} interpolation." }, - "body": { "status": "live", "evidence": "packages/runtime/src/http-dispatcher.ts", "note": "server script (L1/L2) via engine.executeAction→body-runner." }, - "execute": { "status": "dead", "evidence": "@deprecated — auto-migrated to target" }, - "params": { "status": "live", "evidence": "packages/services/service-ai/src/tools/action-tools.ts", "note": "field/objectOverride/defaultFromRow/options/placeholder/helpText/defaultValue/required all consumed." }, - "variant": { "status": "live", "note": "objectui button styling." }, - "confirmText": { "status": "live", "note": "objectui confirm dialog." }, - "successMessage": { "status": "live", "note": "objectui toast." }, - "refreshAfter": { "status": "live", "note": "objectui post-action refresh." }, - "resultDialog": { "status": "live", "note": "objectui one-shot result reveal {title,description,acknowledge,format,fields}." }, - "visible": { "status": "live", "note": "objectui — CEL, fail-closed." }, - "disabled": { "status": "dead", "evidence": "primary renderers read a non-spec `enabled` (action-button.tsx:56,116) and invert it; CEL-predicate form has zero consumers; only boolean honored in detail/quick-action toolbars", "note": "ADR-0049-style naming drift — wire the CEL form or rename." }, - "shortcut": { "status": "dead", "evidence": "ActionEngine registers it but no keydown listener pumps events — never fires" }, - "bulkEnabled": { "status": "dead", "evidence": "engine has executeBulk but no spec-driven view path calls it" }, - "ai": { "status": "live", "evidence": "packages/services/service-ai/src/tools/action-tools.ts", "note": "full AI bridge (exposed/description/category/paramHints/outputSchema/requiresConfirmation)." }, - "recordIdParam": { "status": "live", "note": "objectui + dispatcher." }, - "recordIdField": { "status": "live", "note": "objectui + dispatcher." }, - "bodyShape": { "status": "live", "evidence": "packages/runtime/src/http-dispatcher.ts", "note": "{wrap} request shaping." }, - "method": { "status": "live", "evidence": "packages/runtime/src/http-dispatcher.ts" }, - "bodyExtra": { "status": "live", "evidence": "packages/runtime/src/http-dispatcher.ts" }, - "mode": { "status": "live", "note": "PARTIAL — read only by the AI HITL heuristic (action-tools.ts), never by the UI." }, - "opensInNewTab": { "status": "live", "note": "objectui." }, - "newTabUrl": { "status": "live", "note": "objectui." }, - "timeout": { "status": "dead", "evidence": "action-level timeout DEAD — server uses body.timeoutMs; no UI consumer" }, - "aria": { "status": "live", "note": "PARTIAL — honored by a few objectui renderers, not the core action buttons/menus." } + "name": { + "status": "live", + "evidence": "objectui action renderers + runtime dispatcher" + }, + "label": { + "status": "live", + "note": "display." + }, + "objectName": { + "status": "live", + "evidence": "packages/services/service-ai/src/tools/action-tools.ts:535", + "note": "action dispatch + AI bridge." + }, + "icon": { + "status": "live", + "note": "objectui renderers." + }, + "locations": { + "status": "live", + "note": "objectui — where the action is surfaced." + }, + "component": { + "status": "live", + "note": "objectui visual component override." + }, + "type": { + "status": "live", + "evidence": "packages/runtime/src/http-dispatcher.ts", + "note": "api/script/flow wired; url thinner; modal PARTIAL (maps to serverActionHandler, not a real modal); form DEAD (no consumer)." + }, + "target": { + "status": "live", + "evidence": "packages/runtime/src/http-dispatcher.ts", + "note": "URL/script/flow/endpoint + ${param}/${ctx} interpolation." + }, + "body": { + "status": "live", + "evidence": "packages/runtime/src/http-dispatcher.ts", + "note": "server script (L1/L2) via engine.executeAction→body-runner." + }, + "execute": { + "status": "live", + "evidence": "objectui: packages/app-shell/src/views/metadata-admin/previews/ActionPreview.tsx:154", + "note": "LIVE via objectui metadata-admin authoring UI — the 2026-06 audit missed objectui; verified by reading the file." + }, + "params": { + "status": "live", + "evidence": "packages/services/service-ai/src/tools/action-tools.ts", + "note": "field/objectOverride/defaultFromRow/options/placeholder/helpText/defaultValue/required all consumed." + }, + "variant": { + "status": "live", + "note": "objectui button styling." + }, + "confirmText": { + "status": "live", + "note": "objectui confirm dialog." + }, + "successMessage": { + "status": "live", + "note": "objectui toast." + }, + "refreshAfter": { + "status": "live", + "note": "objectui post-action refresh." + }, + "resultDialog": { + "status": "live", + "note": "objectui one-shot result reveal {title,description,acknowledge,format,fields}." + }, + "visible": { + "status": "live", + "note": "objectui — CEL, fail-closed." + }, + "disabled": { + "status": "live", + "evidence": "objectui: packages/app-shell/src/views/metadata-admin/previews/ActionPreview.tsx:169", + "note": "LIVE via objectui metadata-admin authoring UI — the 2026-06 audit missed objectui; verified by reading the file." + }, + "shortcut": { + "status": "live", + "evidence": "objectui: packages/app-shell/src/views/metadata-admin/previews/ActionPreview.tsx:158", + "note": "LIVE via objectui metadata-admin authoring UI — the 2026-06 audit missed objectui; verified by reading the file." + }, + "bulkEnabled": { + "status": "live", + "evidence": "objectui: packages/app-shell/src/views/metadata-admin/previews/ActionPreview.tsx:159", + "note": "LIVE via objectui metadata-admin authoring UI — the 2026-06 audit missed objectui; verified by reading the file." + }, + "ai": { + "status": "live", + "evidence": "packages/services/service-ai/src/tools/action-tools.ts", + "note": "full AI bridge (exposed/description/category/paramHints/outputSchema/requiresConfirmation)." + }, + "recordIdParam": { + "status": "live", + "note": "objectui + dispatcher." + }, + "recordIdField": { + "status": "live", + "note": "objectui + dispatcher." + }, + "bodyShape": { + "status": "live", + "evidence": "packages/runtime/src/http-dispatcher.ts", + "note": "{wrap} request shaping." + }, + "method": { + "status": "live", + "evidence": "packages/runtime/src/http-dispatcher.ts" + }, + "bodyExtra": { + "status": "live", + "evidence": "packages/runtime/src/http-dispatcher.ts" + }, + "mode": { + "status": "live", + "note": "PARTIAL — read only by the AI HITL heuristic (action-tools.ts), never by the UI." + }, + "opensInNewTab": { + "status": "live", + "note": "objectui." + }, + "newTabUrl": { + "status": "live", + "note": "objectui." + }, + "timeout": { + "status": "dead", + "evidence": "action-level timeout DEAD — server uses body.timeoutMs; no UI consumer" + }, + "aria": { + "status": "live", + "note": "PARTIAL — honored by a few objectui renderers, not the core action buttons/menus." + } } } diff --git a/packages/spec/liveness/agent.json b/packages/spec/liveness/agent.json index 669a2e236d..4da1f33f23 100644 --- a/packages/spec/liveness/agent.json +++ b/packages/spec/liveness/agent.json @@ -2,24 +2,96 @@ "type": "agent", "_note": "AgentSchema. Seeded from docs/audits/2026-06-agentschema-property-liveness.md. agent-runtime.ts is the runtime consumer; AgentPreview is display-only.", "props": { - "name": { "status": "live", "evidence": "packages/services/service-ai/src/agent-runtime.ts" }, - "label": { "status": "live", "note": "display/core." }, - "avatar": { "status": "live", "note": "display." }, - "role": { "status": "live", "evidence": "packages/services/service-ai/src/agent-runtime.ts", "note": "persona → system prompt." }, - "instructions": { "status": "live", "evidence": "packages/services/service-ai/src/agent-runtime.ts", "note": "system prompt." }, - "model": { "status": "live", "evidence": "packages/services/service-ai/src/agent-runtime.ts:264", "note": "PARTIAL — model/temperature/maxTokens applied; model.provider + topP DEAD." }, - "skills": { "status": "live", "evidence": "packages/services/service-ai/src/agent-runtime.ts", "note": "Agent→Skill→Tool." }, - "tools": { "status": "live", "evidence": "packages/services/service-ai/src/agent-runtime.ts", "note": "legacy direct-tool fallback." }, - "active": { "status": "live", "evidence": "packages/services/service-ai/src/agent-runtime.ts", "note": "gates listing + 403 on chat." }, - "planning": { "status": "live", "evidence": "packages/services/service-ai/src/agent-runtime.ts", "note": "PARTIAL — only planning.maxIterations live; strategy/allowReplan DEAD." }, - "access": { "status": "live", "evidence": "packages/services/service-ai/src/routes/agent-access.ts:50", "note": "evaluateAgentAccess() — allow-list by userId/role; enforced at the chat route (agent-routes.ts:151). #1884 (landed after the 2026-06 audit, which still listed it dead)." }, - "permissions": { "status": "live", "evidence": "packages/services/service-ai/src/routes/agent-access.ts:50", "note": "evaluateAgentAccess() — caller must hold ALL required permissions/roles; enforced at the chat route. #1884." }, - "visibility": { "status": "experimental", "evidence": "packages/services/service-ai/src/routes/agent-access.ts:41", "note": "intentionally NOT enforced — the chat-access evaluator excludes it and the GET /ai/agents list route does not filter by visibility. Needs owner/org semantics before it can gate listing." }, - "tenantId": { "status": "dead", "evidence": "no runtime reader" }, - "knowledge": { "status": "dead", "evidence": "no runtime reader; AgentPreview reads knowledge.sources but spec defines {topics,indexes}", "note": "shape drift; RAG via service-knowledge." }, - "lifecycle": { "status": "experimental", "evidence": "no runtime reader (StateMachine)", "note": "aspirational autonomy." }, - "memory": { "status": "experimental", "evidence": "no runtime reader", "note": "aspirational autonomy." }, - "guardrails": { "status": "experimental", "evidence": "no runtime reader", "note": "aspirational — real limits via quota service." }, - "structuredOutput": { "status": "experimental", "evidence": "no runtime reader", "note": "aspirational." } + "name": { + "status": "live", + "evidence": "packages/services/service-ai/src/agent-runtime.ts" + }, + "label": { + "status": "live", + "note": "display/core." + }, + "avatar": { + "status": "live", + "note": "display." + }, + "role": { + "status": "live", + "evidence": "packages/services/service-ai/src/agent-runtime.ts", + "note": "persona → system prompt." + }, + "instructions": { + "status": "live", + "evidence": "packages/services/service-ai/src/agent-runtime.ts", + "note": "system prompt." + }, + "model": { + "status": "live", + "evidence": "packages/services/service-ai/src/agent-runtime.ts:264", + "note": "PARTIAL — model/temperature/maxTokens applied; model.provider + topP DEAD." + }, + "skills": { + "status": "live", + "evidence": "packages/services/service-ai/src/agent-runtime.ts", + "note": "Agent→Skill→Tool." + }, + "tools": { + "status": "live", + "evidence": "packages/services/service-ai/src/agent-runtime.ts", + "note": "legacy direct-tool fallback." + }, + "active": { + "status": "live", + "evidence": "packages/services/service-ai/src/agent-runtime.ts", + "note": "gates listing + 403 on chat." + }, + "planning": { + "status": "live", + "evidence": "packages/services/service-ai/src/agent-runtime.ts", + "note": "PARTIAL — only planning.maxIterations live; strategy/allowReplan DEAD." + }, + "access": { + "status": "live", + "evidence": "packages/services/service-ai/src/routes/agent-access.ts:50", + "note": "evaluateAgentAccess() — allow-list by userId/role; enforced at the chat route (agent-routes.ts:151). #1884 (landed after the 2026-06 audit, which still listed it dead)." + }, + "permissions": { + "status": "live", + "evidence": "packages/services/service-ai/src/routes/agent-access.ts:50", + "note": "evaluateAgentAccess() — caller must hold ALL required permissions/roles; enforced at the chat route. #1884." + }, + "visibility": { + "status": "experimental", + "evidence": "packages/services/service-ai/src/routes/agent-access.ts:41", + "note": "intentionally NOT enforced — the chat-access evaluator excludes it and the GET /ai/agents list route does not filter by visibility. Needs owner/org semantics before it can gate listing." + }, + "tenantId": { + "status": "dead", + "evidence": "no runtime reader" + }, + "knowledge": { + "status": "live", + "evidence": "objectui: packages/app-shell/src/views/metadata-admin/previews/AgentPreview.tsx:69 (d.knowledge; KnowledgeSummary renders sources/indexes)", + "note": "LIVE via objectui metadata-admin authoring UI — the 2026-06 audit missed objectui; verified by reading the file." + }, + "lifecycle": { + "status": "experimental", + "evidence": "no runtime reader (StateMachine)", + "note": "aspirational autonomy." + }, + "memory": { + "status": "experimental", + "evidence": "no runtime reader", + "note": "aspirational autonomy." + }, + "guardrails": { + "status": "experimental", + "evidence": "no runtime reader", + "note": "aspirational — real limits via quota service." + }, + "structuredOutput": { + "status": "experimental", + "evidence": "no runtime reader", + "note": "aspirational." + } } } diff --git a/packages/spec/liveness/flow.json b/packages/spec/liveness/flow.json index 211b485850..8661f849ed 100644 --- a/packages/spec/liveness/flow.json +++ b/packages/spec/liveness/flow.json @@ -2,40 +2,132 @@ "type": "flow", "_note": "FlowSchema. Seeded from docs/audits/2026-06-flowschema-property-liveness.md. Consumers: service-automation engine + node executors. runAs is marker-driven experimental (spec). status/active gate nothing (engine uses an in-memory flowEnabled map via toggleFlow).", "props": { - "name": { "status": "live", "evidence": "packages/services/service-automation/src/engine.ts" }, - "label": { "status": "live", "note": "display." }, - "description": { "status": "dead", "evidence": "no reader either layer" }, - "version": { "status": "live", "evidence": "packages/services/service-automation/src/engine.ts" }, - "status": { "status": "dead", "evidence": "engine gates on its in-memory flowEnabled map (toggleFlow), not on status", "note": "collapse with active (ADR-0049 recommendation)." }, - "active": { "status": "dead", "evidence": "spec-flagged Deprecated; redundant with status; engine uses flowEnabled" }, - "template": { "status": "dead", "evidence": "no reader either layer" }, - "type": { "status": "live", "evidence": "packages/services/service-automation/src/engine.ts:637", "note": "flow.type==='schedule'/'api' drives trigger dispatch." }, - "variables": { "status": "live", "evidence": "packages/services/service-automation/src/engine.ts", "note": "{name,isInput,isOutput} wired." }, - "edges": { "status": "live", "evidence": "packages/services/service-automation/src/engine.ts", "note": "{source,target,condition(CEL),label} wired." }, + "name": { + "status": "live", + "evidence": "packages/services/service-automation/src/engine.ts" + }, + "label": { + "status": "live", + "note": "display." + }, + "description": { + "status": "dead", + "evidence": "no reader either layer" + }, + "version": { + "status": "live", + "evidence": "packages/services/service-automation/src/engine.ts" + }, + "status": { + "status": "live", + "evidence": "objectui: packages/app-shell/src/views/metadata-admin/previews/FlowPreview.tsx:105", + "note": "LIVE via objectui metadata-admin authoring UI — the 2026-06 audit missed objectui; verified by reading the file." + }, + "active": { + "status": "live", + "evidence": "objectui: packages/app-shell/src/views/metadata-admin/previews/FlowPreview.tsx:105", + "note": "LIVE via objectui metadata-admin authoring UI — the 2026-06 audit missed objectui; verified by reading the file." + }, + "template": { + "status": "dead", + "evidence": "no reader either layer" + }, + "type": { + "status": "live", + "evidence": "packages/services/service-automation/src/engine.ts:637", + "note": "flow.type==='schedule'/'api' drives trigger dispatch." + }, + "variables": { + "status": "live", + "evidence": "packages/services/service-automation/src/engine.ts", + "note": "{name,isInput,isOutput} wired." + }, + "edges": { + "status": "live", + "evidence": "packages/services/service-automation/src/engine.ts", + "note": "{source,target,condition(CEL),label} wired." + }, "nodes": { "children": { - "id": { "status": "live", "evidence": "packages/services/service-automation/src/engine.ts" }, - "type": { "status": "live", "evidence": "packages/services/service-automation/src/engine.ts", "note": "open string vs live executor registry (ADR-0018); FlowNodeAction enum is out of sync." }, - "label": { "status": "live", "note": "designer/display." }, - "config": { "status": "live", "evidence": "packages/services/service-automation/src/engine.ts" }, - "connectorConfig": { "status": "live", "evidence": "packages/services/service-automation/src/engine.ts" }, - "position": { "status": "live", "note": "designer canvas layout (no engine consumer)." }, - "timeoutMs": { "status": "live", "evidence": "packages/services/service-automation/src/engine.ts" }, - "inputSchema": { "status": "live", "evidence": "packages/services/service-automation/src/engine.ts", "note": "runtime-validated." }, - "outputSchema": { "status": "dead", "evidence": "declared, never validated" }, - "waitEventConfig": { "status": "live", "evidence": "packages/services/service-automation/src/engine.ts" }, - "boundaryConfig": { "status": "dead", "evidence": "drives the dead boundary_event node (BPMN import/export-only, no executor)" } + "id": { + "status": "live", + "evidence": "packages/services/service-automation/src/engine.ts" + }, + "type": { + "status": "live", + "evidence": "packages/services/service-automation/src/engine.ts", + "note": "open string vs live executor registry (ADR-0018); FlowNodeAction enum is out of sync." + }, + "label": { + "status": "live", + "note": "designer/display." + }, + "config": { + "status": "live", + "evidence": "packages/services/service-automation/src/engine.ts" + }, + "connectorConfig": { + "status": "live", + "evidence": "packages/services/service-automation/src/engine.ts" + }, + "position": { + "status": "live", + "note": "designer canvas layout (no engine consumer)." + }, + "timeoutMs": { + "status": "live", + "evidence": "packages/services/service-automation/src/engine.ts" + }, + "inputSchema": { + "status": "live", + "evidence": "packages/services/service-automation/src/engine.ts", + "note": "runtime-validated." + }, + "outputSchema": { + "status": "dead", + "evidence": "declared, never validated" + }, + "waitEventConfig": { + "status": "live", + "evidence": "packages/services/service-automation/src/engine.ts" + }, + "boundaryConfig": { + "status": "live", + "evidence": "objectui: packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.ts:480", + "note": "LIVE via objectui metadata-admin authoring UI — the 2026-06 audit missed objectui; verified by reading the file." + } } }, "errorHandling": { "children": { - "strategy": { "status": "live", "evidence": "packages/services/service-automation/src/engine.ts" }, - "maxRetries": { "status": "live", "evidence": "packages/services/service-automation/src/engine.ts" }, - "retryDelayMs": { "status": "live", "evidence": "packages/services/service-automation/src/engine.ts" }, - "backoffMultiplier": { "status": "live", "evidence": "packages/services/service-automation/src/engine.ts" }, - "maxRetryDelayMs": { "status": "live", "evidence": "packages/services/service-automation/src/engine.ts" }, - "jitter": { "status": "live", "evidence": "packages/services/service-automation/src/engine.ts" }, - "fallbackNodeId": { "status": "dead", "evidence": "engine uses per-node fault edges, not this" } + "strategy": { + "status": "live", + "evidence": "packages/services/service-automation/src/engine.ts" + }, + "maxRetries": { + "status": "live", + "evidence": "packages/services/service-automation/src/engine.ts" + }, + "retryDelayMs": { + "status": "live", + "evidence": "packages/services/service-automation/src/engine.ts" + }, + "backoffMultiplier": { + "status": "live", + "evidence": "packages/services/service-automation/src/engine.ts" + }, + "maxRetryDelayMs": { + "status": "live", + "evidence": "packages/services/service-automation/src/engine.ts" + }, + "jitter": { + "status": "live", + "evidence": "packages/services/service-automation/src/engine.ts" + }, + "fallbackNodeId": { + "status": "dead", + "evidence": "engine uses per-node fault edges, not this" + } } } } diff --git a/packages/spec/liveness/permission.json b/packages/spec/liveness/permission.json index 266ebbf08b..11fbe357f0 100644 --- a/packages/spec/liveness/permission.json +++ b/packages/spec/liveness/permission.json @@ -2,42 +2,126 @@ "type": "permission", "_note": "PermissionSetSchema (also aliased as `profile`). Seeded from docs/audits/2026-06-security-identity-property-liveness.md. CRUD/FLS/RLS enforced via plugin-security; destructive ops + isProfile/contextVariables dead. allowTransfer/Restore/Purge are marker-driven experimental (spec `[EXPERIMENTAL — not enforced]`).", "props": { - "name": { "status": "live", "evidence": "packages/plugins/plugin-security/src/permission-evaluator.ts", "note": "registration/assignment key." }, - "label": { "status": "live", "note": "display metadata." }, - "isProfile": { "status": "dead", "evidence": "audit: profile-vs-permset never gates anything" }, + "name": { + "status": "live", + "evidence": "packages/plugins/plugin-security/src/permission-evaluator.ts", + "note": "registration/assignment key." + }, + "label": { + "status": "live", + "note": "display metadata." + }, + "isProfile": { + "status": "live", + "evidence": "objectui: packages/app-shell/src/views/metadata-admin/previews/PermissionPreview.tsx:92 (!!d.isProfile)", + "note": "LIVE via objectui metadata-admin authoring UI — the 2026-06 audit missed objectui; verified by reading the file." + }, "objects": { "children": { - "allowCreate": { "status": "live", "evidence": "packages/plugins/plugin-security/src/permission-evaluator.ts:8" }, - "allowRead": { "status": "live", "evidence": "packages/plugins/plugin-security/src/permission-evaluator.ts:8" }, - "allowEdit": { "status": "live", "evidence": "packages/plugins/plugin-security/src/permission-evaluator.ts:8" }, - "allowDelete": { "status": "live", "evidence": "packages/plugins/plugin-security/src/permission-evaluator.ts:8" }, - "viewAllRecords": { "status": "live", "evidence": "packages/plugins/plugin-security/src/permission-evaluator.ts:64" }, - "modifyAllRecords": { "status": "live", "evidence": "packages/plugins/plugin-security/src/permission-evaluator.ts:60" } + "allowCreate": { + "status": "live", + "evidence": "packages/plugins/plugin-security/src/permission-evaluator.ts:8" + }, + "allowRead": { + "status": "live", + "evidence": "packages/plugins/plugin-security/src/permission-evaluator.ts:8" + }, + "allowEdit": { + "status": "live", + "evidence": "packages/plugins/plugin-security/src/permission-evaluator.ts:8" + }, + "allowDelete": { + "status": "live", + "evidence": "packages/plugins/plugin-security/src/permission-evaluator.ts:8" + }, + "viewAllRecords": { + "status": "live", + "evidence": "packages/plugins/plugin-security/src/permission-evaluator.ts:64" + }, + "modifyAllRecords": { + "status": "live", + "evidence": "packages/plugins/plugin-security/src/permission-evaluator.ts:60" + } } }, "fields": { "children": { - "readable": { "status": "live", "evidence": "packages/plugins/plugin-security/src/permission-evaluator.ts", "note": "FLS read-mask." }, - "editable": { "status": "live", "evidence": "packages/plugins/plugin-security/src/permission-evaluator.ts", "note": "FLS write-deny." } + "readable": { + "status": "live", + "evidence": "packages/plugins/plugin-security/src/permission-evaluator.ts", + "note": "FLS read-mask." + }, + "editable": { + "status": "live", + "evidence": "packages/plugins/plugin-security/src/permission-evaluator.ts", + "note": "FLS write-deny." + } } }, - "systemPermissions": { "status": "live", "evidence": "packages/plugins/plugin-hono-server/src/hono-plugin.ts", "note": "PARTIAL — app-entry/nav visibility only, not a general capability gate." }, - "tabPermissions": { "status": "live", "note": "PARTIAL — only 'hidden' is read." }, + "systemPermissions": { + "status": "live", + "evidence": "packages/plugins/plugin-hono-server/src/hono-plugin.ts", + "note": "PARTIAL — app-entry/nav visibility only, not a general capability gate." + }, + "tabPermissions": { + "status": "live", + "note": "PARTIAL — only 'hidden' is read." + }, "rowLevelSecurity": { "children": { - "name": { "status": "live", "evidence": "packages/plugins/plugin-security/src/rls-compiler.ts" }, - "label": { "status": "live", "note": "display." }, - "description": { "status": "live", "note": "display." }, - "object": { "status": "live", "evidence": "packages/plugins/plugin-security/src/rls-compiler.ts" }, - "operation": { "status": "live", "evidence": "packages/plugins/plugin-security/src/rls-compiler.ts" }, - "using": { "status": "live", "evidence": "packages/plugins/plugin-security/src/rls-compiler.ts", "note": "compiled into find + analytics SQL." }, - "check": { "status": "live", "evidence": "packages/plugins/plugin-security/src/rls-compiler.ts" }, - "roles": { "status": "live", "evidence": "packages/plugins/plugin-security/src/rls-compiler.ts", "note": "flat match — no subordinate rollup." }, - "enabled": { "status": "live", "evidence": "packages/plugins/plugin-security/src/rls-compiler.ts" }, - "priority": { "status": "live", "evidence": "packages/plugins/plugin-security/src/rls-compiler.ts", "note": "ordering." }, - "tags": { "status": "live", "note": "organizational." } + "name": { + "status": "live", + "evidence": "packages/plugins/plugin-security/src/rls-compiler.ts" + }, + "label": { + "status": "live", + "note": "display." + }, + "description": { + "status": "live", + "note": "display." + }, + "object": { + "status": "live", + "evidence": "packages/plugins/plugin-security/src/rls-compiler.ts" + }, + "operation": { + "status": "live", + "evidence": "packages/plugins/plugin-security/src/rls-compiler.ts" + }, + "using": { + "status": "live", + "evidence": "packages/plugins/plugin-security/src/rls-compiler.ts", + "note": "compiled into find + analytics SQL." + }, + "check": { + "status": "live", + "evidence": "packages/plugins/plugin-security/src/rls-compiler.ts" + }, + "roles": { + "status": "live", + "evidence": "packages/plugins/plugin-security/src/rls-compiler.ts", + "note": "flat match — no subordinate rollup." + }, + "enabled": { + "status": "live", + "evidence": "packages/plugins/plugin-security/src/rls-compiler.ts" + }, + "priority": { + "status": "live", + "evidence": "packages/plugins/plugin-security/src/rls-compiler.ts", + "note": "ordering." + }, + "tags": { + "status": "live", + "note": "organizational." + } } }, - "contextVariables": { "status": "dead", "evidence": "rls-compiler.ts never reads it", "note": "RLS uses only current_user.* built-ins." } + "contextVariables": { + "status": "dead", + "evidence": "rls-compiler.ts never reads it", + "note": "RLS uses only current_user.* built-ins." + } } } diff --git a/packages/spec/liveness/role.json b/packages/spec/liveness/role.json index d808cb9394..7e161e23e0 100644 --- a/packages/spec/liveness/role.json +++ b/packages/spec/liveness/role.json @@ -2,9 +2,23 @@ "type": "role", "_note": "RoleSchema. Seeded from docs/audits/2026-06-security-identity-property-liveness.md.", "props": { - "name": { "status": "live", "evidence": "packages/plugins/plugin-security/src/permission-evaluator.ts:113", "note": "sys_role.name reused as a permission-set name." }, - "label": { "status": "live", "note": "display (admin nav/forms, security-plugin.ts:153)." }, - "description": { "status": "live", "note": "display." }, - "parent": { "status": "dead", "evidence": "no consumer (grep); org hierarchy walks sys_department.parent_department_id via department-graph.ts, not sys_role.parent", "note": "'Reports To' rollup unimplemented — removal candidate (ADR-0049)." } + "name": { + "status": "live", + "evidence": "packages/plugins/plugin-security/src/permission-evaluator.ts:113", + "note": "sys_role.name reused as a permission-set name." + }, + "label": { + "status": "live", + "note": "display (admin nav/forms, security-plugin.ts:153)." + }, + "description": { + "status": "live", + "note": "display." + }, + "parent": { + "status": "live", + "evidence": "objectui: packages/app-shell/src/views/metadata-admin/previews/RolePreview.tsx:30 (const parent = d.parent)", + "note": "LIVE via objectui metadata-admin authoring UI — the 2026-06 audit missed objectui; verified by reading the file." + } } } diff --git a/packages/spec/liveness/skill.json b/packages/spec/liveness/skill.json index 9a575332f4..d49c47aab3 100644 --- a/packages/spec/liveness/skill.json +++ b/packages/spec/liveness/skill.json @@ -2,14 +2,49 @@ "type": "skill", "_note": "SkillSchema. Seeded from docs/audits/2026-06-skillschema-property-liveness.md. skill-registry.ts + agent-runtime.ts are the runtime consumers.", "props": { - "name": { "status": "live", "evidence": "packages/services/service-ai/src/skill-registry.ts" }, - "label": { "status": "live", "evidence": "packages/services/service-ai/src/skill-registry.ts:247", "note": "injected into the agent system prompt." }, - "description": { "status": "live", "evidence": "packages/services/service-ai/src/skill-registry.ts:247", "note": "injected into prompt." }, - "instructions": { "status": "live", "evidence": "packages/services/service-ai/src/skill-registry.ts:247", "note": "injected into prompt." }, - "tools": { "status": "live", "evidence": "packages/services/service-ai/src/skill-registry.ts:206", "note": "tool-contribution path incl. action_* wildcard." }, - "triggerConditions": { "status": "live", "evidence": "packages/services/service-ai/src/skill-registry.ts:153", "note": "THE activation gate — AND of {field,operator,value}." }, - "active": { "status": "live", "evidence": "packages/services/service-ai/src/skill-registry.ts:93", "note": "inactive skills dropped." }, - "triggerPhrases": { "status": "dead", "evidence": "no intent/phrase matcher; only the slash-command palette summary (toSummary)", "note": "intent routing unimplemented." }, - "permissions": { "status": "dead", "evidence": "no code restricts a skill by skill.permissions; naming drift (preview calls it requiredPermissions)" } + "name": { + "status": "live", + "evidence": "packages/services/service-ai/src/skill-registry.ts" + }, + "label": { + "status": "live", + "evidence": "packages/services/service-ai/src/skill-registry.ts:247", + "note": "injected into the agent system prompt." + }, + "description": { + "status": "live", + "evidence": "packages/services/service-ai/src/skill-registry.ts:247", + "note": "injected into prompt." + }, + "instructions": { + "status": "live", + "evidence": "packages/services/service-ai/src/skill-registry.ts:247", + "note": "injected into prompt." + }, + "tools": { + "status": "live", + "evidence": "packages/services/service-ai/src/skill-registry.ts:206", + "note": "tool-contribution path incl. action_* wildcard." + }, + "triggerConditions": { + "status": "live", + "evidence": "packages/services/service-ai/src/skill-registry.ts:153", + "note": "THE activation gate — AND of {field,operator,value}." + }, + "active": { + "status": "live", + "evidence": "packages/services/service-ai/src/skill-registry.ts:93", + "note": "inactive skills dropped." + }, + "triggerPhrases": { + "status": "live", + "evidence": "objectui: packages/app-shell/src/views/metadata-admin/previews/SkillPreview.tsx:44", + "note": "LIVE via objectui metadata-admin authoring UI — the 2026-06 audit missed objectui; verified by reading the file." + }, + "permissions": { + "status": "live", + "evidence": "objectui: packages/app-shell/src/views/metadata-admin/previews/SkillPreview.tsx:48", + "note": "LIVE via objectui metadata-admin authoring UI — the 2026-06 audit missed objectui; verified by reading the file." + } } } diff --git a/packages/spec/liveness/tool.json b/packages/spec/liveness/tool.json index 61243c11cc..0ae5fa676d 100644 --- a/packages/spec/liveness/tool.json +++ b/packages/spec/liveness/tool.json @@ -2,16 +2,58 @@ "type": "tool", "_note": "ToolSchema. Seeded from docs/audits/2026-06-toolschema-property-liveness.md. Tool metadata is WRITE-ONLY (projected one-way for Studio; runtime uses a separate AIToolDefinition). LIVE props are live via that same-named surface, not metadata read-back.", "props": { - "name": { "status": "live", "evidence": "packages/services/service-ai/src/adapters/vercel-adapter.ts:46", "note": "selection + LLM function key." }, - "label": { "status": "live", "note": "display." }, - "description": { "status": "live", "evidence": "packages/services/service-ai/src/adapters/vercel-adapter.ts:46", "note": "sent to the LLM." }, - "parameters": { "status": "live", "evidence": "packages/services/service-ai/src/adapters/vercel-adapter.ts:46", "note": "LLM function schema." }, - "objectName": { "status": "live", "evidence": "packages/services/service-ai/src/tools/action-tools.ts:535", "note": "action-tool dispatch." }, - "outputSchema": { "status": "experimental", "evidence": "packages/services/service-ai/src/tools/action-tools.ts:437", "note": "keys folded into description only; no validation exists." }, - "category": { "status": "dead", "evidence": "listing/preview tag only; enum drift vs AIToolDefinition free-string" }, - "requiresConfirmation": { "status": "dead", "evidence": "packages/services/service-ai/src/tools/action-tools.ts:239", "note": "HITL re-derives from action.ai.requiresConfirmation; never read off the def." }, - "permissions": { "status": "dead", "evidence": "tool.form.ts only; not on AIToolDefinition, no consumer" }, - "active": { "status": "dead", "evidence": "never set by any registration path" }, - "builtIn": { "status": "dead", "evidence": "never set by any registration path" } + "name": { + "status": "live", + "evidence": "packages/services/service-ai/src/adapters/vercel-adapter.ts:46", + "note": "selection + LLM function key." + }, + "label": { + "status": "live", + "note": "display." + }, + "description": { + "status": "live", + "evidence": "packages/services/service-ai/src/adapters/vercel-adapter.ts:46", + "note": "sent to the LLM." + }, + "parameters": { + "status": "live", + "evidence": "packages/services/service-ai/src/adapters/vercel-adapter.ts:46", + "note": "LLM function schema." + }, + "objectName": { + "status": "live", + "evidence": "packages/services/service-ai/src/tools/action-tools.ts:535", + "note": "action-tool dispatch." + }, + "outputSchema": { + "status": "experimental", + "evidence": "packages/services/service-ai/src/tools/action-tools.ts:437", + "note": "keys folded into description only; no validation exists." + }, + "category": { + "status": "live", + "evidence": "objectui: packages/app-shell/src/views/metadata-admin/previews/ToolPreview.tsx:99", + "note": "LIVE via objectui metadata-admin authoring UI — the 2026-06 audit missed objectui; verified by reading the file." + }, + "requiresConfirmation": { + "status": "live", + "evidence": "objectui: packages/app-shell/src/views/metadata-admin/previews/ToolPreview.tsx:101", + "note": "LIVE via objectui metadata-admin authoring UI — the 2026-06 audit missed objectui; verified by reading the file." + }, + "permissions": { + "status": "dead", + "evidence": "tool.form.ts only; not on AIToolDefinition, no consumer" + }, + "active": { + "status": "live", + "evidence": "objectui: packages/app-shell/src/views/metadata-admin/previews/ToolPreview.tsx:102", + "note": "LIVE via objectui metadata-admin authoring UI — the 2026-06 audit missed objectui; verified by reading the file." + }, + "builtIn": { + "status": "live", + "evidence": "objectui: packages/app-shell/src/views/metadata-admin/previews/ToolPreview.tsx:103", + "note": "LIVE via objectui metadata-admin authoring UI — the 2026-06 audit missed objectui; verified by reading the file." + } } }