๐Ÿ“ฅ Feedback

Actionable inbox items for Clara to process. The "proactive sticky notes" of the portal.

Why Feedback Exists

Feedback was created as part of the Entity Architecture refactoring (A82, April 2026). The old comments table was overloaded โ€” serving as both permanent history AND an actionable inbox. This caused confusion:

The original problem: "Previously I want to leave a comment, but actually what I really mean is I want to leave a feedback, that will be collected and processed. Then the comment (actually feedback) will be gone when we run Clara." โ€” Adrian

The solution: split into Comment (permanent, backward-looking) and Feedback (actionable, forward-looking).

Schema

D1 feedback table

Proactive inbox items. Clara's sweep pulls from here.
idTEXT PK โ€” UUID
contentTEXT NOT NULL โ€” The feedback message
workspaceTEXT โ€” Optional workspace routing
priorityTEXT โ€” urgent | high | normal | low (default: normal)
statusTEXT โ€” open | processed | parked | archived (default: open)
targetTEXT โ€” Optional target entity
linked_typeTEXT โ€” task | report | job (optional)
linked_idTEXT โ€” ID of linked entity (optional)
sourceTEXT โ€” portal | clara | claudebot | agent (default: portal)
processed_atTEXT โ€” Timestamp set once when processed (immutable)
processed_noteTEXT โ€” Clara's one-liner ("Created A67" or "Not actionable")
created_atTEXT โ€” ISO timestamp
updated_atTEXT โ€” ISO timestamp

Lifecycle

open โ†’ processed
open โ†’ parked โ†’ open (promote)
any โ†’ archived

Ownership Rules

Transition Who Notes
open โ†’ processed Clara only She's the one doing the processing. Sets processed_at + processed_note.
* โ†’ parked Adrian only Conscious decision: "I've read this, I'm choosing not to act now."
* โ†’ archived Adrian only "I don't care about this anymore." Not the same as processing.
parked โ†’ open Adrian only Promotes parked feedback back to Clara's queue.
"Processed" is immutable: Once Clara marks feedback as processed, it cannot be reopened. The outcome lives elsewhere โ€” if Clara created a task from it, the task carries it forward. If she decided it wasn't actionable, that's captured in processed_note.

Agent-Posted Feedback

When agents (not humans) post feedback, it arrives as parked โ€” not open. This prevents agents from presumptively filling Clara's queue.

Inversion: Agents say "here's a thought" (parked). Adrian decides whether it's worth Clara's time by promoting to open. The source field disambiguates the origin.

API

Method Endpoint Description
GET /api/feedback List. Filter: ?status=open, ?workspace=agentic
POST /api/feedback Create. Body: { content, workspace?, priority?, source? }
PATCH /api/feedback?id=xxx Update status/content. Body: { status: "processed", processed_note: "Created A87" }
DELETE /api/feedback?id=xxx Hard delete (prefer PATCH to archive)

Where It Appears

Location Context
Inbox page Global feedback view โ€” all open feedback across workspaces
Task modal โ†’ Feedback tab Feedback scoped to a specific task (target: task:workspace:id)
Report viewer โ†’ Annotations drawer Feedback on reports โ€” "This report needs updating" or "Finding is outdated"

Naming Decisions

Choice Alternatives Rejected Why
Feedback Notes, Inbox Items Feedback implies someone should act. "Notes" feels passive.
Processed Considered, Evaluated Unambiguous. "This item has been through the pipeline."
Open Ready "Ready" collides with task status. "Open" is universal.
Parked Draft "Draft" implies incomplete writing. "Parked" = consciously deferred.