Who does what
GreatBook does not have an elaborate permission matrix. It has one rule, applied consistently, and the roles fall out of it.The document-intake rule: three distinct, authenticated people stand behind every document-originated posted journal entry.
Whoever submitted the document, whoever approved it into the queue, and whoever approved the posting
must be three different named users.
The seven roles
Submitter
Files a document into the queue, by composing it in the Typewriter or dropping it into chat.
Anyone signed in can be a submitter.
A submitter can never approve their own document at either gate.
Designated document approver
Signs a composed Typewriter document before it may be handed to the Clerk.
Designated per document type.
Cannot approve a document they composed.
Intake approver
Stands at gate 1 and answers “is this document real and correctly extracted?”.
Approving launches the Bookkeeper and moves no money.
May not be the submitter.
Posting checker
Stands at gate 2 and answers “is this journal entry right?”.
This releases a document-originated proposal; the ledger service remains the only component that writes.
May not be anyone who submitted, drafted, edited or approved that document.
Accountant
Runs the period close, reads the checklist, and proposes adjusting entries.
Proposes only. An adjustment follows its stable-source approval path and reaches the single writer through the Bookkeeper gate.
Auditor
Asks the Auditor agent for independent assurance and reads its findings.
Nothing in this role can change a book, because the agent has no write path at all.
Developer
Operates the system: connector health, migrations, deploys.
Being able to deploy the system does not confer the ability to approve a posting in it.
Who may do what in the document workflow
Agents are not people
Five identities are agents, never people: the Clerk, the Bookkeeper, the Accountant, the Auditor and the Typewriter. The document gate records who approved its journal entry, and “an agent approved it” is not an answer that provenance may carry. So agent identities are refused at both gates, as are placeholder identities:unknown, anonymous, none, n/a, user, someone, test, and the bare string submitter.
That last one has a history worth knowing, because it explains why the rule is written the way it is.
Why the old rule was decorative
Why the old rule was decorative
The separation-of-duties check used to compare identities as raw strings.
In the deployed path the maker set contained no real human identity except the intake approver:
So
checker != submitter compared a real email address against the word “submitter”, and passed every
time.
The person who uploaded a document could approve their own document.
The advertised “maker is not checker” meant “two humans touch the money”, not “the uploader cannot
approve”.The fix had two halves, and only both together are worth anything.
The rule now compares three named identities, and the submitter is now a real identity: the UI’s
passthrough injects it from the validated session and strips any the browser sent.
A rule comparing authenticated identities is only worth writing once the identities are authenticated.How two spellings of one person are handled
The three identities do not all arrive in the same format, so they are compared on a canonical key: casefolded, trimmed, and reduced to the local part of an email address.Thai, thai and thai@vinmake.com are therefore one person.
That choice leans deliberately in one direction.
It can merge two different people who share a local part across domains, which refuses a posting that should have been allowed.
The opposite error, treating one person’s two spellings as two people, would admit a self-approval.
A refused posting is a phone call.
An admitted self-approval is a fraudulent entry in an immutable ledger.
Where the rule is enforced
Three places, deliberately, because each covers what the others cannot.1
At the intake gate
So a document cannot even enter the active queue in a state where it could never be posted.
Fail at the gate the human is standing at, not two gates later.
2
At the API boundary of the posting gate
So the reviewer gets a clean 409 with a readable reason rather than a failed run.
3
Inside the Bookkeeper, immediately before the writer
Against the record the graph re-read itself, so the rule holds even if the graph is driven another way.
A rejection is subject to only half the rule.
Refusing a document writes nothing to the ledger, so it is not gated on three distinct people, only
on the refusal itself being attributable to a named user.
Applying the full rule to rejections used to strand documents: a row whose submitter was still a
placeholder could not be posted, could not be rejected, and could not be resubmitted.
It sat active forever and showed up in the Auditor’s reconciliation as a document with no journal entry.
Related
- Two layers on the same documents - the layer division these roles work within
- The golden path - four identities walking one document end to end
- Gate 1, the intake approval
- Gate 2, the posting approval