| name | propose-edit |
| description | Produce a clean output/proposed-questionnaire.json or output/suggestions.json with stable linkIds, exact baseVersion, and the current typed proposal vocabulary. Use whenever you're about to suggest a structural change to the form. |
Propose edit
When to use this
- Anytime you are about to write
output/suggestions.json or
output/proposed-questionnaire.json.
- Anytime your visible reply says changes are ready for review.
- Whenever a small change can be represented as an item-level card.
Light vs heavy
Default to suggestions.json for small changes the clinician should
accept item-by-item.
Use proposed-questionnaire.json only when the form is empty or the
change is too broad for a small set of typed suggestions.
When the form is empty and the user asks to create/build/draft a broad clinical
form, default to a micro starter increment unless the user explicitly asks
for a complete, comprehensive, full, or exhaustive one-shot instrument. A good
micro starter has about 1-3 top-level sections and 6-12 answerable items. Cover
must-not-miss safety triage, one high-yield longitudinal tracking axis, and
visit priorities/next-step steering. Defer additional domains into reply.md
as concrete backlog modules the user can choose to add. If the request includes
research, still write output/research/bundle.json and output/findings.json;
the micro starter does not replace the evidence synthesis artifacts. Keep the
evidence pass proportional to the micro slice: about 3-6 high-quality sources,
then stop once the first-slice safety/tracking/steering jobs are supported.
For an empty current form, the host auto-applies a valid
proposed-questionnaire.json; in reply.md, say the initial micro starter has
been created and is ready to review, then offer concrete backlog modules. Do
not tell the user to click Apply/Replace for this first draft.
Mandatory self-check
Validate the exact JSON artifact before writing the final visible reply:
curl -sS -X POST "$FORMTASTIC_OUTPUT_VALIDATOR_URL?kind=suggestions" \
-H 'content-type: application/json' \
--data-binary @"$FORMTASTIC_RUN_DIR/output/suggestions.json"
curl -sS -X POST "$FORMTASTIC_OUTPUT_VALIDATOR_URL?kind=proposed-questionnaire" \
-H 'content-type: application/json' \
--data-binary @"$FORMTASTIC_RUN_DIR/output/proposed-questionnaire.json"
If the response has "ok": false, fix the JSON before telling the
clinician that cards or replacement changes are ready.
suggestions.json shape
Each entry is exactly:
{
"id": "s-1",
"baseVersion": "<exact snapshot hash from this prompt>",
"narrative": "Add a follow-up question about light sensitivity.",
"proposal": { "kind": "add-item" }
}
proposal.kind must be one of the host vocabulary entries below.
| kind | shape |
|---|
add-item | { "kind":"add-item", "anchor": Anchor, "item": QuestionnaireItem, "reason": string } |
edit-text | `{ "kind":"edit-text", "linkId": string, "field":"text" |
edit-help | { "kind":"edit-help", "linkId": string, "newHelpText": string, "reason": string } |
add-answer-option | { "kind":"add-answer-option", "linkId": string, "option": AnswerOption, "atIndex"?: number, "reason": string } |
remove-answer-option | { "kind":"remove-answer-option", "linkId": string, "option": AnswerOption, "reason": string } |
set-required | { "kind":"set-required", "linkId": string, "required": boolean, "reason": string } |
set-repeats | { "kind":"set-repeats", "linkId": string, "repeats": boolean, "reason": string } |
set-enable-when | `{ "kind":"set-enable-when", "linkId": string, "enableWhen": EnableWhen[] |
move-item | { "kind":"move-item", "linkId": string, "newAnchor": Anchor, "reason": string } |
remove-item | { "kind":"remove-item", "linkId": string, "reason": string } |
add-citation | `{ "kind":"add-citation", "linkId": string, "citation": { "refType":"instrument" |
set-form-meta | `{ "kind":"set-form-meta", "field":"title" |
include-instrument | { "kind":"include-instrument", "anchor": Anchor, "canonicalUrl": string, "reason": string } |
Anchor is exactly one of:
{ "kind": "after", "afterLinkId": "existing-link-id" }
{ "kind": "intoGroup", "intoGroupLinkId": "existing-group-link-id", "atEnd": true }
{ "kind": "atRoot", "position": "start" }
Do not emit intoGroup with atEnd:false; that is invalid. If the
new item should appear near another item, use { "kind":"after", "afterLinkId":"..." }.
proposed-questionnaire.json shape
Write the complete FHIR Questionnaire plus a top-level _baseVersion
sentinel:
{
"resourceType": "Questionnaire",
"_baseVersion": "<exact snapshot hash from this prompt>"
}
The host strips _baseVersion before storing the canonical FHIR
Questionnaire.
BaseVersion
Use the exact snapshot hash embedded in the run packet. Do not invent,
rehash, or read an old run's value. Every suggestion gets the same
baseVersion.
LinkId stability
- Never renumber existing items.
- New items use stable kebab-case linkIds that survive wording changes.
- If you must remove or rename a linkId, say so plainly in the
suggestion narrative and
reason.
Pitfalls
- Forgetting to run the output validator before the visible reply.
- Mentioning a suggestion id in
reply.md that is not present in
suggestions.json.
- Emitting a proposed replacement identical to the current snapshot.
- Using old fields such as
title, why, patch, or
anchorAfterLinkId; those are not part of the current contract.