Give both kinds of card the same anatomy
A question the room answered and a comment the room accepted are the same kind of thing, and looked nothing alike: one had a header and no provenance, the other provenance and no header. Two components drawing similar chrome by convention is how that happens, so the chrome moved into a shell both use, and neither draws its own any more. The header names the kind; the footer's verb carries the status, because "accepted by" and "answered by" already say it. The footer was not just missing for questionnaires, it was impossible. QuestionView has rendered "Answered by @x" all along and nothing could pass it a resolver: the client builds those cards from the document, and the document recorded no such thing. There was no timestamp anywhere either, not even in the server's record. So a questionnaire now records who settled it and when, in the plan, the way an accepted comment already did. On the container rather than on each answer, because it resolves as a unit — derive is all-or-nothing — so every Answer would otherwise repeat one handle and one moment. Decision carries its provenance the same way, which makes the two identical in shape rather than merely similar. That took a deviation from what was agreed, which said Answer; the reasoning is in the dialect. Both attributes are optional, so every existing plan.mdx still validates, and no wire change was needed: the client already reads the whole questionnaire off the node. One questionnaire answered before any of this will show no footer. Its record has a resolver but the file has nothing and there is no timestamp to recover. Not backfilled on load — the plan is a file a person can edit between runs, and correcting it at startup is the thing we decided against for missing Decision nodes. The shell insets its own body except where the body already insets itself, which QuestionView does and cannot stop doing from another package.
Parent4470569
11 files changed+348-80
StackedSplit