- title
- Authoring guide for Stillcurrent
- audience
- LLMs that write documents for this viewer
- renderer
- GitHub-flavoured Markdown + Mermaid 11.16
- updated
- 2026-10-04
Authoring guide for Stillcurrent#
You are writing a Markdown document that will be opened in a custom viewer. The viewer renders GitHub-flavoured Markdown, draws Mermaid diagrams, highlights code and styles everything itself. Follow this guide exactly: anything outside it either renders as plain text or breaks the page's styling.
The viewer owns all colours, fonts, line styles and layout of diagrams. Never set colours, themes, fonts or curve styles in Markdown or Mermaid. Write content and structure only.
1. Output contract#
Produce one Markdown document, UTF-8, with
.mdextension when saved as a file.When you deliver the document inside a chat reply, wrap the whole document in a fence of four backticks with the language
markdown, so the triple-backtick fences inside it survive:Text````markdown --- title: … --- # … ```mermaid … ``` ````When you write it to a file, do not wrap it in any outer fence.
Do not add commentary before or after the document unless asked.
2. Document skeleton#
Use this order:
- Frontmatter (optional but recommended): a YAML block at the very top. The viewer shows it as a small properties card above the title.
- One H1 (
#): the document title. Use exactly one. - Summary: one or two plain sentences saying what the document is and who it is for.
- Sections as H2 (
##), subsections as H3 (###). Go no deeper than H4.
---
title: Posting a sales invoice
status: draft
owner: Accounting team
updated: 2026-10-04
tags: [posting, ledger, outbox]
---
# Posting a sales invoice
How a sales invoice moves from draft to the general ledger, for backend developers.
## Request path
…Frontmatter rules#
- Use only
key: valuelines, inline listskey: [a, b, c], or a key followed by- itemlines. - Nested objects are not supported; they are flattened. Keep values short (they sit in a narrow card).
- Lists render as small chips, so
tagsandownerswork well as lists.
How headings behave#
- H1, H2 and H3 appear in the Contents sidebar. Write headings as short, specific noun phrases, because they double as navigation.
- Every H2 gets a divider line above it, so H2s mark major sections. Do not use H2 for a single short paragraph.
- Do not number headings by hand ("1.", "2.") unless the order is meaningful to the reader.
3. Supported Markdown#
| Element | Syntax | Notes |
|---|---|---|
| Paragraphs | blank line between blocks | Single line breaks inside a paragraph are joined; do not hard-wrap for layout. |
| Emphasis | *italic*, **bold**, ~~strike~~ |
Use bold sparingly, for key terms. |
| Inline code | `code` |
For identifiers, paths, commands, config keys. |
| Lists | - or 1. |
Nest with two or four spaces. Use numbered lists only when order matters. |
| Task lists | - [ ] and - [x] |
Rendered as checkboxes (read-only). |
| Blockquote | > text |
For quotations. For notes and warnings use callouts (section 4). |
| Tables | GitHub pipe tables | See section 5. |
| Code blocks | triple-backtick fence with a language | See section 6. |
| Mermaid | ```mermaid fence |
See sections 11 to 13. |
| Horizontal rule | --- on its own line |
Rarely needed; H2s already draw dividers. |
| Links | [text](https://…), [text](#heading-slug) |
See section 7. |
| Keyboard keys | <kbd>Ctrl</kbd> |
Allowed inline HTML. |
| Highlight | <mark>text</mark> |
Allowed inline HTML; use rarely. |
| Line break in a table cell | <br> |
The only reliable way to break a line inside a cell. |
4. Callouts#
Use GitHub-style alerts. The marker must be alone on the first line of the blockquote, in capitals:
> [!NOTE]
> Background the reader should know.
> [!TIP]
> A better or faster way to do something.
> [!IMPORTANT]
> Something the reader must not miss.
> [!WARNING]
> Something that can cause problems.
> [!CAUTION]
> Something that can cause data loss or security issues.- Only these five types exist. Any other marker (
[!INFO],[!DANGER]) renders as a plain quote. - Use at most one callout per section. Callouts lose their effect when everything is a callout.
5. Tables#
- Always include the header row and the separator row.
- Align numbers to the right with
--:. Text stays left-aligned (---). - Header cells are shown in small capitals, so keep them to one to three words.
- Wide tables scroll sideways inside their frame. Still, prefer five columns or fewer.
- Do not put block content (lists, code blocks) in cells. Use
<br>for a line break. - Escape a literal pipe inside a cell as
\|.
| Account | Purpose | Debit | Credit |
| ----------------- | ------------------ | -------: | -------: |
| 1400 Receivables | `sales.receivable` | 1,190.00 | |
| 8400 Revenue 19 % | `sales.revenue` | | 1,000.00 |6. Code blocks#
- Always put a language tag after the opening fence. The viewer shows it as the block's label and uses it for syntax colouring.
- Use
textfor output, logs or anything that is not code. - Keep blocks under about 40 lines. Show the relevant part, not whole files.
- Do not put line numbers or
$prompts inside the code unless the reader needs them.
Languages with syntax colouring (tag, then common aliases):
bash (sh, shell), c, cpp, csharp (cs), css, diff, go, graphql, ini (toml), java, javascript (js, jsx), json, kotlin (kt), less, lua, makefile, markdown (md), objectivec, perl, php, plaintext (text), python (py), r, ruby (rb), rust (rs), scss, sql, swift, typescript (ts, tsx), vbnet, xml (html, svg), yaml (yml).
Other tags (for example dart, dockerfile, http) still display with their label, just without colours.
7. Links and anchors#
- External links must be absolute:
https://…. They open in a new tab. - Link to a heading in the same document with its slug:
[see Containers](#level-2-containers). - Slug rules (GitHub style): lowercase, punctuation removed, spaces become hyphens, letters in any script are kept. A repeated heading gets
-2,-3.## Level 2: Containers→#level-2-containers### Why not REST?→#why-not-rest
- Inside a project, link to another document of the same project by its file name:
[see the ledger rules](ledger-rules.md)or[steps](./posting-flow.md#steps). The match ignores case,.mdmay be left out, and spaces can be written as%20. These links open that document (also on a shared project page). - Links to any other files (
../other.md,folder/a.md, or a file that isn't in the project) cannot be opened in the viewer. Avoid them, or also name the file in the text.
8. Images#
- Images from relative paths (
./img/a.png) are not shown; the viewer displays a placeholder with the alt text. - Only
https://images and images embedded asdata:image/…URIs display. Anything else (http://, relative paths) shows the placeholder. - Prefer a Mermaid diagram over an image whenever the picture is a diagram.
- Always write meaningful alt text:
.
9. Multilingual text and right-to-left scripts#
- Each block (paragraph, list item, table cell, heading) picks its own direction from its first letter. Arabic, Persian and Hebrew paragraphs render right to left automatically.
- Keep each language in its own paragraph or list item. A short foreign word inside a sentence is fine.
- Do not add
dirattributes or Unicode direction marks.
10. Not supported: do not use#
- Math or LaTeX (
$…$,$$…$$,\(...\)): shown as raw text. Write formulas in inline code or plain words. - Footnotes (
[^1]), definition-list shorthand, custom containers (:::note), wiki links ([[Page]]), emoji shortcodes (:tada:). - Raw HTML beyond
<kbd>,<mark>,<br>,<sub>,<sup>,<details>/<summary>. Scripts, styles, iframes and event attributes are removed. - Inline styles or colour HTML (
<span style="color:…">,<font>). - PlantUML, Graphviz/DOT, ASCII-art diagrams. Use Mermaid.
- Emoji as section markers or bullets.
11. Mermaid: rules for every diagram#
Write each diagram in its own fence:
```mermaid
flowchart LR
A[Draft] -->|post| B[Posted]
```Styling is the viewer's job#
The viewer applies the reader's chosen diagram colour, light or dark theme, the page typeface, rounded connector corners and its own spacing. Therefore:
- Never start a diagram with
%%{init: …}%%or a---config block. - Never use
style,linkStyle,classDef … fill/stroke/color,class X someClassfor colour,themeVariables,UpdateElementStyleorUpdateRelStyle. - Never set
curve, fonts or sizes. - Express emphasis with words, stereotypes (
<<interface>>) or grouping (subgraph, boundaries), not colour.
The viewer also animates direction: small pulses travel along every one-way connector toward its arrowhead (readers can turn this off). So give each arrow the direction you mean, and use a line without an arrowhead (---, --) or a two-headed arrow where there is no single direction. Never draw an arrow just for decoration.
Size and readability#
- Keep one idea per diagram: about 15 nodes or fewer, 20 connectors or fewer. Split larger systems into several diagrams.
- Put one sentence before each diagram saying what it shows. The diagram card shows only its type ("Flowchart", "Sequence"), not a caption.
- Labels: short noun phrases for boxes, short verb phrases for arrows (one to four words).
- Readers can zoom, pan and expand diagrams, so wide diagrams are acceptable. Prefer
LRfor pipelines andTBfor hierarchies.
Supported diagram types (Mermaid 11.16)#
| Purpose | First line |
|---|---|
| Flow, process, architecture sketch | flowchart LR / flowchart TB |
| Calls over time between parties | sequenceDiagram |
| Types, interfaces, relations | classDiagram |
| Lifecycle, status machine | stateDiagram-v2 |
| Database tables | erDiagram |
| Software architecture (C4) | C4Context, C4Container, C4Component, C4Dynamic, C4Deployment |
| Schedule | gantt |
| Proportions | pie |
| Trends | xychart-beta |
| Two-axis positioning | quadrantChart |
| Hierarchy of ideas | mindmap |
| Events in order | timeline |
| Branching history | gitGraph |
| User experience steps | journey |
| Flows with quantities | sankey-beta |
| Requirements | requirementDiagram |
| Columns of work items | kanban |
| Fixed-grid block layout | block-beta |
| Network packet fields | packet-beta |
| Cloud/service layout | architecture-beta |
| Comparing scores across dimensions | radar-beta |
| Nested quantities | treemap-beta |
| Overlapping sets | venn-beta |
| Root causes (fishbone) | ishikawa-beta |
| File or folder tree | treeView-beta |
| Process with owners per lane | swimlane-beta LR |
| Event modeling | eventmodeling |
| Strategy map | wardley-beta |
| Problem domains | cynefin-beta |
| Grammar (syntax diagram) | railroad-ebnf-beta |
Section 17 shows a working example of every type.
Syntax pitfalls that cause errors#
Flowchart:
- Node IDs are single words:
orderSvc[Order service]. Never use the bare wordendas an ID (usedoneorEnd). - Quote labels that contain punctuation:
A["Validate (strict)"],B["Cost: 1,190 €"]. - Line break inside a label:
A["First line<br/>second line"]. - Edge labels:
A -->|calls| BorA -- calls --> B. - After a link, do not start an ID with lowercase
oorx(A---oBdraws a circle end). Use readable IDs. - Subgraphs:
subgraph billing [Billing]…end.
Sequence:
- Declare participants first:
participant S as SalesService,actor U as User. - Solid call
->>, dashed reply-->>, notesNote over A,B: text. - Blocks:
alt/else/end,opt,loop,par/and. Every block needs itsend. - Do not use
;or#inside message text. Write#59;for a semicolon and#35;for#if you must. autonumberon its own line numbers the messages.
Class:
- Members:
+String name, methods:+post(PostingRequest r) PostingResult. - Generics use tildes:
List~PostingLine~,Map~String,Object~. - Static
$and abstract*go after the member:+of(String code)$ DocumentType. - Relations: inheritance
<|--, realisation<|.., composition*--, aggregationo--, association-->, dependency..>. Cardinality:Order "1" *-- "many" Line.
State:
- Use
stateDiagram-v2, start and end with[*]:[*] --> Draft,Void --> [*]. - Transition labels:
Draft --> Posted : post.
ER:
CUSTOMER ||--o{ INVOICE : receives.Attributes go inside braces after the entity name, one per line, as
type namewith optionalPK,FKorUK:TextINVOICE { uuid id PK string number date issued }
Gantt:
- Always set
dateFormat YYYY-MM-DD. Each task needs an id or a dependency:Build API :api, 2026-10-05, 10d,Tests :after api, 5d.
12. Class diagrams: stereotypes the viewer styles#
Put the stereotype as the first line inside the class body. The viewer recognises these words and styles them consistently:
| Stereotype | Use for | Look |
|---|---|---|
<<interface>> |
interfaces, ports | coloured border and title |
<<record>> |
value objects, DTOs, Java records | tinted fill |
<<enumeration>> |
enums | tinted fill |
<<entity>> |
aggregates, persisted entities | dark border |
<<abstract>> |
abstract base classes | dotted border |
<<plugin>> |
optional, later-phase or third-party parts | dashed amber border |
<<service>> or anything else |
implementations | default look |
classDiagram
direction LR
class PostingEngine {
<<interface>>
+post(PostingRequest r) PostingResult
}
class DefaultPostingEngine {
<<service>>
-resolveAccounts(PostingRequest r) Resolved
}
class Side {
<<enumeration>>
DEBIT
CREDIT
}
PostingEngine <|.. DefaultPostingEngine
DefaultPostingEngine ..> Side13. C4 model diagrams#
The viewer gives C4 diagrams special treatment. It colours people, systems, containers and components as shades of the reader's diagram colour (external elements in grey). It reroutes every relationship as a right-angled connector that goes around boxes, places labels in free space, and widens the gaps to fit the labels.
Which diagram for which level#
| C4 level | Mermaid keyword | Show |
|---|---|---|
| 1. System context | C4Context |
people and systems around the one system in scope |
| 2. Containers | C4Container |
deployable/runnable parts inside the system boundary |
| 3. Components | C4Component |
the parts inside one container |
| 4. Code | classDiagram |
the classes behind one component (Mermaid has no C4 code type) |
| Runtime flow | C4Dynamic |
numbered interactions for one scenario |
| Infrastructure | C4Deployment |
nodes and where containers run |
Elements#
- People:
Person(alias, "Label", "Description"),Person_Ext(...). - Systems:
System,SystemDb,SystemQueue,System_Ext,SystemDb_Ext,SystemQueue_Ext. - Containers:
Container(alias, "Label", "Technology", "Description"), plusContainerDb,ContainerQueue,Container_Ext,ContainerDb_Ext,ContainerQueue_Ext. - Components:
Component(alias, "Label", "Technology", "Description"), plusComponentDb,ComponentQueue,Component_Ext, … - Boundaries:
Enterprise_Boundary(alias, "Label") { … },System_Boundary(…) { … },Container_Boundary(…) { … },Boundary(…) { … }. - Deployment:
Deployment_Node(alias, "Label", "Type") { … }.
Relationships#
Rel(from, to, "Label", "Technology"). The technology argument is optional.BiRel(a, b, "Label")for two-way relationships.Rel_U,Rel_D,Rel_L,Rel_Rare accepted but have no visible effect, because the viewer routes all connectors itself. PlainRelis preferred.- Connect elements to elements. Do not point a relationship at a boundary alias.
- Labels: a verb phrase of one to four words ("Reads and writes", "Sends webhooks"). Put protocols in the technology argument ("JDBC", "HTTPS"). Avoid very long single words; the gap between boxes grows to fit the longest word.
Layout: you control it through declaration order#
Mermaid places C4 elements in rows, in the order you declare them. Elements outside boundaries are drawn first, then each boundary's contents. Use this to get a clean picture:
- Declare elements in reading order: people first, then the system or boundary in scope, then external systems.
- Put elements that talk to each other next to each other in the order. Short connectors stay straight; distant ones need bends.
- End the diagram with
UpdateLayoutConfig($c4ShapeInRow="N", $c4BoundaryInRow="1"):N = 2for Context and Container diagrams with up to six elements.N = 3for Component diagrams with up to nine components.
- Keep each diagram to about nine elements. Split a busy container into two component diagrams.
- Descriptions: ten words or fewer. They wrap inside the box.
- Strings use double quotes and must not contain double quotes. Parentheses, colons and slashes inside the quotes are fine.
Complete C4 example (Level 2)#
C4Container
Person(accountant, "Accountant", "Posts invoices")
System_Ext(erp, "Customer ERP", "REST client")
System_Boundary(saas, "Accounting SaaS") {
Container(web, "Web app", "TypeScript, React", "Document, ledger and report screens")
Container(app, "Application", "Java 21, Spring Boot", "Modular monolith with the REST API")
ContainerDb(db, "Database", "PostgreSQL", "One schema per module")
ContainerQueue(outbox, "Event outbox", "Table and relay", "Delivers events after commit")
}
Rel(accountant, web, "Uses", "HTTPS")
Rel(web, app, "Calls", "JSON/HTTPS")
Rel(erp, app, "Calls", "REST")
Rel(app, db, "Reads and writes", "JDBC")
Rel(app, outbox, "Writes events", "same transaction")
Rel(outbox, erp, "Sends webhooks", "HTTPS")
UpdateLayoutConfig($c4ShapeInRow="2", $c4BoundaryInRow="1")14. Writing style#
- Write for a busy reader: the point first, details after.
- Short paragraphs (two to four sentences). One idea per paragraph.
- Prefer a table to a long list of "X: value" lines, and a list to a long sentence with many commas.
- Use active voice and concrete names ("
PostingEnginewrites the ledger", not "the ledger is written"). - Define each abbreviation once, at first use.
15. Checklist before you deliver#
- Exactly one H1; sections are H2; nothing deeper than H4.
- Frontmatter, if present, is at the very top and uses flat
key: valuelines. - Every code fence has a language tag; every fence is closed.
- Every Mermaid diagram starts directly with its type keyword. No
%%{init}%%, no styles, no colours. - Every diagram has one sentence before it explaining what it shows.
- Flowchart labels with punctuation are quoted; no node is called
end. - Sequence messages contain no
;or#; everyalt,loop,opt,parhas anend. - C4: elements declared in reading order, plain
Rel, short labels,UpdateLayoutConfigat the end, nine elements or fewer. - Callouts use one of the five GitHub types, marker alone on its first line.
- No math, footnotes, relative images, raw styling HTML or emoji headings.
- In chat, the whole document is wrapped in a four-backtick
markdownfence.
16. Template#
Copy this and replace the content:
---
title: <Document title>
status: draft
owner: <Team or person>
updated: <YYYY-MM-DD>
tags: [<tag>, <tag>]
---
# <Document title>
<One or two sentences: what this document covers and for whom.>
> [!NOTE]
> <Optional context the reader needs before starting.>
## Overview
<Short explanation.>
<One sentence describing the diagram below.>
```mermaid
flowchart LR
request[Request] --> validate["Validate input"]
validate --> process[Process]
process --> store[(Database)]
```
## <Section>
| Item | Meaning | Value |
| ------ | ------------- | ----: |
| <name> | <description> | 0.00 |
```java
// <the relevant lines only>
```
## Open questions
- [ ] <Question or decision still open>17. Diagram gallery#
One working example of every diagram type the viewer draws, so you can see how each one looks in your colour and theme. Each block follows the rules above; copy one as a starting point. Open Source on any card to see its Mermaid text. Types marked beta are new in Mermaid and may change in a later version; prefer the stable types for documents that must last.
Flowchart#
How a sales invoice moves from draft to the ledger.
flowchart LR
draft[Draft invoice] --> check{"Valid?"}
check -->|yes| post[Post to ledger]
check -->|no| fix[Return to author]
fix --> draft
post --> ledger[(Ledger)]
post --> notify([Notify customer])Sequence diagram#
The calls made when an accountant posts an invoice.
sequenceDiagram
autonumber
actor U as Accountant
participant S as SalesService
participant T as TaxEngine
participant L as Ledger
U->>S: Post invoice
S->>T: Calculate tax
T-->>S: Tax lines
alt Period open
S->>L: Write entries
L-->>S: Entry ids
S-->>U: Posted
else Period closed
S-->>U: Rejected
endClass diagram#
The posting engine and the request it accepts. Section 12 lists the stereotypes the viewer styles.
classDiagram
class PostingEngine {
<<interface>>
+post(PostingRequest r) PostingResult
}
class DefaultPostingEngine {
-resolveAccounts(PostingRequest r) Resolved
}
class PostingRequest {
<<record>>
+UUID companyId
+List~PostingLine~ lines
}
class PostingLine {
<<record>>
+Money amount
+Side side
}
PostingEngine <|.. DefaultPostingEngine
DefaultPostingEngine ..> PostingRequest
PostingRequest "1" *-- "many" PostingLineState diagram#
The lifecycle of an invoice, with payment as a nested state.
stateDiagram-v2
[*] --> Draft
Draft --> Posted : post
Draft --> Cancelled : cancel
Posted --> Paid : payment received
Posted --> Void : void
state Paid {
[*] --> Partial
Partial --> Settled : final payment
}
Paid --> [*]
Void --> [*]
Cancelled --> [*]Entity relationship diagram#
The tables behind invoicing.
erDiagram
CUSTOMER ||--o{ INVOICE : receives
INVOICE ||--|{ INVOICE_LINE : contains
PRODUCT ||--o{ INVOICE_LINE : "appears on"
CUSTOMER {
uuid id PK
string name
string vat_number UK
}
INVOICE {
uuid id PK
uuid customer_id FK
string number
date issued
}
INVOICE_LINE {
uuid id PK
uuid invoice_id FK
uuid product_id FK
decimal amount
}
PRODUCT {
uuid id PK
string sku UK
}C4: system context#
Who uses the system and which systems it depends on. Section 13 has the container level and the C4 layout rules.
C4Context
Person(accountant, "Accountant", "Posts invoices")
System(saas, "Accounting SaaS", "Ledger, sales and reports")
System_Ext(bank, "Bank", "Statement feeds")
System_Ext(mail, "Email service", "Delivers invoices")
Rel(accountant, saas, "Uses", "HTTPS")
Rel(saas, bank, "Imports statements from")
Rel(saas, mail, "Sends email through", "SMTP")
UpdateLayoutConfig($c4ShapeInRow="2", $c4BoundaryInRow="1")C4: components#
The parts inside the sales API container.
C4Component
Container_Boundary(api, "Sales API") {
Component(ctrl, "Invoice controller", "Spring MVC", "REST endpoints")
Component(svc, "Posting service", "Java", "Validates and posts")
Component(repo, "Invoice repository", "JPA", "Reads and writes invoices")
}
ContainerDb(db, "Ledger DB", "PostgreSQL", "Invoices and entries")
Rel(ctrl, svc, "Calls")
Rel(svc, repo, "Uses")
Rel(repo, db, "Reads and writes", "JDBC")
UpdateLayoutConfig($c4ShapeInRow="3", $c4BoundaryInRow="1")C4: dynamic#
The numbered steps of one scenario: posting an invoice.
C4Dynamic
Person(user, "Accountant", "Posts invoices")
Container(web, "Web app", "React", "Invoice screens")
Container(api, "Sales API", "Java", "Posting rules")
ContainerDb(db, "Ledger DB", "PostgreSQL", "Entries")
Rel(user, web, "Clicks Post")
Rel(web, api, "Posts invoice", "JSON/HTTPS")
Rel(api, db, "Writes entries", "JDBC")
UpdateLayoutConfig($c4ShapeInRow="2", $c4BoundaryInRow="1")C4: deployment#
Where the containers run.
C4Deployment
Deployment_Node(eu, "EU region", "Cloud") {
Deployment_Node(k8s, "Kubernetes cluster", "Managed") {
Container(api, "Sales API", "Java", "Posting rules")
}
Deployment_Node(pg, "Managed PostgreSQL", "Service") {
ContainerDb(db, "Ledger DB", "PostgreSQL 17", "Entries")
}
}
Rel(api, db, "Reads and writes", "TLS")
UpdateLayoutConfig($c4ShapeInRow="2", $c4BoundaryInRow="1")Architecture (beta)#
Services and data stores in one cloud region, with icons.
architecture-beta
group eu(cloud)[EU region]
service web(internet)[Web app] in eu
service api(server)[Sales API] in eu
service db(database)[Ledger DB] in eu
service files(disk)[Exports] in eu
web:R --> L:api
api:R --> L:db
api:B --> T:filesBlock diagram#
Parts placed on a fixed grid.
block-beta
columns 3
web["Web app"] api["Sales API"] worker["Worker"]
space:3
db[("Ledger DB")] queue[["Outbox"]] mail["Email"]
web --> api
api --> db
api --> queue
queue --> worker
worker --> mailRequirement diagram#
Requirements and the element that satisfies them.
requirementDiagram
requirement post_once {
id: 1
text: An invoice posts exactly once
risk: high
verifymethod: test
}
functionalRequirement audit_trail {
id: 2
text: Every posting is traceable
risk: medium
verifymethod: inspection
}
element posting_engine {
type: service
}
posting_engine - satisfies -> post_once
posting_engine - satisfies -> audit_trailGit graph#
A feature branch merged back into main.
gitGraph
commit id: "init"
branch tax-engine
checkout tax-engine
commit id: "tax rules"
commit id: "tests"
checkout main
commit id: "hotfix"
merge tax-engine
commit id: "release"Gantt chart#
The plan for the next release.
gantt
title Invoicing v2
dateFormat YYYY-MM-DD
section Build
Posting API :api, 2026-10-05, 10d
Tax engine :tax, after api, 7d
section Release
Beta :beta, after tax, 5d
General release :milestone, ga, after beta, 0dTimeline#
Milestones in order.
timeline
title Ledger platform
2024 : Single-tenant ledger
2025 : Multi-tenant SaaS : Bank feeds
2026 : Public API : MCP server for agentsUser journey#
How an accountant feels at each step, scored 1 to 5.
journey
title Posting a month-end invoice
section Prepare
Open draft: 4: Accountant
Check tax lines: 3: Accountant
section Post
Post invoice: 5: Accountant, System
Send to customer: 4: SystemMind map#
The areas of the product.
mindmap
root((Invoicing))
Sales
Quotes
Invoices
Credit notes
Ledger
Posting
Periods
Integrations
Bank feeds
EmailKanban#
Work in progress.
kanban
todo[To do]
t1[Credit notes API]
t2[Bank feed retries]
doing[In progress]
t3[Tax engine v2]
shipped[Done]
t4[MCP server]Pie chart#
Share of invoices by status.
pie title Invoices by status
"Paid" : 62
"Posted" : 23
"Draft" : 11
"Void" : 4XY chart#
Invoices posted per month, as bars with a trend line.
xychart-beta
title "Invoices posted per month"
x-axis [Jan, Feb, Mar, Apr, May, Jun]
y-axis "Invoices" 0 --> 1400
bar [620, 710, 890, 940, 1120, 1260]
line [620, 710, 890, 940, 1120, 1260]Quadrant chart#
Technical debt placed by effort and impact.
quadrantChart
title Technical debt
x-axis Low effort --> High effort
y-axis Low impact --> High impact
quadrant-1 Plan carefully
quadrant-2 Do first
quadrant-3 Fill-in work
quadrant-4 Skip
Tax rules cache: [0.25, 0.8]
Retry queue: [0.4, 0.62]
Legacy PDF export: [0.8, 0.35]
Old admin UI: [0.75, 0.15]Sankey (beta)#
Where revenue goes. One source,target,value row per flow.
sankey-beta
Sales,Revenue,820
Services,Revenue,310
Revenue,Salaries,520
Revenue,Hosting,140
Revenue,Profit,470Radar chart (beta)#
Service quality today against the target, on a 0 to 5 scale.
radar-beta
title Service quality
axis perf["Performance"], rel["Reliability"], sec["Security"], cost["Cost"], dx["Developer experience"]
curve today["Today"]{3, 4, 4, 2, 3}
curve target["Target"]{4, 5, 5, 3, 4}
max 5
min 0Treemap (beta)#
Monthly cost, nested by area.
treemap-beta
"Monthly cost"
"Compute"
"API": 420
"Workers": 180
"Data"
"PostgreSQL": 310
"Backups": 60
"Email": 40Packet (beta)#
The fields of a TCP header, by bit position.
packet-beta
title TCP header
0-15: "Source port"
16-31: "Destination port"
32-63: "Sequence number"
64-95: "Acknowledgment number"
96-99: "Data offset"
100-105: "Reserved"
106-111: "Flags"
112-127: "Window"Venn diagram (beta)#
Overlap between two groups of users.
venn-beta
set api["API users"]:120
set ui["Web users"]:300
union api,ui:45Ishikawa (fishbone) (beta)#
Possible causes of late invoices, by category.
ishikawa-beta
Late invoices
Process
Manual approval step
Month-end backlog
Systems
Tax engine timeouts
Bank feed delays
People
Missing training
Data
Wrong customer emailsTree view (beta)#
A folder structure.
treeView-beta
├── src/
│ ├── invoices/
│ │ ├── post.ts
│ │ └── tax.ts
│ └── index.ts
├── package.json
└── README.mdSwimlanes (beta)#
Who does each step of an order.
swimlane-beta LR
subgraph Customer
Browse[Browse catalogue]
Pay[Pay]
end
subgraph Warehouse
Pick[Pick items]
Ship[Ship order]
end
subgraph Finance
Invoice[Raise invoice]
end
Browse --> Pay
Pay --> Pick
Pick --> Ship
Pay --> InvoiceEvent modeling (beta)#
A screen, the command it sends and the event that results.
eventmodeling
tf 01 ui CartUI
tf 02 cmd AddItem
tf 03 evt ItemAddedWardley map (beta)#
Components placed by visibility to the user and by evolution.
wardley-beta
title Invoicing
anchor Accountant [0.95, 0.9]
component "Invoice screens" [0.8, 0.65]
component "Posting rules" [0.6, 0.45] (build)
component "Tax engine" [0.45, 0.6] (buy)
component Database [0.25, 0.85] (outsource)
Accountant -> "Invoice screens"
"Invoice screens" -> "Posting rules"
"Posting rules" -> "Tax engine"
"Posting rules" -> DatabaseCynefin (beta)#
Sorting incident work by how well the problem is understood.
cynefin-beta
title Incident response
complex
"Investigate root cause"
complicated
"Analyse slow queries"
clear
"Restart worker"
chaotic
"Page on-call"
confusion
"Unknown failure"Railroad (beta)#
The grammar of an invoice number, in EBNF.
railroad-ebnf-beta
title "Invoice number"
number = prefix "-" year "-" digits ;
prefix = "INV" | "CRN" ;
year = digit digit digit digit ;
digits = digit { digit } ;
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;