Printed to last.
Account.
The green-bar style prints the system on continuous form in
design-system-greenbar.css:
IBM Plex Mono capitals, banded paper punched down both edges, torn rules and
[ BRACKET ] buttons. Same components, same markup — straight
off the line printer.
Reading in an unnamed pair — greenbar / blotter Change theme Browse all 8 →
01
Account page & identity card
The page behind /account
(_AccountChassis,
_SectionIdentity): a sticky rail and one card
per section, both generated from one list read three times — for
the rail, for the cards, and for the tally at the foot that says how many
sections have content and how many are absent. The identity card leads:
the monogram in the badge's tone, the name, the mono line, the byline when
a profile exists, the role pill on the trailing edge. And the outcome line,
done or refused and
a sentence, which falls under the cards when its own section has gone.
Account
Identity
acct_01SPECJOTNJo Tan
donerevoked Safari on iOS - 0 other sessions remaining
1 of 5 sections have content · 4 not rendered
Kumar
Jo Tan
Maya Hart
Pat Lee
Dan Kovac
02
Credentials & sessions
Every way to be you and every place you are
(_SectionCredentials,
_CredRow,
_SectionSessions): a credential row is a glyph
square, the provider and one mono line, with a
.kc-mini that is never disabled to stand in
for the server's check; a session row is a dot, the device and place, and
either current or a revoke, with one control to revoke every other
device.
GitHub
adding one asks you to sign in again first — the last one cannot be removed, and the check is a count in the same transaction, not the button
refusedthe last credential cannot be removed - it is the only way back in
donerevoked Chrome on Windows - 1 other session remaining
03
Role & the grant disagreement
The role section places the role panel and draws nothing of its own but one
paragraph (_SectionRole,
.kc-account__disagree): for the person whose
grant says one thing and whose site says another, both answers, and the
clock named as the thing between them.
The ninety days are a server-side check on every appendix request, not a badge this page is displaying. When it ends, this panel says so and the appendix stops answering - in that order, and without either of them consulting the other.
The grant says Pass; the site acts on Reader. They disagree because the expiry is checked at the point the capability is spent, not written into a column by a job that has not run. The panel above is describing the row, and the row is the thing that ended - the appendix stopped answering on the day it did, without either of them consulting the other.
04
Danger zone, export & delete
Leaving, in the order the docket insists on
(_SectionDanger,
_SectionExport,
_SectionDelete): the frame that says what goes,
the export with what it does not hold struck through, then the deletion card
— a ledger of what is deleted now beside what stays on the site, a
typed phrase matched on the server, and the action buttons
.kc-abtn--danger and
--ghost --sm. Export first, then delete.
Export everything, or delete this account
2 credentials, the profile, and everything on this page. Anything already published stays up, re-attributed. Two of the three actions here are irreversible and one of them takes published bylines with it.
Export everything
Everything the site holds about you, as one JSON document: 19 fields across three records — the account, its credentials and the profile. It is the recovery story for the deletion below, and it is the only one: there is no grace period and nothing is kept back.
and what is not in it, because it is not held at all
addressphoneemployerjob titlebirthdaygendercountryip history
it asks you to sign in again first — and the drafts SPEC 01 promises beside this document are not in it, because they belong to the Workshop and this surface cannot reach them
irreversibleDelete jo@example.com
Deleted now
2 credentials — github, google
3 sessions, signed out everywhere, immediately
Reading positions and series progress
Unpublished drafts, and their revisions
The profile: byline, avatar, bio, links
The Author grant — lapses in 20 days if unused
Stays on the site
Published posts , re-attributed to the site
Their URLs, their series positions, their inbound links
/blog/by/jo-tan — a 301 to the archive
Audit rows naming acct_01SPECJOTN, now unresolvable
The JSON export, if you took one — on your disk, not ours
4 of 6 rows in the left column are rendered by a section of this page · 2 are not, and carry no count: reading positions and series progress, unpublished drafts, and their revisions
Re-attribution is not anonymisation of the writing itself: a post that says “when I built this at Northbridge” still says it. Export first if you want a copy; the button is one control up, and it needs the same step-up as this does.
Inert until the text matches exactly, and the match is made on the server against the address on your account row rather than against anything this form carried. A step-up is asked for first, and it is asked for again if the last one is older than five minutes. Hard delete · no grace period · no recovery.
refusedthe confirmation did not match the address on this account
05
Settings & preferences
/settings, the one Account page built for
somebody signed out (_SettingsHead,
_SettingsGroup,
_PrefRow,
_SettingsPreview): six preferences in three
groups, one row each — label and reason left, control right — and
the control is segmented, not a chip row: one box, hairline dividers,
the current value filled solid ink, every option a submit button carrying its
own value.
Settings
How this site behaves for you.
Six choices about reading, and nothing about who you are. Nothing on this page can change what you are permitted to do — that is the rule that decides what is allowed to appear here, and it is why this page works signed out.
These six live in this browser. When this site gains a sign-in, the same six follow the account instead — so a choice made on a laptop is already made on a phone.
Appearance
Reading
What the choices do
The article column is one measure. Type size decides whether it is a comfortable one; density decides how tightly the lines sit inside it. Both take effect on this paragraph as soon as they are pressed.
PreferenceCatalog.TryFind(key, out var pref)
&& pref.Permits(value)
06
Sign-in card
One screen for both doors and no separate registration
(_SignInCard): kicker, title, the provider
doors, the rule, the email field and its ghost link button, the aside; then
what the server did, in the gate under the card, in a tone that is
not an error unless something failed.
Sign in.
Everything published stays readable without it. Signing in syncs your reading, and unlocks the Workshop if you have been invited.
We receive your account id and email — nothing else, no repositories, no contacts. Revoke it at your provider at any time.
Sign in.
Everything published stays readable without it. Signing in syncs your reading, and unlocks the Workshop if you have been invited.
We receive your account id and email — nothing else, no repositories, no contacts. Revoke it at your provider at any time.
Sign in.
Everything published stays readable without it. Signing in syncs your reading, and unlocks the Workshop if you have been invited.
We receive your account id and email — nothing else, no repositories, no contacts. Revoke it at your provider at any time.
07
Invitation card
The invited person's half of an invitation
(_InviteCard): a centred card naming who invited
whom, the role in the role panel's own pill, one button, and the note that
the grant arrives with the account. A refusal is a sentence, because
the link was good enough to reach the card.
Write the guest series on queues
Kumar invited lee@example.com to join as
Accepting creates the account with the grant already attached. Nothing to approve afterwards, and nothing to wait for.
Write the guest series on queues
Kumar invited lee@example.com to join as
This invitation is for lee@example.com, and you are signed in as somebody else. Sign out first, then open the link again.
08
Account switcher
The development door, a permanent feature of this app on one laptop
(_SwitcherCard,
_SwitcherRow,
_SwitcherPanes): a card of seeded people, each
row the monogram, the name and why they exist, the grant pill on the right;
the owner armed by one press and taken by a second; and the evidence panes
that show what the principal answers. The specimen emits no form:
on the real screen every row is a sign-in.
Development bypass
Who would you like to be?
Six viewers. Pick one and this browser is signed in as them, with a real session, until you sign out or it expires. There is no password because nobody is authenticating you — the account id is the whole assertion, and the only thing keeping that acceptable is that this door exists on one laptop and in no deployment.
-
The grant says Pass; the principal answers Reader. They disagree because the expiry is checked at the point the capability is spent, not written into a column by a job that has not run. Selecting this row gives you Reader — which is the whole reason this person is in the seed.
-
Nothing has changed yet. This is the owner — the one role here that no row can express and that no screen anywhere offers to grant. Press the row again to take it, or pick any other name to forget this.
POST /account/switch/leave · the real sign-out, all four steps
The four downstream reads
Everything downstream is supposed to read
ICurrentPrincipal and be unable to tell which source
filled it. Here are the four, with what each computes for you right
now. Change viewer above and read them again.
-
SiteNavigation.Build(IUrlHelper, app, section)does not read the principal yetWeb/Services/SiteNavigation.cs:70— appends a RailApp row per app this deployment has.6 rows, 3 of them mounts - the same answer for every viewerIt takes an app name and no viewer, deliberately: it runs on a page the edge caches.
-
AccessPolicies.Owner -> OwnerRequirementHandlerreads ICurrentPrincipalWeb/Filters/AccessPolicies.cs:126— decides whether this request may enter the Control Room.the requirement fails - every route under /control answers 404It reads the seam, so it cannot tell which source filled it.
-
WorkshopController.Move -> DraftStateMachine.Evaluatedoes not read the principal yetWeb/Areas/Workshop/Controllers/WorkshopController.cs:497— the actor a draft transition is judged as.TransitionActor.Author - hard-coded, for every callerThe defect SPEC 06 names rather than a principle it illustrates.
-
GET /api/session -> SessionCapabilitiesreads ICurrentPrincipalWeb/Areas/Workshop/Controllers/SessionController.cs:105— the three booleans the rail reveals its mounted rows from.workshop=false, control=false, identity=trueNull AccountId is the only null on a SiteViewer that means something: the Guest.
- consumers shown
4- reading ICurrentPrincipal
2- naming __Host-kc.session
0
Zero is the number that made the deletion cheap, and it was
collected on. Every consumer here reaches the viewer through
ICurrentPrincipal or SiteViewer, or does
not reach it at all — and both of those survived the bypass
being deleted untouched, which is exactly what BY4 measured. Two of
the four do not read the principal yet and each row says why; that is
the honest state of this estate rather than the docket's fixture, and
it does not weaken the zero. They cannot name a cookie whose name is
a file-scoped constant they are not permitted to see.
This counter is a summary and the COMPILER is the authority
now. It counts declarations on four rows. The real check used to
be a solution-wide search for the cookie name, run by somebody who
remembered to; SessionCookie.cs put the literal on a
file-scoped type instead, which turns the convention
into a build error. That is the one place this wave's arrangement is
strictly better than the one it restored.
What /api/session answers for you
Three booleans from three separate predicates — a stored grant that can lapse, a computation over configuration, and whether there is a session at all. They are what the spine rail reveals its rows from, and they are safe on a page a cache may hand to somebody else because they say what you may do rather than who you are.
- workshop
false- control
false- identity
true
What it deliberately does not carry
The viewer record the server resolved for this request. It is on this
page because this page is private, behind a gate that 404s, in a
process the public cannot reach, on a response marked
no-store. It is not on that endpoint for the same
reasons in reverse.
- accountId
acct_01SPECDAN0- display
Dan Kovac- role
Reader- expires
null- isBypass
false
isBypass is false here, and it is false
on purpose. This pane used to say the opposite: the bypass source
answered true even when it established nobody, and the
banner was driven by that flag. There is no bypass source now —
SessionPrincipalSource passes IsBypass: false
as a literal, with the comment “its one legitimate reader is
the banner that says a bypass answered, and a bypass did
not”. The session you are holding is a real one. The banner
above is driven by ISwitcherDoor instead, so it is on
whenever the door EXISTS rather than whenever somebody has chosen
— which is the property the old sentence was protecting, held by
a stronger mechanism.
Markup
As rendered on the page behind this — captured, not transcribed.