konpeki 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/AGENTS.md +21 -28
  2. package/AUTHORING.md +68 -229
  3. package/CONTRIBUTING.md +10 -23
  4. package/README.md +98 -106
  5. package/SETUP.md +49 -129
  6. package/docs/development.md +43 -256
  7. package/docs/workflow.md +6 -108
  8. package/html/README.md +140 -0
  9. package/html/browser.ts +103 -0
  10. package/html/document.ts +38 -0
  11. package/html/floor.ts +34 -0
  12. package/html/index.html +5 -0
  13. package/html/inspect.ts +313 -0
  14. package/html/preview.css +62 -0
  15. package/html/preview.tsx +463 -0
  16. package/html/review-hints.ts +63 -0
  17. package/html/server.ts +99 -0
  18. package/html/source.ts +104 -0
  19. package/html/starter.ts +6 -0
  20. package/html/theme-authoring.md +176 -0
  21. package/html/theme.md +61 -0
  22. package/index.html +9 -9
  23. package/package.json +21 -37
  24. package/plugin.json +1 -1
  25. package/public/og.png +0 -0
  26. package/runtime/browser-B-29TH1a.mjs +595 -0
  27. package/runtime/floor-Cmk7G3pU.mjs +41 -0
  28. package/runtime/konpeki.mjs +90 -1410
  29. package/runtime/server-BAqC_5WD.mjs +2 -0
  30. package/runtime/server-DfRpfcY9.mjs +205 -0
  31. package/runtime/source-B_Ui9tMp.mjs +141 -0
  32. package/runtime/source-CZQq9GUO.mjs +2 -0
  33. package/skills/konpeki/SKILL.md +88 -172
  34. package/skills/konpeki/assets/blank.html +17 -0
  35. package/skills/konpeki/floor.md +76 -0
  36. package/skills/konpeki/references/cover.md +27 -0
  37. package/skills/konpeki/references/long-document.md +40 -0
  38. package/skills/konpeki/references/one-pager.md +27 -0
  39. package/skills/konpeki/references/patterns.md +118 -0
  40. package/skills/konpeki/references/resume.md +28 -0
  41. package/skills/konpeki/references/slides.md +28 -0
  42. package/skills/konpeki/scripts/ensure-runtime.mjs +10 -31
  43. package/skills/konpeki/scripts/prepare-document.mjs +25 -14
  44. package/src/components/PageBoard.tsx +156 -0
  45. package/src/lib/alignment.ts +21 -0
  46. package/src/lib/page-board.ts +25 -0
  47. package/src/lib/review-position.ts +19 -0
  48. package/src/styles/base.css +1 -10
  49. package/src/styles/feedback.css +2 -1
  50. package/src/styles/shell.css +94 -354
  51. package/theme-base.css +90 -0
  52. package/theme.css +56 -0
  53. package/vite.config.ts +2 -5
  54. package/composition/README.md +0 -156
  55. package/composition/compile.ts +0 -227
  56. package/composition/document.ts +0 -600
  57. package/composition/schema.json +0 -3001
  58. package/composition/schema.ts +0 -437
  59. package/composition/theme-tokens.ts +0 -16
  60. package/composition/types.ts +0 -269
  61. package/composition/validate.ts +0 -226
  62. package/composition/vector.ts +0 -143
  63. package/composition/visualizations.ts +0 -319
  64. package/design/README.md +0 -17
  65. package/design/palettes/README.md +0 -14
  66. package/design/palettes/base.ts +0 -14
  67. package/design/palettes/candidates.ts +0 -19
  68. package/design/palettes/index.ts +0 -78
  69. package/design/review/color-theme.md +0 -44
  70. package/design/review/layout.md +0 -16
  71. package/design/review/text.md +0 -18
  72. package/design/review/typography.md +0 -15
  73. package/design/review/visuals.md +0 -31
  74. package/design/semantic-patterns.md +0 -43
  75. package/design/themes/README.md +0 -40
  76. package/design/themes/index.ts +0 -24
  77. package/design/visual-languages/technical-product.md +0 -17
  78. package/design/visual-review.md +0 -88
  79. package/lib/assets.d.ts +0 -8
  80. package/lib/charts.ts +0 -18
  81. package/lib/contrast.ts +0 -16
  82. package/lib/layouts.ts +0 -50
  83. package/lib/slide.tsx +0 -42
  84. package/lib/taste.ts +0 -17
  85. package/lib/text.tsx +0 -89
  86. package/lib/typeface.ts +0 -44
  87. package/scripts/migrate-react-page.ts +0 -120
  88. package/skills/konpeki/assets/blank.json +0 -23
  89. package/slides/README.md +0 -56
  90. package/slides/architecture/PROMPT.md +0 -31
  91. package/slides/architecture/index.tsx +0 -102
  92. package/slides/article-brief/PROMPT.md +0 -35
  93. package/slides/article-brief/index.tsx +0 -71
  94. package/slides/bar-chart/PROMPT.md +0 -39
  95. package/slides/bar-chart/index.tsx +0 -97
  96. package/slides/comparison/PROMPT.md +0 -29
  97. package/slides/comparison/index.tsx +0 -95
  98. package/slides/decision-memo/PROMPT.md +0 -34
  99. package/slides/decision-memo/index.tsx +0 -85
  100. package/slides/delivery-plan/PROMPT.md +0 -45
  101. package/slides/delivery-plan/index.tsx +0 -105
  102. package/slides/drawing-references.md +0 -32
  103. package/slides/experiment/PROMPT.md +0 -44
  104. package/slides/experiment/index.tsx +0 -127
  105. package/slides/github-cover/PROMPT.md +0 -21
  106. package/slides/github-cover/README.md +0 -21
  107. package/slides/github-cover/author.ts +0 -67
  108. package/slides/github-cover/composition.json +0 -595
  109. package/slides/incident-workflow/PROMPT.md +0 -57
  110. package/slides/incident-workflow/index.tsx +0 -78
  111. package/slides/introducing-konpeki/PROMPT.md +0 -30
  112. package/slides/introducing-konpeki/README.md +0 -44
  113. package/slides/introducing-konpeki/SOURCE.md +0 -19
  114. package/slides/introducing-konpeki/author.ts +0 -165
  115. package/slides/introducing-konpeki/composition.json +0 -3270
  116. package/slides/line-chart/PROMPT.md +0 -40
  117. package/slides/line-chart/index.tsx +0 -72
  118. package/slides/migration/PROMPT.md +0 -38
  119. package/slides/migration/index.tsx +0 -89
  120. package/slides/og-images/PROMPT.md +0 -21
  121. package/slides/og-images/index.tsx +0 -76
  122. package/slides/product-introduction/PROMPT.md +0 -24
  123. package/slides/product-introduction/index.tsx +0 -105
  124. package/slides/research-brief/PROMPT.md +0 -40
  125. package/slides/research-brief/index.tsx +0 -104
  126. package/slides/results-explanation/PROMPT.md +0 -32
  127. package/slides/results-explanation/index.tsx +0 -96
  128. package/slides/retrospective/PROMPT.md +0 -43
  129. package/slides/retrospective/index.tsx +0 -105
  130. package/slides/sankey/PROMPT.md +0 -11
  131. package/slides/sankey/index.tsx +0 -93
  132. package/slides/teaching/PROMPT.md +0 -45
  133. package/slides/teaching/index.tsx +0 -124
  134. package/slides/vertical-bar-charts/PROMPT.md +0 -13
  135. package/slides/vertical-bar-charts/index.tsx +0 -97
  136. package/src/app/App.tsx +0 -845
  137. package/src/components/BuildOrb.tsx +0 -40
  138. package/src/components/Canvas.tsx +0 -1191
  139. package/src/components/DiagramTypeIcon.tsx +0 -78
  140. package/src/components/InspectorPanel.tsx +0 -757
  141. package/src/components/LeftPanel.tsx +0 -120
  142. package/src/components/PageSizePicker.tsx +0 -30
  143. package/src/components/Presentation.tsx +0 -105
  144. package/src/components/RevisionNotes.tsx +0 -55
  145. package/src/components/RightPanel.tsx +0 -233
  146. package/src/components/VectorOverflowWarning.tsx +0 -73
  147. package/src/components/WorkspaceChrome.tsx +0 -316
  148. package/src/components/ui.tsx +0 -147
  149. package/src/lib/examples/react-page-migration.json +0 -1295
  150. package/src/lib/examples.ts +0 -42
  151. package/src/lib/export-png.ts +0 -104
  152. package/src/lib/file-session.ts +0 -87
  153. package/src/lib/history.ts +0 -53
  154. package/src/lib/model.ts +0 -188
  155. package/src/lib/page-size.ts +0 -24
  156. package/src/lib/presentation.ts +0 -17
  157. package/src/lib/review.ts +0 -26
  158. package/src/lib/storage.ts +0 -71
  159. package/src/lib/theme.ts +0 -25
  160. package/src/lib/use-file-session.ts +0 -249
  161. package/src/main.tsx +0 -29
  162. package/src/styles/canvas.css +0 -299
  163. package/src/styles/chrome.css +0 -475
  164. package/src/styles/component-previews.css +0 -386
  165. package/src/styles/left-panel.css +0 -187
  166. package/src/styles/presentation.css +0 -72
  167. package/src/styles/right-panel.css +0 -1298
