Spec Studio

Recipe 49 renders a change proposal as the Markdown memo a person reviews

spec:consumers.intent-composition.proposal.memoContract · storyready floor ready

Packs: pack:self-hosting-v1, pack:spec-studio-v1

Design: 5 design entries · no pinned declarations · no decisions

Findings: no errors, no warnings

specs/consumers/intent-composition.proposal.memo.sdp.md

No open questions and no blocking questions; implementation binding present, verifier binding present, and expected-outcome oracle present.

A person reviews a proposed change as text, not as JSON beside the proposal check's rows. The memo is a rendering of the proposal document and never a second source of it: it ends with the document itself, so one paste hands an agent everything the person reviewed. Recipe 49 renders it, and the Studio's composing panel writes the same bytes, so a person, a reviewer and an agent read one text.

Intent
outcome
Render a change proposal as one Markdown memo, the same bytes from the recipe and from the Studio's composing panel, that a person reviews and hands to an agent whole.
Contract
rule.memo line 17 · specs/consumers/intent-composition.proposal.memo.sdp.md:17
Recipe 49 renders a proposal as the Markdown memo a person reviews and hands off, ending with the document itself, and the Studio's composing panel, spec:consumers.spec-studio.intent-panel, writes the same bytes for the same document, so a person, a reviewer and an agent read one text.

spec:consumers.intent-composition.proposal.memo.shared · enabled

0 unkeyed rules.

Verifying examples

Recipe 49 and the composing panel write one memo for one proposal · spec:consumers.intent-composition.proposal.memo.shared · ready floor ready

Executable Spec

Given a change proposal with {changes: 2} changes, one whose exact text holds a run of {ticks: 3} backticks
When recipe 49 renders its memo and the composing panel renders its memo
Then the two memos are byte-identical: {identical: true}
Then the memo ends with the proposal as JSON in a fenced block: {carriesDocument: true}
Then the fence around that exact text is {fence: 4} backticks long

Open example

Example space

Given a change proposal with {changes:number} changes, one whose exact text holds a run of {ticks:number} backticks
When recipe 49 renders its memo and the composing panel renders its memo
Then the two memos are byte-identical: {identical:boolean}
Then the memo ends with the proposal as JSON in a fenced block: {carriesDocument:boolean}
Then the fence around that exact text is {fence:number} backticks long
Design
memoRecipe line 20 · specs/consumers/intent-composition.proposal.memo.sdp.md:20
recipe 49, the proposal memo, takes params.proposal and returns { schemaProblems: [{ path, problem }], memo }: the schema problems recipe 38 reports for the same document and, when there are none, the memo as one string, otherwise memo: null; it reads no graph value, so one document renders one memo in any corpus.
memoHead line 21 · specs/consumers/intent-composition.proposal.memo.sdp.md:21
the memo opens with the line # Change proposal, a blank line, the line Base: followed by the base as a code span, the line Reason: followed by the reason as a code span, and a blank line.

Cited at

  • Test line · test/studio-s5.test.ts:1137 · test:protocol.studio-memo-shared
memoChange line 22 · specs/consumers/intent-composition.proposal.memo.sdp.md:22
each change follows in document order as the line ## Change <n>, counting from 1, and a blank line, then each on its own line: Scope: followed by the scope items as code spans joined by , ; Request: followed by a blank line and the request in a fenced block whose info string is text; when present, Replaces: or Follows: followed by the address as a code span; Relation: followed by the action, the source as a code span, the relation type and the target as a code span, separated by single spaces; and Reason: followed by the change's reason as a code span; then, when the change carries exact text, a blank line and the text in a fenced block with no info string; then a blank line.

Cited at

  • Test line · test/studio-s5.test.ts:1138 · test:protocol.studio-memo-shared
memoDocument line 23 · specs/consumers/intent-composition.proposal.memo.sdp.md:23
the memo ends with the line ## The proposal, a blank line, and the document in a fenced block whose info string is json, written as JSON.stringify writes it with two-space indentation and the keys in the order the document holds them.

Cited at

  • Test line · test/studio-s5.test.ts:1139 · test:protocol.studio-memo-shared
memoMarkup line 24 · specs/consumers/intent-composition.proposal.memo.sdp.md:24
a code span uses a backtick run one longer than the longest run its content holds, padded with a space on each side when the content starts or ends with a backtick; a fence is a backtick run one longer than the longest run its content holds and at least three long; each request and each change's exact text is enclosed in a fence longer than any backtick run it holds, each reason is enclosed in a code span whose backtick run is longer than any run it holds, so no field of the memo can open HTML, add a heading or close its enclosing span or fence; every value is written verbatim; every line ends with a line feed and the memo with one.
Verification

