Feedback
A drop-in feedback capability for any MeshWeaver deployment. A user types /feedback <message>
in any thread; the flow captures the message plus the context that makes it actionable, files it
as a draft, and shows the user a polished preview with a Submit button — so they see exactly
what will be sent before it goes. Only when they click Submit does it reach the shared
Feedback space, where Systemorph reviews it.
What gets captured
Every submission is a Feedback/Feedback node whose FeedbackContent records:
| Field | Source | Notes |
|---|---|---|
message |
the user's words, verbatim | the record itself |
submittedBy / submittedByName |
# Current User context |
who |
timestamp |
server, stamped on submit | real ISO-8601 UTC; a client can't backdate |
mainNodePath / mainNodeTitle / mainNodeGist |
# Current Application Context |
where they were (the main panel) + a gist |
sidePanel |
the agent, if reachable | related area open beside the main panel |
extraContext |
the agent, opportunistically | role, repro detail, related paths, … |
category |
inferred, only if obvious | bug | idea | praise | question — and answer, filed by /wrong-answer for a qualitative miss |
status |
server | Draft on capture (invisible to reviewers); flips to New when the user hits Submit; a reviewer then moves it to Triaged / Resolved / WontFix |
issueUrl |
the control instance | the GitHub issue the Systemorph triage agent filed for it, written back when the feedback was submitted here and turned out to be actionable; empty otherwise |
Every context field is optional — the agent fills what it can reach and leaves the rest empty (shown as "not captured" in the review view). A submission never fails because a field couldn't be filled.
The pieces
/feedbackskill (Feedback/Skill/feedback) — the entry point. Instructs the thread agent to capture the message + context, extract more if it can, file a draft, and show the user the preview to review and submit. Prefers the Feedback Agent when present./wrong-answerskill (Feedback/Skill/wrong-answer) — the entry point for a qualitative miss: the chat made something up, said "I don't know" about something in the mesh, answered from the wrong source, or changed something unasked. Reads the offendingThreadMessage(agent, model, tool calls), checks whether the node the user meant is readable, classifies the failure and files the sameFeedback/Feedbackdraft withcategory: answer— which stays in the Inbox for a person to route. Runs in-thread (never hands off — the evidence is in the thread). Design, kinds and addressees: Wrong answers.Feedback Agent (
Feedback/Agent/feedback-agent) — the "feedback agent": does the capture-draft-preview. Callable directly (@agent/Feedback/Agent/feedback-agent) or by the skill.FeedbackContenttype (Feedback/Feedback, compiled live fromSource/) — the record and its views (the card is drawn once and reused, so the submitter's preview is byte-for-byte the reviewer's view):- Compose — the preview-and-submit surface (
Feedback/Compose/{id}or@@("/{User ID}/Feedback/{id}/area/Compose")). Loads the captured draft (as System) and shows it as a card whose message is an editable, data-bound field (host.Edit), with a Submit button. Nothing reaches the reviewers until the user clicks it — this is what lets them SEE and refine their feedback before it's sent. - Detail — the reviewer's full view of one submission (message + all context, present-or-not).
- Inbox — the admin review list on the space root: every submitted submission (drafts excluded), newest first.
- Submit — the space-root "give feedback via chat" call to action (points the user to
/feedback). Feedback is captured in chat, previewed, edited and submitted — there's no separate in-page form.
Every view is built from framework controls styled with CSS — no hand-rolled HTML.
- Compose — the preview-and-submit surface (
FeedbackSubmitter(Source/FeedbackSubmitter.cs) — the submit-as-System core. Every write (create draft, publish, in-UI submit) runs underAccessService.ImpersonateAsSystem()(the same trickCouponRedeemeruses), so any signed-in user can submit even though they have no write access to theFeedbackpartition.CreateDraftcaptures aDraft;Publish(the Submit button) reads the draft as System, flips it toNewand stamps the real submit time — so a client can neither backdate nor pre-triage, and nothing is visible to reviewers until the user submits.
After Submit: technical feedback is handed to the Systemorph triage agent
Maintainer, 2026-09-12: "the feedback skill must do exactly this ⇒ if it is a technical issue / bug report / feature request ⇒ hand over to systemorph-com triage agent."
When the user clicks Submit — and never before — the submission reads New, and its OWN hub
hands it over (FeedbackHandover.HandOverOnActivation, Source/FeedbackHandover.cs): the hub
observes its node, and whenever the node reads New, technical, and not yet stamped
handedOverAt, it sends ONE signed event and writes the stamp. Publish merely flips
Draft → New; it no longer hands over inline. Since 2026-09-20 this is the ONLY hand-over path,
and it is the RequestedX + owning-hub-watcher shape for a reason: a submission created New by
anyone — the /feedback skill, an agent through MCP, the platform's thread supervisor filing an
exhausted thread (Doc/Architecture/ThreadSupervision) — is handed over the moment its hub
activates, not only when a person pressed a button in this process. Creation alone activates
nothing (the create is handled by the owner namespace's hub), so FeedbackSubmitter.Submit reads
the node once after creating it — the same wake hub.StartThread gives a thread — and an
agent creating the node directly must read it once too. handedOverAt on the submission is the
proof it went; a technical New submission without it on a portal whose control inbox is
configured is one whose hub never activated.
What is handed over is unchanged:
| The feedback | What happens |
|---|---|
category: bug or idea |
handed over, always |
category: question, or no category |
handed over when the message reads as technical — it names a defect or a feature (FeedbackHandover.LooksTechnical) |
category: praise, or a non-technical message |
stays in this instance's Inbox; nothing is sent |
category: answer (a /wrong-answer report) |
stays in this instance's Inbox even when the message reads as technical — its addressee is the agent's owner, a space owner or a content owner here (Wrong answers); the one kind that is a platform defect is filed as bug by the skill and takes the first row |
"Handed over" means ONE signed feedback event on the control instance's pooled inbox
(https://memex.systemorph.com/api/hooks/Hosting/PlatformBuilds) — the same URL and HMAC every
fleet repository's CI posts to. There it becomes a Hosting/TriageItem, a thread with the
triage agent, and — for what is actionable — a GitHub issue, filed via systemorph-com in
the repository that owns the Space the feedback was given on (else Systemorph/MeshWeaver.Feedback).
When the feedback was submitted on the control instance itself, the issue URL is written back onto
the Feedback node (issueUrl). The mechanism end to end is Hosting's
Triage page.
Configuration — two keys, both required, defined once per portal:
| Key | Value |
|---|---|
Hosting:ControlInbox:Url |
https://memex.systemorph.com/api/hooks/Hosting/PlatformBuilds |
Hosting:ControlInbox:Secret |
the control inbox's HMAC secret — the same value as the control instance's Hosting:PlatformWebhookSecret (Key Vault), mapped e.g. as memexcloud-Hosting-ControlInbox-Secret |
With either key absent the plugin logs one warning per technical submission naming both keys
and keeps today's behaviour — the submission stays in the Inbox. The control instance itself
needs neither: it lists Hosting/PlatformBuilds as a webhook target and holds the watcher's
secret, so it delivers the same signed event into its own inbox. A hand-over that fails for any
reason (network, a refused signature) is logged and never fails the submission.
Where submissions live
Feedback/_Submissions/{id} — an underscore container (kept out of catalogs). The Feedback space's
Inbox area lists them for reviewers. Feedback is admin-reviewed: seed the space so only
platform admins read it.
Tests
- Unit (
Feedback/Feedback/Test/FeedbackTests.cs, run by theTestslayout area and asserted by CI): content-type defaults, the pure submission-building core (timestamp stamping,New/Draftpinning, the Draft→New publish transition, the draft/Inbox filter, id/summary/description shapes), the shared card renderer (message shown, empty context hidden in the preview, HTML escaped, main node linked) and the message-only graceful-degradation contract. - e2e (
e2e/feedback-skill.spec.ts,npm run feedback-skill): drives the memex portal —/feedback <marker>in a thread → agent confirms → the node lands in the Inbox with the message, submitter and main-node context.