package/slides/README.md DELETED
@@ -1,56 +0,0 @@
1
- # What can I make with Konpeki?
2
-
3
- Reviewed examples with editable text and vector artwork. Scenarios and data
4
- are illustrative; these are finished documents, not one-click templates.
5
-
6
- Download an example's JSON and choose **Demo Mode → Import** in the
7
- [playground](https://vcfgdev.github.io/konpeki/). For revision notes and agent
8
- handoff, open it in a [file-backed preview](../docs/workflow.md#file-backed-editing-with-an-agent).
9
- Playground edits stay in your browser.
10
-
11
- ## Explain a system
12
-
13
- An order platform's request handling, data, events and fulfillment.
14
-
15
- [Editable JSON](gallery/architecture.json) ·
16
- [Brief](gallery/PROMPT.md#architecture) · [Source](gallery/SOURCE.md#architecture)
17
-
18
- ![Editable order-platform architecture](gallery/architecture.png)
19
-
20
- ## Communicate data
21
-
22
- A proportional Sankey follows 1,000 trial users through activation and outcomes.
23
-
24
- [Editable JSON](gallery/sankey.json) ·
25
- [Brief](gallery/PROMPT.md#sankey) · [Source](gallery/SOURCE.md#sankey)
26
-
27
- ![Editable trial-user flow with proportional ribbons](gallery/sankey.png)
28
-
29
- ## Announce a release
30
-
31
- A 1080×1350 Clearpath release announcement: preview, review and export Markdown.
32
-
33
- [Editable JSON](gallery/release.json) ·
34
- [Brief](gallery/PROMPT.md#release) · [Source](gallery/SOURCE.md#release)
35
-
36
- ![Clearpath portrait announcement](gallery/release.png)
37
-
38
- ## Teach a concept
39
-
40
- A 1200×1600 Folio explainer shows a stale save, its rejection and recovery choices.
41
-
42
- [Editable JSON](gallery/explainer.json) ·
43
- [Brief](gallery/PROMPT.md#explainer) · [Source](gallery/SOURCE.md#explainer)
44
-
45
- ![Folio optimistic-concurrency explainer](gallery/explainer.png)
46
-
47
- ## More examples
48
-
49
- - [Introducing Konpeki](introducing-konpeki/README.md): six-page product overview.
50
- - [Repository cover](github-cover/README.md): 1280×640 social preview.
51
- - [React/SVG drawing references](drawing-references.md): 18 older examples, not editor-importable documents.
52
-
53
- These four gallery exports are repository-only; their authoring projects are
54
- maintained separately. They are not bundled in npm or the hosted playground.
55
- The introduction and cover JSONs are included in npm; the playground bundles
56
- the introduction. View this gallery in the repository for its screenshots.
@@ -1,31 +0,0 @@
1
- Make a three-page presentation explaining Parcel Relay to engineers joining its
2
- team. Help them follow an event from acceptance to delivery and understand why
3
- a timeout can lead to a duplicate request.
4
-
5
- ---
6
-
7
- Parcel Relay is a fictional webhook delivery service. A producer submits an
8
- event with an event ID. The API saves the event and its delivery job in one
9
- database transaction and returns Accepted after the transaction commits. If
10
- the transaction cannot commit, the API returns an error and the event has not
11
- been accepted.
12
-
13
- Workers claim jobs from that database using time-limited leases, then POST the
14
- events to customer endpoints. Each request includes the event ID. The database
15
- holds the job queue; there is no separate message broker.
16
-
17
- A 2xx response marks the job delivered. A timeout or 5xx schedules another
18
- attempt, up to three attempts in total. A third unsuccessful attempt marks the
19
- job failed for human investigation. A 4xx is terminal in this example. If a
20
- worker crashes, another worker can claim its unfinished job after the lease
21
- expires, even if the customer already received the earlier request.
22
-
23
- Customers must handle repeated event IDs. Relay cannot make their side effects
24
- atomic or guarantee exactly-once delivery.
25
-
26
- ---
27
-
28
- Walk through this failure: evt-204 reaches the customer, which applies its
29
- update, but the response is lost. Relay times out and retries evt-204. The
30
- customer recognizes the event ID and skips the repeated update. That final
31
- step depends on the customer's implementation; Relay does not enforce it.
@@ -1,102 +0,0 @@
1
- import type { ReactNode } from 'react';
2
- import '../../lib/typeface.ts';
3
-
4
- const ink = '#172633', muted = '#4D5D6B', accent = '#006EAC', line = '#A7B2BC';
5
- function Text({ x, y, children, size = 34, weight = 400, color = ink }: { x: number; y: number; children: ReactNode; size?: number; weight?: number; color?: string }) {
6
- return <text x={x} y={y} fontSize={size} fontWeight={weight} fill={color}>{children}</text>;
7
- }
8
- function Arrow({ x1, x2, y, dashed = false }: { x1: number; x2: number; y: number; dashed?: boolean }) {
9
- const d = x2 > x1 ? -16 : 16;
10
- return <g fill="none" stroke={accent} strokeWidth={3}><path d={`M${x1} ${y} H${x2}`} strokeDasharray={dashed ? '10 8' : undefined}/><path d={`M${x2 + d} ${y - 10} L${x2} ${y} L${x2 + d} ${y + 10}`}/></g>;
11
- }
12
- function Frame({ title, description, page, children }: { title: string; description: string; page: number; children: ReactNode }) {
13
- return <svg xmlns="http://www.w3.org/2000/svg" width="1920" height="1080" viewBox="0 0 1920 1080" fontFamily="IBM Plex Sans, sans-serif" role="img" aria-label={`${title}. ${description}`}>
14
- <rect width={1920} height={1080} fill="#FFFFFF"/>
15
- <Text x={112} y={150} size={64} weight={600}>{title}</Text>
16
- {children}
17
- <Text x={1760} y={1018} size={26} color={muted}>{page} / 3</Text>
18
- </svg>;
19
- }
20
- function Acceptance() {
21
- return <Frame page={1} title="Parcel Relay accepts an event after commit" description="Fictional service. Producer submits an event ID to the API. The API saves event and job in one database transaction. Accepted follows commit; commit failure returns an error, so the event was not accepted. Workers claim leased jobs from the database and POST to customer endpoints with the event ID. No separate broker.">
22
- <Text x={112} y={224} color={muted}>A fictional webhook service • the database holds both events and the job queue</Text>
23
- <Text x={160} y={365} size={40} weight={600}>Producer</Text>
24
- <Text x={548} y={365} size={40} weight={600}>API</Text>
25
- <path d="M250 390 V635 M580 390 V635" fill="none" stroke={line} strokeWidth={2}/>
26
- <rect x={965} y={294} width={835} height={280} rx={8} fill="#FFFFFF" stroke={line} strokeWidth={2}/>
27
- <Text x={1005} y={355} size={40} weight={600}>Database</Text>
28
- <Text x={1005} y={423}>Event + delivery job</Text>
29
- <Text x={1005} y={479} color={accent} weight={500}>Saved in one transaction</Text>
30
- <Text x={1005} y={531} size={30} color={muted}>Commit is the acceptance boundary.</Text>
31
- <Arrow x1={250} x2={580} y={415}/>
32
- <Text x={280} y={397} size={30}>Submit event ID</Text>
33
- <Arrow x1={580} x2={965} y={415}/>
34
- <Text x={690} y={391} size={30}>Save both</Text>
35
- <Arrow x1={965} x2={580} y={515}/>
36
- <Text x={680} y={563} size={30}>Commit succeeds</Text>
37
- <Arrow x1={580} x2={250} y={610}/>
38
- <Text x={236} y={660} color={accent} weight={500}>Return Accepted</Text>
39
- <path d="M1120 704 V574 M1110 590 L1120 574 L1130 590" fill="none" stroke={accent} strokeWidth={3}/>
40
- <Text x={1160} y={644} size={30}>Claim leased job</Text>
41
- <Text x={112} y={797} size={40} weight={600}>If commit fails</Text>
42
- <Text x={112} y={855}>API returns an error.</Text>
43
- <Text x={112} y={907}>The event has not been accepted.</Text>
44
- <Text x={1020} y={738} size={40} weight={600}>Worker</Text>
45
- <path d="M1120 756 V844" fill="none" stroke={accent} strokeWidth={3}/>
46
- <Arrow x1={1120} x2={1550} y={844}/>
47
- <Text x={1160} y={891} size={30}>POST + event ID</Text>
48
- <Text x={1555} y={817} size={38} weight={600}>Customer</Text>
49
- <Text x={1555} y={869} size={30}>endpoint</Text>
50
- </Frame>;
51
- }
52
- function Outcomes() {
53
- return <Frame page={2} title="The response decides the job’s next state" description="2xx marks delivered. Timeout or 5xx schedules another attempt, up to three attempts total. The third unsuccessful attempt marks failed for human investigation. 4xx is terminal. If a worker crashes, another may claim the unfinished job after lease expiry even if the customer already received it.">
54
- <Text x={112} y={228} color={muted}>After each POST, the worker records the outcome in the database.</Text>
55
- <Text x={112} y={346} size={30} color={muted}>OBSERVED RESULT</Text>
56
- <Text x={660} y={346} size={30} color={muted}>WHAT RELAY DOES</Text>
57
- {[380, 490, 660, 780].map(y => <line key={y} x1={112} x2={1808} y1={y} y2={y} stroke={line} strokeWidth={2}/>)}
58
- <Text x={112} y={447} size={40} weight={600}>2xx</Text>
59
- <Text x={660} y={447} size={38}>Marks the job delivered.</Text>
60
- <Text x={112} y={555} size={40} weight={600}>Timeout or 5xx</Text>
61
- <Text x={660} y={552} size={38}>Schedules another attempt; three attempts total.</Text>
62
- <Text x={660} y={609} size={32} color={muted}>Third unsuccessful attempt: failed, for human investigation.</Text>
63
- <Text x={112} y={731} size={40} weight={600}>4xx</Text>
64
- <Text x={660} y={731} size={38}>Terminal in this example.</Text>
65
- <Text x={112} y={865} size={38} weight={600}>A worker crash can also repeat a request</Text>
66
- <Text x={112} y={925} size={34}>After lease expiry, another worker can claim the unfinished job,</Text>
67
- <Text x={112} y={975} size={34}>even if the customer already received the earlier request.</Text>
68
- </Frame>;
69
- }
70
- function Duplicate() {
71
- return <Frame page={3} title="A timeout can hide a completed update" description="evt-204 reaches the customer and applies its update, but the response is lost. Relay times out and retries the same event ID. The customer recognizes evt-204 and skips the repeated update. This deduplication depends on the customer implementation. Relay cannot enforce it, make customer side effects atomic, or guarantee exactly-once delivery.">
72
- <Text x={112} y={224} color={muted}>The same event ID connects both requests: evt-204.</Text>
73
- <Text x={260} y={334} size={40} weight={600}>Relay worker</Text>
74
- <Text x={1130} y={334} size={40} weight={600}>Customer endpoint</Text>
75
- <line x1={380} x2={380} y1={367} y2={785} stroke={line} strokeWidth={2}/>
76
- <line x1={1260} x2={1260} y1={367} y2={785} stroke={line} strokeWidth={2}/>
77
- <Arrow x1={380} x2={1260} y={432}/>
78
- <Text x={610} y={406} size={32}>POST evt-204</Text>
79
- <Text x={1310} y={445} size={34} weight={500}>Applies update</Text>
80
- <path d="M1260 525 H760" fill="none" stroke={accent} strokeWidth={3} strokeDasharray="10 8"/>
81
- <path d="M746 511 L774 539 M774 511 L746 539" stroke={accent} strokeWidth={3}/>
82
- <Text x={835} y={504} size={32}>Response lost</Text>
83
- <Text x={112} y={561} size={32}>Times out</Text>
84
- <Text x={112} y={603} size={30} color={muted}>Outcome unknown</Text>
85
- <Arrow x1={380} x2={1260} y={663}/>
86
- <Text x={610} y={637} size={32}>Retry POST evt-204</Text>
87
- <Text x={1310} y={672} size={34} weight={500}>Recognizes evt-204</Text>
88
- <Text x={1310} y={720} size={34} color={accent} weight={500}>Skips repeated update</Text>
89
- <Text x={112} y={861} size={40} weight={600}>Customers must handle repeated event IDs.</Text>
90
- <Text x={112} y={924} size={34}>The skip above depends on customer code; Relay does not enforce it.</Text>
91
- <Text x={112} y={974} size={34}>Relay cannot make customer side effects atomic or guarantee exactly-once delivery.</Text>
92
- </Frame>;
93
- }
94
-
95
- export const meta = { title: 'Parcel Relay', createdAt: '2026-09-12T14:14:00Z' };
96
- export const notes = [
97
- 'Audience question: When is an event accepted, and where does the job live? The connector from the database to the worker denotes job ownership, not a separate message broker.',
98
- 'Audience question: What happens after a delivery attempt, or a worker crash? No backoff duration or lease duration is specified by the fictional brief.',
99
- 'Audience question: Why did evt-204 repeat, and who prevents duplicate side effects? The customer deduplication outcome is an example, not a guarantee supplied by Relay.',
100
- ];
101
- const pages = [Acceptance, Outcomes, Duplicate];
102
- export default pages;
@@ -1,35 +0,0 @@
1
- Turn the article below into a two-page briefing for engineering managers.
2
- Explain its main argument and a practical way to apply it without turning
3
- the author's experience into a universal rule.
4
-
5
- ---
6
-
7
- This is the complete fictional article, written for this example.
8
-
9
- “The decision record that survived the meeting”
10
- By Mira Sol, an engineer at the fictional company Alder
11
-
12
- Our meeting notes were detailed, but a month later we could not explain why
13
- we had chosen a daily data export over a live integration. The notes recorded
14
- who spoke and which tasks followed. They did not record the constraint that
15
- made the decision sensible: the receiving system accepted only one upload
16
- per day.
17
-
18
- We started keeping a short decision record alongside the work. It contains
19
- the question, the constraints known at the time, the alternatives considered,
20
- the choice and the condition that would make us revisit it. For the export,
21
- that condition was the receiving system adding a supported live API.
22
-
23
- This is not an attempt to predict every future requirement. It gives the next
24
- engineer enough context to distinguish a deliberate trade-off from an accident.
25
- When circumstances change, we append a new decision and link the old one
26
- rather than silently rewriting its rationale.
27
-
28
- Not every implementation detail deserves a record. We use one when a choice
29
- crosses team boundaries, is costly to reverse or depends on a constraint likely
30
- to change. Routine local choices can stay in code review. We still need task
31
- lists and meeting notes; they answer different questions.
32
-
33
- We have not measured whether this practice makes delivery faster. Our claim
34
- is narrower: recording the reason and revisit condition makes our decisions
35
- easier to explain later.
@@ -1,71 +0,0 @@
1
- import type { ReactNode } from 'react';
2
- import { Text } from '../../lib/text.tsx';
3
- import { fontsReady } from '../../lib/typeface.ts';
4
-
5
- await fontsReady;
6
-
7
- const ink = '#182B35';
8
- const muted = '#4C606B';
9
- const accent = '#006D77';
10
-
11
- function Copy({ x = 112, y, width = 1696, size = 38, weight = 400, color = ink, children }: {
12
- x?: number; y: number; width?: number; size?: number; weight?: number; color?: string; children: string;
13
- }) {
14
- return <Text x={x} y={y} width={width} size={size} weight={weight} color={color} maxLines={8} leading={1.22}>{children}</Text>;
15
- }
16
-
17
- function Canvas({ page, title, description, children }: { page: number; title: string; description: string; children: ReactNode }) {
18
- return <svg xmlns="http://www.w3.org/2000/svg" width="1920" height="1080" viewBox="0 0 1920 1080" role="img"
19
- aria-labelledby={`title-${page} description-${page}`} data-page={page} fontFamily="IBM Plex Sans">
20
- <title id={`title-${page}`}>{title}</title>
21
- <desc id={`description-${page}`}>{description}</desc>
22
- <rect width="1920" height="1080" fill="#FFFFFF" />
23
- <Copy y={146} size={72} weight={600}>{title}</Copy>
24
- {children}
25
- <text x="1808" y="1020" textAnchor="end" fill={muted} fontSize="28">{page} / 2</text>
26
- </svg>;
27
- }
28
-
29
- const Argument = () => <Canvas page={1} title="Keep the reason with the decision"
30
- description="In Mira Sol’s fictional Alder account, meeting notes preserved speakers and tasks but lost why a daily export was chosen. The receiving system allowed only one upload per day. Alder’s decision record preserved that constraint and a revisit trigger: a supported live API. Sol claims decisions became easier to explain, not measured faster delivery.">
31
- <Copy y={224} size={32} color={muted}>Mira Sol’s “The decision record that survived the meeting” · A fictional Alder account</Copy>
32
- <Copy y={354} width={560} size={48} weight={600}>A month later, the “why” was missing.</Copy>
33
- <Copy y={508} width={550} color={muted}>Meeting notes captured who spoke and what to do next. They lost the constraint behind the export choice.</Copy>
34
- <Copy x={800} y={350} width={1008} size={30} weight={600} color={accent}>ALDER’S EXPORT DECISION</Copy>
35
- <line x1="800" x2="1808" y1="388" y2="388" stroke="#A5B4BC" strokeWidth="2" />
36
- <Copy x={800} y={450} width={260} size={34} weight={600}>Choice</Copy>
37
- <Copy x={1100} y={450} width={708} size={38}>Daily data export over a live integration</Copy>
38
- <line x1="800" x2="1808" y1="532" y2="532" stroke="#A5B4BC" strokeWidth="2" />
39
- <Copy x={800} y={594} width={260} size={34} weight={600}>Reason</Copy>
40
- <Copy x={1100} y={594} width={708} size={38}>Receiving system accepted only one upload per day</Copy>
41
- <line x1="800" x2="1808" y1="676" y2="676" stroke="#A5B4BC" strokeWidth="2" />
42
- <Copy x={800} y={738} width={260} size={34} weight={600}>Revisit when</Copy>
43
- <Copy x={1100} y={738} width={708} size={38}>Receiving system adds a supported live API</Copy>
44
- <line x1="800" x2="1808" y1="820" y2="820" stroke="#A5B4BC" strokeWidth="2" />
45
- <Copy y={922} size={40} weight={500} color={accent}>The claim: decisions became easier to explain later.</Copy>
46
- <Copy y={975} size={32} color={muted}>Sol reports no measurement of faster delivery; this is one team’s experience.</Copy>
47
- </Canvas>;
48
-
49
- const Application = () => <Canvas page={2} title="Try a record on one consequential choice"
50
- description="Suggested application for engineering managers, adapted from Sol’s fictional account: choose a decision that crosses teams, is costly to reverse, or rests on a changing constraint. Keep a short record beside the work with question, constraints, alternatives, choice, and revisit condition. If Alder gains a supported live API, reassess the export; append and link a new decision rather than overwrite the old rationale. Routine local choices can stay in code review. Keep task lists and meeting notes for their separate purposes.">
51
- <Copy y={224} size={32} color={muted}>A suggested first trial, adapted from Sol’s practice—not a requirement for every team.</Copy>
52
- <Copy y={350} width={620} size={44} weight={600}>Choose selectively</Copy>
53
- <Copy y={420} width={620} size={36}>Use a record when a choice:</Copy>
54
- <Copy y={490} width={620} size={38}>• Crosses team boundaries</Copy>
55
- <Copy y={552} width={620} size={38}>• Is costly to reverse</Copy>
56
- <Copy y={614} width={620} size={38}>• Relies on a constraint likely to change</Copy>
57
- <Copy y={780} width={610} size={34} color={muted}>Routine local choices can stay in code review. Keep task lists and meeting notes; they answer different questions.</Copy>
58
- <Copy x={860} y={350} width={948} size={44} weight={600}>Keep a short record beside the work</Copy>
59
- <Copy x={860} y={423} width={948} size={36}>Question · Known constraints · Alternatives</Copy>
60
- <Copy x={860} y={477} width={948} size={36}>Choice · Condition for revisiting</Copy>
61
- <Copy x={860} y={600} width={948} size={44} weight={600} color={accent}>When Alder gains a supported live API…</Copy>
62
- <Copy x={860} y={723} width={948} size={38}>Reassess whether the daily export still fits. Append a new decision and link the old one; preserve the original rationale.</Copy>
63
- <Copy x={860} y={911} width={948} size={34} color={muted}>A manager’s review question: can the next engineer explain the trade-off and when to reconsider it?</Copy>
64
- </Canvas>;
65
-
66
- export const meta = { title: 'Alder — The reason behind the decision' };
67
- export const notes = [
68
- 'Source: the complete fictional article in PROMPT.md by Mira Sol at Alder. This page summarizes the stated experience and preserves its explicit evidence limit.',
69
- 'The single-choice trial and manager’s review question are editorial applications, not quotations or measured outcomes. All five record fields and selective-use criteria come from the supplied article.',
70
- ];
71
- export default [Argument, Application];
@@ -1,39 +0,0 @@
1
- Make a two-page briefing for the operations lead at Birch about processing time
2
- across five workflows. Use grouped horizontal bars to compare before and after,
3
- then explain the decision the evidence supports and what remains unknown.
4
-
5
- Use one common zero-based minute axis, directly label every bar and keep the
6
- before/after series order consistent. Make the workflow that became slower as
7
- easy to notice as the improvements.
8
-
9
- ---
10
-
11
- Birch is a fictional internal operations team. These are synthetic, hand-authored
12
- median active processing times per completed case. Waiting time is excluded.
13
- Each workflow has 80 completed cases in the before period and 80 different
14
- completed cases in the after period. Lower is better.
15
-
16
- Workflow | Before median (minutes) | After median (minutes)
17
- Account setup | 18 | 12
18
- Address correction | 11 | 10
19
- Refund review | 25 | 19
20
- Access removal | 7 | 8
21
- Supplier onboarding | 32 | 24
22
-
23
- The before and after periods each lasted two weeks. A revised work queue was
24
- introduced between them. Cases were not randomized or matched, and case
25
- complexity and staffing could differ. These are independent groups, not paired
26
- measurements of the same cases. No raw times, variability estimates or quality
27
- measurements are supplied.
28
-
29
- ---
30
-
31
- Four workflows have lower observed medians; access removal rises from 7 to 8
32
- minutes. Supplier onboarding has the largest absolute median reduction, eight
33
- minutes, but still has the highest after-period median at 24 minutes.
34
-
35
- Recommend investigating the access-removal increase and checking case mix and
36
- quality before extending the revised queue. The data do not establish that the
37
- queue caused any change. Do not multiply median differences by case counts to
38
- claim total time or money saved, or imply that a lower median means every case
39
- became faster.
@@ -1,97 +0,0 @@
1
- import type { ReactNode } from 'react';
2
- import { Bar } from '@nivo/bar';
3
- import '../../lib/typeface.ts';
4
- import { chartDefaults } from '../../lib/charts.ts';
5
- import { palettes } from '../../lib/taste.ts';
6
-
7
- const ink = '#182B36';
8
- const muted = '#445663';
9
- const before = '#536879';
10
- const after = '#146B60';
11
- export const workflows = [
12
- { workflow: 'Account setup', Before: 18, After: 12 },
13
- { workflow: 'Address correction', Before: 11, After: 10 },
14
- { workflow: 'Refund review', Before: 25, After: 19 },
15
- { workflow: 'Access removal', Before: 7, After: 8 },
16
- { workflow: 'Supplier onboarding', Before: 32, After: 24 },
17
- ];
18
-
19
- function Copy({ x = 112, y, size = 32, weight = 400, fill = ink, children }: {
20
- x?: number; y: number; size?: number; weight?: number; fill?: string; children: ReactNode;
21
- }) {
22
- return <text x={x} y={y} fontSize={size} fontWeight={weight} fill={fill}>{children}</text>;
23
- }
24
-
25
- function Canvas({ title, description, page, children }: {
26
- title: string; description: string; page: number; children: ReactNode;
27
- }) {
28
- return <svg xmlns="http://www.w3.org/2000/svg" width="1920" height="1080" viewBox="0 0 1920 1080"
29
- role="img" aria-label={`${title}. ${description}`} fontFamily="IBM Plex Sans, sans-serif" data-birch-page={page}>
30
- <rect width="1920" height="1080" fill="#FFFFFF" />
31
- <Copy y={136} size={62} weight={600}>{title}</Copy>
32
- {children}
33
- <Copy x={1770} y={1020} size={24} fill={muted}>{page} / 2</Copy>
34
- </svg>;
35
- }
36
-
37
- const Evidence = () => <Canvas page={1} title="Four medians fell; access removal rose"
38
- description="Synthetic Birch data, median active processing minutes per completed case; lower is better. Account setup: before 18, after 12. Address correction: before 11, after 10. Refund review: before 25, after 19. Access removal: before 7, after 8. Supplier onboarding: before 32, after 24. Each workflow has 80 independent cases per period. Waiting time excluded. These observations do not establish causation.">
39
- <Copy y={202} size={30} fill={muted}>Birch · Synthetic median active processing time per completed case · Lower is better</Copy>
40
- <g transform="translate(112 262)">
41
- <Bar {...chartDefaults(palettes.paper)} width={1696} height={640}
42
- data={[...workflows].reverse()} keys={['Before', 'After']} indexBy="workflow"
43
- layout="horizontal" groupMode="grouped" valueScale={{ type: 'linear', min: 0, max: 35 }}
44
- margin={{ top: 0, right: 90, bottom: 60, left: 345 }} padding={0.26} innerPadding={7}
45
- colors={({ id }) => id === 'Before' ? before : after}
46
- label={d => `${d.id} ${d.value}`} labelTextColor="#FFFFFF" labelSkipWidth={0} labelSkipHeight={0}
47
- axisLeft={{ tickSize: 0, tickPadding: 24 }}
48
- axisBottom={{ tickSize: 0, tickPadding: 16, tickValues: [0, 5, 10, 15, 20, 25, 30, 35] }}
49
- enableGridX enableGridY={false} gridXValues={[0, 5, 10, 15, 20, 25, 30, 35]}
50
- theme={{ text: { fontFamily: 'IBM Plex Sans', fontSize: 28, fill: ink },
51
- axis: { ticks: { text: { fontSize: 28, fill: ink } }, domain: { line: { stroke: '#8A969F' } } },
52
- grid: { line: { stroke: '#DCE2E5', strokeWidth: 1 } },
53
- labels: { text: { fontSize: 26, fontWeight: 500 } } }}
54
- />
55
- </g>
56
- <Copy x={1340} y={935} size={27} fill={muted}>Minutes · common zero baseline</Copy>
57
- <Copy y={934} size={30} weight={600} fill={after}>Access removal: +1 minute</Copy>
58
- <Copy y={984} size={27} fill={muted}>80 different cases per workflow per period · Two weeks each · Waiting time excluded</Copy>
59
- </Canvas>;
60
-
61
- const Decision = () => <Canvas page={2} title="Investigate before extending the revised queue"
62
- description="Recommendation: investigate the access-removal increase and check case mix and quality before extending the revised queue. Supplier onboarding has the largest absolute median reduction, 8 minutes, but still the highest after median, 24 minutes. Independent groups were not randomized or matched; complexity and staffing could differ. No raw times, variability or quality measurements were supplied. Median differences cannot establish total savings or imply every case became faster.">
63
- <Copy y={207} size={32} fill={muted}>Observed changes are a reason to investigate, not evidence that the queue caused them.</Copy>
64
- <Copy y={322} size={38} weight={600}>Check before rollout</Copy>
65
- <Copy x={1050} y={322} size={38} weight={600}>What the comparison cannot tell us</Copy>
66
-
67
- <Copy y={400} size={32} weight={600} fill={after}>Investigate access removal</Copy>
68
- <Copy y={451}>Its median rose from 7 to 8 minutes.</Copy>
69
- <Copy y={497}>Review the workflow and the cases behind it.</Copy>
70
-
71
- <Copy y={594} size={32} weight={600} fill={after}>Check case mix, staffing and quality</Copy>
72
- <Copy y={645}>Before extending the queue, compare complexity</Copy>
73
- <Copy y={691}>and staffing, and collect quality measurements.</Copy>
74
-
75
- <Copy y={788} size={32} weight={600} fill={after}>Keep supplier onboarding in view</Copy>
76
- <Copy y={839}>32 → 24 minutes: the largest drop, 8 minutes.</Copy>
77
- <Copy y={885}>It still has the highest after-period median.</Copy>
78
-
79
- <Copy x={1050} y={400} size={32} weight={600}>No causal attribution</Copy>
80
- <Copy x={1050} y={451}>The queue changed between two two-week periods.</Copy>
81
- <Copy x={1050} y={497}>Groups were independent, not randomized or matched;</Copy>
82
- <Copy x={1050} y={543}>case complexity and staffing could differ.</Copy>
83
-
84
- <Copy x={1050} y={640} size={32} weight={600}>No estimate of uncertainty or total savings</Copy>
85
- <Copy x={1050} y={691}>No raw times, variability or quality data were supplied.</Copy>
86
- <Copy x={1050} y={737}>Do not multiply median changes by case counts</Copy>
87
- <Copy x={1050} y={783}>to claim total time or money saved.</Copy>
88
- <Copy x={1050} y={861}>A lower median does not mean every case was faster.</Copy>
89
- <Copy y={1000} size={27} fill={muted}>Birch is fictional. All measurements are synthetic, hand-authored data.</Copy>
90
- </Canvas>;
91
-
92
- export const meta = { title: 'Birch — Processing time' };
93
- export const notes = [
94
- 'Source: exact supplied PROMPT.md. The chart compares independent medians, not paired cases. All bars share a 0–35 minute scale.',
95
- 'Recommendation follows the supplied brief. No causal, total-savings, statistical-significance or universal-improvement claim is justified.',
96
- ];
97
- export default [Evidence, Decision];
@@ -1,29 +0,0 @@
1
- Make a three-page presentation helping the operations lead at Moss choose a
2
- support inbox for a six-person team. Compare the options against the team's
3
- actual needs and recommend what to trial.
4
-
5
- ---
6
-
7
- Moss and all three products are fictional. The team needs email intake, shared
8
- assignment and a complete CSV export of ticket history. Its monthly subscription
9
- budget is $150. Chat support would be useful later, but is not required now.
10
- The team does not have capacity to operate its own server.
11
-
12
- - Postbox: hosted, $18 per agent per month. Email intake, shared assignment and
13
- complete CSV history export are included. No chat channel. No setup fee.
14
- - Threadline: hosted, $24 per agent per month. Includes email, chat, shared
15
- assignment and complete CSV history export. No setup fee.
16
- - OwnDesk: self-hosted, no software subscription fee. Includes email, chat,
17
- shared assignment and complete CSV history export. The team must supply
18
- hosting, backups, upgrades and incident response; their costs are unknown.
19
-
20
- These are hand-authored scenario specifications, not vendor research. Hosted
21
- prices exclude tax and assume six paid agents. There are no measured usability,
22
- reliability or migration results. A feature being listed does not establish
23
- how well it works.
24
-
25
- ---
26
-
27
- Recommend a first trial, explain what would make the other hosted option worth
28
- its extra cost, and identify what to verify before purchase. Treat self-hosting
29
- as an operational commitment rather than a zero-cost option.
@@ -1,95 +0,0 @@
1
- import type { ReactNode } from 'react';
2
- import '../../lib/typeface.ts';
3
-
4
- const ink = '#172B26';
5
- const muted = '#4F605A';
6
- const accent = '#236B50';
7
- const rule = '#C4CEC9';
8
-
9
- function Copy({ x = 112, y, lines, size = 36, weight = 400, color = ink }: {
10
- x?: number; y: number; lines: string[]; size?: number; weight?: number; color?: string;
11
- }) {
12
- return <text x={x} y={y} fill={color} fontSize={size} fontWeight={weight}>
13
- {lines.map((line, i) => <tspan key={i} x={x} dy={i ? size * 1.35 : 0}>{line}</tspan>)}
14
- </text>;
15
- }
16
-
17
- function Canvas({ title, description, number, children }: {
18
- title: string; description: string; number: number; children: ReactNode;
19
- }) {
20
- return <svg xmlns="http://www.w3.org/2000/svg" width="1920" height="1080" viewBox="0 0 1920 1080"
21
- fontFamily="IBM Plex Sans" role="img" aria-label={`${title}. ${description}`} data-moss-page={number}>
22
- <rect width="1920" height="1080" fill="#FFFFFF" />
23
- <Copy y={154} lines={[title]} size={72} weight={600} />
24
- {children}
25
- <Copy x={1752} y={1022} lines={[`${number} / 3`]} size={28} color={muted} />
26
- </svg>;
27
- }
28
-
29
- const Shortlist = () => <Canvas number={1} title="Moss should trial Postbox first"
30
- description="Fictional scenario. Six agents need email, shared assignment and complete CSV history export. Postbox includes all three for $108 per month before tax, leaving $42 of the $150 subscription budget. Threadline costs $144 and adds chat. OwnDesk requires server operations Moss cannot supply.">
31
- <Copy y={234} lines={['Six people. Email intake, shared assignment and complete CSV history export.']} color={muted} />
32
- <Copy y={332} lines={['All three list the required features. Cost and operating capacity decide the shortlist.']} size={38} weight={500} />
33
- <Copy x={112} y={423} lines={['Option']} size={30} color={muted} />
34
- <Copy x={510} y={423} lines={['Monthly cost · six agents']} size={30} color={muted} />
35
- <Copy x={1038} y={423} lines={['Fit for Moss now']} size={30} color={muted} />
36
- <line x1={112} x2={1808} y1={452} y2={452} stroke={rule} strokeWidth={2} />
37
- <Copy y={512} lines={['Postbox']} size={44} weight={600} color={accent} />
38
- <Copy x={510} y={512} lines={['$108 subscription', '$18 × 6 agents']} size={36} />
39
- <Copy x={1038} y={512} lines={['Hosted · trial first', 'Meets today’s needs; no chat channel.']} size={36} />
40
- <line x1={112} x2={1808} y1={594} y2={594} stroke={rule} strokeWidth={2} />
41
- <Copy y={653} lines={['Threadline']} size={44} weight={600} />
42
- <Copy x={510} y={653} lines={['$144 subscription', '$24 × 6 agents']} size={36} />
43
- <Copy x={1038} y={653} lines={['Hosted · conditional alternative', 'Adds chat, useful later rather than now.']} size={36} />
44
- <line x1={112} x2={1808} y1={735} y2={735} stroke={rule} strokeWidth={2} />
45
- <Copy y={794} lines={['OwnDesk']} size={44} weight={600} />
46
- <Copy x={510} y={794} lines={['$0 software subscription', 'Operating costs unknown']} size={36} />
47
- <Copy x={1038} y={794} lines={['Self-hosted · exclude for now', 'Moss cannot operate its own server.']} size={36} />
48
- <line x1={112} x2={1808} y1={876} y2={876} stroke={rule} strokeWidth={2} />
49
- <Copy y={936} lines={['Fictional, hand-authored specifications—not vendor research. Hosted prices exclude tax;', 'both hosted options have no setup fee. Listed features do not establish quality.']} size={30} color={muted} />
50
- </Canvas>;
51
-
52
- const Tradeoff = () => <Canvas number={2} title="Chat must earn its $36 monthly premium"
53
- description="Postbox is $108 per month with $42 subscription headroom; Threadline is $144 with $6 headroom against a $150 budget, before tax. Trial Threadline if a concrete near-term chat workflow is valuable enough to justify the premium. OwnDesk includes chat but requires hosting, backups, upgrades and incident response with unknown costs.">
54
- <Copy y={239} lines={['Both hosted options fit the $150 subscription budget before tax.']} size={38} color={muted} />
55
- <Copy y={358} lines={['Postbox']} size={42} weight={600} color={accent} />
56
- <Copy y={442} lines={['$108 / month']} size={64} weight={600} />
57
- <Copy y={505} lines={['$42 budget headroom']} size={34} color={muted} />
58
- <Copy x={982} y={358} lines={['Threadline']} size={42} weight={600} />
59
- <Copy x={982} y={442} lines={['$144 / month']} size={64} weight={600} />
60
- <Copy x={982} y={505} lines={['$6 budget headroom']} size={34} color={muted} />
61
- <Copy y={624} lines={['Start with the current workflow']} size={40} weight={600} />
62
- <Copy y={682} lines={['Postbox covers the three required capabilities.', 'Do not pay for chat on a feature list alone.']} size={36} />
63
- <Copy x={982} y={624} lines={['Trial Threadline when chat has a job']} size={40} weight={600} />
64
- <Copy x={982} y={682} lines={['Name a near-term chat workflow and test it.', 'Choose Threadline only if the added value', 'justifies $36/month and the final bill fits.']} size={36} />
65
- <line x1={112} x2={1808} y1={847} y2={847} stroke={rule} strokeWidth={2} />
66
- <Copy y={911} lines={['OwnDesk also lists chat, but Moss would own hosting, backups, upgrades and incident', 'response. With no operating capacity and unknown costs, it is not a zero-cost alternative.']} size={34} />
67
- <Copy y={1014} lines={['Fictional scenario · subscription calculations for six paid agents, before tax.']} size={28} color={muted} />
68
- </Canvas>;
69
-
70
- const Trial = () => <Canvas number={3} title="Use the trial to test the purchase decision"
71
- description="Start Postbox with a representative sample. Verify email intake and shared assignment with all six agents; reconcile a CSV export to ticket history; confirm six-agent pricing and tax. No usability, reliability or migration results are measured. Purchase only after required workflow and export checks pass; compare Threadline if chat becomes a justified need.">
72
- <Copy y={239} lines={['Begin with Postbox and representative tickets, then make a go/no-go decision.']} size={38} color={muted} />
73
- <Copy y={369} lines={['Verify in the trial']} size={32} color={muted} />
74
- <Copy x={788} y={369} lines={['Evidence to collect before purchase']} size={32} color={muted} />
75
- <line x1={112} x2={1808} y1={397} y2={397} stroke={rule} strokeWidth={2} />
76
- <Copy y={463} lines={['Email + assignment']} size={40} weight={600} />
77
- <Copy x={788} y={463} lines={['Send incoming email; assign and reassign tickets.', 'Have all six agents confirm ownership is clear.']} size={36} />
78
- <line x1={112} x2={1808} y1={549} y2={549} stroke={rule} strokeWidth={2} />
79
- <Copy y={613} lines={['Complete CSV history']} size={40} weight={600} />
80
- <Copy x={788} y={613} lines={['Export the sample and reconcile it to ticket history.', 'Check records, fields and chronological completeness.']} size={36} />
81
- <line x1={112} x2={1808} y1={699} y2={699} stroke={rule} strokeWidth={2} />
82
- <Copy y={763} lines={['Final cost + transition']} size={40} weight={600} />
83
- <Copy x={788} y={763} lines={['Confirm the six-agent quote and tax against budget.', 'Test a small migration before committing the inbox.']} size={36} />
84
- <line x1={112} x2={1808} y1={849} y2={849} stroke={rule} strokeWidth={2} />
85
- <Copy y={915} lines={['Buy only after required workflow and export checks pass.']} size={40} weight={600} color={accent} />
86
- <Copy y={974} lines={['No measured usability, reliability or migration results exist in this fictional scenario.', 'Review reliability evidence separately; a short trial cannot establish long-term reliability.']} size={30} color={muted} />
87
- </Canvas>;
88
-
89
- export const meta = { title: 'Moss — choosing a support inbox', createdAt: '2026-09-12T14:20:00Z' };
90
- export const notes = [
91
- 'Recommendation based only on supplied fictional specifications, not observed product performance.',
92
- 'Derived arithmetic: 18 × 6 = 108; 24 × 6 = 144; 144 − 108 = 36; 150 − 108 = 42; 150 − 144 = 6.',
93
- 'Trial checks are proposed decision criteria, not measured results or claims about product behavior.',
94
- ];
95
- export default [Shortlist, Tradeoff, Trial];
@@ -1,34 +0,0 @@
1
- Make a three-page presentation for the operations lead at Cedar Support to help
2
- decide whether to extend a trial of suggested replies. Explain the trade-off
3
- between handling time and quality, what the evidence supports, and what the
4
- team should learn next.
5
-
6
- ---
7
-
8
- Cedar Support is a fictional customer-support team. These figures are synthetic,
9
- hand-authored examples rather than results of an actual trial.
10
-
11
- Two groups each handled 120 tickets during one week. Assignment was not
12
- randomized, and ticket difficulty and agent experience were not controlled.
13
-
14
- - Standard workflow: median handling time of 12 minutes; 108 tickets passed
15
- quality review; 9 reopened within seven days of closure.
16
- - Suggested replies: median handling time of 9 minutes; 102 tickets passed
17
- quality review; 15 reopened within seven days of closure.
18
-
19
- Quality review and reopening are separate measures: a ticket can pass review
20
- and later reopen. Each rate uses all 120 tickets in its group. The quality rates
21
- are 90% and 85%; the reopen rates are 7.5% and 12.5%.
22
-
23
- We have no raw timing observations, variance estimates, confidence intervals,
24
- labor costs or customer-satisfaction results. The groups cannot establish
25
- causality, and their median times cannot tell us total hours saved.
26
-
27
- The proposed next step is a longer randomized trial with comparable ticket
28
- categories and human review retained. Quality and reopen-rate acceptance
29
- criteria would be agreed before starting; no numerical thresholds have been set.
30
-
31
- ---
32
-
33
- Give it a light editorial feel, with a white background, a deep forest-green
34
- accent, serif headlines and clean sans-serif body text.