Verifier bindings

  • spec:consumers.intent-composition.proposal.memo.shared · Recipe 49 and the composing panel write one memo for one proposal · declared · example enabled · specs/consumers/intent-composition.proposal.memo.shared.sdp.md

    External run evidence from test/studio-s5.test.ts

    Test anchors: test:protocol.studio-export-contained, test:protocol.studio-intent-handoff, test:protocol.studio-intents-refresh, test:protocol.studio-memo-shared, test:protocol.studio-watch-plain. Specs verified by those bindings: spec:consumers.edit-model, spec:consumers.intent-composition, spec:consumers.intent-composition.proposal.memo, spec:consumers.intent-composition.proposal.memo.shared, spec:consumers.spec-studio.components, spec:consumers.spec-studio.export, spec:consumers.spec-studio.export.self-contained, spec:consumers.spec-studio.intent-panel, spec:consumers.spec-studio.intent-panel.refresh-keeps-intents, spec:consumers.spec-studio.publisher.watch, spec:consumers.spec-studio.publisher.watch.matches-plain-run, spec:consumers.spec-studio.responsive.

    Run 1: external run evidence from vitest 4.1.10

    Build: CI 391 · Branch: cursor/media-plan-and-articles-09b1 · Commit: 076cd4f1f85640d8236e5cca1bffffa68ab79a33 · Start: 2026-10-31T15:32:20.471Z · Stop: 2026-10-31T15:34:02.073Z

    NameSuiteResultDuration
    executes the bound example against a fresh worldRefreshing a tab keeps every gathered intent (spec:consumers.spec-studio.intent-panel.refresh-keeps-intents)passed9.92 ms
    executes the bound example against a fresh worldRecipe 49 and the composing panel write one memo for one proposal (spec:consumers.intent-composition.proposal.memo.shared)passed4.43 ms
    executes the bound example against a fresh worldA Pack's export opens alone and keeps its links inside it (spec:consumers.spec-studio.export.self-contained)passed63.32 ms
    executes the bound example against a fresh worldEach watch cycle writes the page set a plain run writes (spec:consumers.spec-studio.publisher.watch.matches-plain-run)passed124.81 ms
    keeps unsupported intents apart and expands Pack members only against the stamped basenot recordedpassed2.27 ms
    returns the same schema problems as recipe 38 and renders in any corpusnot recordedpassed10.03 ms
    composes locally without changing source or requesting a network servicenot recordedpassed1.54 ms
    keeps the last local intents when storage refuses writesnot recordedpassed0.29 ms
    keeps unsaved local intents when storage remains readable but its quota refuses writesnot recordedpassed0.27 ms
    rewrites SVG and accessibility references without changing subject attributes or authored textnot recordedpassed6.38 ms
    opens disclosures for print and restores exactly their prior statenot recordedpassed1.43 ms
    leaves Mermaid source closed for print unless the reader opened itnot recordedpassed1.06 ms
    stops the actual Studio watch process with exit zero on SIGINTnot recordedpassed491.48 ms
    removes a failed watch publication, keeps watching and recovers on the next carrier editnot recordedpassed33.93 ms
    ships a phone layout and a print stylesheet for the whole canvasnot recordedpassed10.85 ms
    keeps exports graph-only when the browsing pages receive a base and run recordsnot recordedpassed27 ms
    starts no cycle for source or input-file eventsnot recordedpassed30.93 ms
    merges concurrent panels before gathering or discarding and flags rejected storage recordsnot recordedpassed0.6 ms
    refreshes the browser panel on storage and pageshow and removes those listeners on disconnectnot recordedpassed1.47 ms
    prefills compose with the authored entry text including code spans and no rendered annotationsnot recordedpassed15.53 ms
    omits blank exact text and reports whitespace requests in the compose dialognot recordedpassed2.42 ms
    uses the stamp base, labels fields, orders actions and copies and saves the named documentsnot recordedpassed5.09 ms
    copies distinct actions and recorded scopes for both Pack choices without a stampnot recordedpassed2.97 ms
    keeps Pack framing changes apart and gathers scenario editor steps verbatimnot recordedpassed2.66 ms
    matches the literal memo for the shared proposal, including the full relation and documentnot recordedpassed0.93 ms
    keeps the last watch pages when an optional base becomes unreadable, just like a plain runnot recordedpassed986.18 ms
    inlines the selected stylesheet asset in exports and publishes those same style bytesnot recordedpassed25.93 ms
    introduces studio before its watch option and gives recipe 49 a use casenot recordedpassed4.36 ms
    renders edit scenario steps outside inert templates without scriptnot recordedpassed1.08 ms
    renders propose scenario steps outside inert templates without scriptnot recordedpassed0.72 ms
    writes both memo reasons as code spans: "<details>Review the design.</details>", "`Keep` the ``literal`` reason`"not recordedpassed0.7 ms
    writes both memo reasons as code spans: "`Review` the ``design`` reason`", "<details>Keep the change.</details>"not recordedpassed0.43 ms
    fences requests so their Markdown cannot alter the memo: "Fix a typo.\n<!--"not recordedpassed0.89 ms
    fences requests so their Markdown cannot alter the memo: "Use this text.\n```\n## Forged heading\n``````\n<!--hidden-->"not recordedpassed0.7 ms
    contains phone navigation, stamp and wide tables within the viewportnot recordedpassed15.39 ms
    keeps the maturity caption readable and empty cells compact on a phonenot recordedpassed7.6 ms
    aligns maturity cell counts with the empty cell dashesnot recordedpassed4.92 ms
    keeps table headers and one-word cells intact while allowing word-boundary wrappingnot recordedpassed7.32 ms
    keeps natural desktop diagram size and fits only on phonesnot recordedpassed7.69 ms
    hides phone scroll advice and closed source in print while keeping opened source printablenot recordedpassed18.32 ms

