Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .changeset/reaudit-crossrepo.md
Original file line number Diff line number Diff line change
@@ -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.
4 changes: 4 additions & 0 deletions docs/audits/2026-06-dead-surface-disposition-plan.md
Original file line number Diff line number Diff line change
@@ -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).
Expand Down
166 changes: 135 additions & 31 deletions packages/spec/liveness/action.json
Original file line number Diff line number Diff line change
Expand Up @@ -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."
}
}
}
110 changes: 91 additions & 19 deletions packages/spec/liveness/agent.json
Original file line number Diff line number Diff line change
Expand Up @@ -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."
}
}
}
Loading
Loading