Example space

  • changes · number · declared by a change proposal with {changes} changes, one whose exact text holds a run of {ticks} backticks
  • ticks · number · declared by a change proposal with {changes} changes, one whose exact text holds a run of {ticks} backticks

Bound points

Oracle binding: present · oracle:protocol.studio-memo · test/studio-s5.test.ts:262

Coverage

changes: 2 · spec:consumers.intent-composition.proposal.memo.shared · not enumerable

ticks: 3 · spec:consumers.intent-composition.proposal.memo.shared · not enumerable

Unbound

  • changes: None
  • ticks: None
Design view

Requirement drawing

Requirement drawing for spec:consumers.intent-composition.proposal.memo
The diagram as text
  • spec:consumers.intent-composition.proposal.memo: Recipe 49 renders a change proposal as the Markdown memo a person reviews · declared Spec
  • spec:consumers.intent-composition.proposal.memo.shared: Recipe 49 and the composing panel write one memo for one proposal · declared Spec
  • spec:consumers.intent-composition.proposal: A change proposal is addressed, based and checked before it lands · declared Spec
  • impl:protocol.proposal-memo-recipe: realizes the catalog proposal memo through its verbatim body check · anchored code · test/recipes.test.ts:7298
  • impl:protocol.studio-proposal-memo: renders proposal fields verbatim with fences that outgrow their content · anchored code · src/studio-elements/memo.ts:13
  • oracle:protocol.studio-memo: oracle:protocol.studio-memo · anchored oracle binding · test/studio-s5.test.ts:262
  • test:protocol.studio-memo-shared: test:protocol.studio-memo-shared · anchored test binding · binding present · test/studio-s5.test.ts:272
  • spec:consumers.intent-composition.proposal.memo refines spec:consumers.intent-composition.proposal · declared
  • spec:consumers.intent-composition.proposal.memo.shared refines spec:consumers.intent-composition.proposal.memo · declared
  • spec:consumers.intent-composition.proposal.memo.shared verifies spec:consumers.intent-composition.proposal.memo · declared
  • impl:protocol.proposal-memo-recipe satisfies spec:consumers.intent-composition.proposal.memo · anchored
  • impl:protocol.studio-proposal-memo satisfies spec:consumers.intent-composition.proposal.memo · anchored
  • oracle:protocol.studio-memo models spec:consumers.intent-composition.proposal.memo · anchored
  • test:protocol.studio-memo-shared verifies spec:consumers.intent-composition.proposal.memo.shared · anchored
Mermaid source

Copyable source; the Studio draws static SVG.

Preferred syntax: requirementDiagram. Chosen syntax: flowchart TB because models require exact labels unavailable in requirement syntax.

Decisions

No decision record named.

Runtime
  • component:protocol.studio-elements · optional browser behavior and proposal handoff · src/studio-elements/index.ts:13 · layer edge · context protocol

    Uses

    • component:protocol.projections · read-only output, layout and owned publication · src/projections/design-review.ts:29 · layer edge · context protocol
    • component:protocol.reader · the typed graph contract and body evaluator · src/reader/reader.ts:671 · layer application · context protocol
  • impl:protocol.proposal-memo-recipe · realizes the catalog proposal memo through its verbatim body check · test/recipes.test.ts:7298

    Uses

    None.

  • impl:protocol.studio-proposal-memo · renders proposal fields verbatim with fences that outgrow their content · src/studio-elements/memo.ts:13

    Component: component:protocol.studio-elements · optional browser behavior and proposal handoff · src/studio-elements/index.ts:13 · layer edge · context protocol

    Uses

    None.

Runtime observation: not tracked.

Evidence

Runtime observation: not tracked.

Build attestations: not tracked.

Deployments: not tracked.

Bills of materials: not tracked.

Impact
Relations of spec:consumers.intent-composition.proposal.memo
The diagram as text
  • spec:consumers.intent-composition.proposal: A change proposal is addressed, based and checked before it lands
  • spec:consumers.intent-composition.proposal.memo: Recipe 49 renders a change proposal as the Markdown memo a person reviews
  • spec:consumers.intent-composition.proposal.memo.shared: Recipe 49 and the composing panel write one memo for one proposal
  • spec:consumers.roadmap.memo: A roadmap renders as the forward section of a pull request description
  • spec:consumers.spec-studio.intent-panel: A composing panel on every page gathers scoped intent for an agent
  • spec:protocol.roadmap-replaces-plans: The Protocol reads its next work from its roadmap and keeps its delivery record in git and its pull requests
  • spec:consumers.intent-composition.proposal.memo refines spec:consumers.intent-composition.proposal · declared
  • spec:consumers.roadmap.memo dependsOn spec:consumers.intent-composition.proposal.memo · declared — the memo writes its code spans by the proposal memo's markup rules
  • spec:consumers.spec-studio.intent-panel dependsOn spec:consumers.intent-composition.proposal.memo · declared — the panel writes the memo recipe 49 renders, byte for byte
  • spec:protocol.roadmap-replaces-plans dependsOn spec:consumers.intent-composition.proposal.memo · declared — the pull request carries a review's proposal as its memo
  • spec:consumers.intent-composition.proposal.memo.shared refines spec:consumers.intent-composition.proposal.memo · declared
  • spec:consumers.intent-composition.proposal.memo.shared verifies spec:consumers.intent-composition.proposal.memo · declared
Mermaid source

Copyable source; the Studio draws static SVG.

Preferred syntax: flowchart. Chosen syntax: labelled flowchart, preserving exact relations, claims and folds.

Rests on

Rested on by

Distance 1

Distance 2

Distance 3

Distance 4

Distance 5

Distance 6

Relations

Relation and directionOther endClaimReasonExercised keys
refines · outgoingA change proposal is addressed, based and checked before it lands
spec:consumers.intent-composition.proposal · resolves
declaredNoneNone
dependsOn · incomingA roadmap renders as the forward section of a pull request description
spec:consumers.roadmap.memo · resolves
declaredthe memo writes its code spans by the proposal memo's markup rulesNone
dependsOn · incomingA composing panel on every page gathers scoped intent for an agent
spec:consumers.spec-studio.intent-panel · resolves
declaredthe panel writes the memo recipe 49 renders, byte for byteNone
dependsOn · incomingThe Protocol reads its next work from its roadmap and keeps its delivery record in git and its pull requests
spec:protocol.roadmap-replaces-plans · resolves
declaredthe pull request carries a review's proposal as its memoNone
refines · incomingRecipe 49 and the composing panel write one memo for one proposal
spec:consumers.intent-composition.proposal.memo.shared · resolves
declaredNoneNone
verifies · incomingRecipe 49 and the composing panel write one memo for one proposal
spec:consumers.intent-composition.proposal.memo.shared · resolves
declaredNonememo

Bindings

Implementation binding: present

  • impl:protocol.proposal-memo-recipe · realizes the catalog proposal memo through its verbatim body check · test/recipes.test.ts:7298
  • impl:protocol.studio-proposal-memo · renders proposal fields verbatim with fences that outgrow their content · src/studio-elements/memo.ts:13 · role projection · component component:protocol.studio-elements · layer edge · context protocol

Design reference: none

Verifier binding: present

Expected-outcome oracle: present

  • oracle:protocol.studio-memo · test/studio-s5.test.ts:262

Runtime observation: not tracked.

Run results: not recorded in the graph.

Findings

None.

Composing (0)

Composing needs the script.