SOLED/2 — The Soledade Publishing Protocol
Technical-narrative document | soledade.city | port 1915
SOLED/2
The Soledade publishing protocol
Plain text over TCP for citizenship, Markdown, and editorial autonomy
Executive summary
SOLED/2 is a plain-text application protocol that runs over TCP on port 1915. It was created so that citizens of Soledade can register an identity, publish Markdown, validate drafts, list their files, delete content, and recover access without depending on a web dashboard, REST API, WordPress, or a relational database.
This document presents SOLED/2 as a deliberate architectural component: simple enough to fit inside a terminal, strict enough to preserve operational safety, and symbolic enough to turn remote publishing into an act of citizenship inside soledade.city.
1. What SOLED/2 is
SOLED/2 is the official write contract between simple clients — such as ncat, automation scripts, and terminals — and the soledade.post_server server.
It does not try to be an IETF standard. It is not a public RFC. It does not compete with HTTP. Its role is narrower and more honest: it transports commands and Markdown into Soledade's content/ tree, where the static site is rebuilt after validation.
The name SOLED comes from Soledade. The /2 suffix marks the second generation of the posting protocol. Before it, there was only the legacy mode: an administrative token, a file path, and a body terminated by a single dot. That worked, but only for a city governed by one key.
2. Why it was created
The original problem was simple: publish remotely without a web dashboard.
For a single administrator, a secret token was enough. But Soledade stopped being a personal blog and started adopting a more ambitious metaphor: a textual city with citizens, houses, districts, documents, and rules of coexistence.
In that new scenario, a single shared token became both a bottleneck and a risk. It does not separate authorship. It does not create individual identity. It does not provide a solid basis for moderation. Worst of all, it turns every authorized client into something too powerful.
Bluntly: a shared secret is acceptable for personal automation; it is bad architecture for a community.
SOLED/2 was created to solve that scaling problem without betraying the philosophy of the project. The answer was not to add a dashboard, a heavy web stack, or a JSON API. The answer was to design a small, textual, explicit protocol in which each operation says who is speaking, what they want to do, and which file they are acting on.
3. The real need: citizenship, not just login
The protocol had to solve something larger than authentication. It had to allow entry into Soledade's citizenship model.
That means allowing a person to:
- register a handle;
- receive a secret identity;
- write only inside their own file territory;
- validate drafts before publication;
- list their own Markdown files;
- delete authorized content;
- recover access if their identity is lost.
The choice of plain text is part of the need itself. Anyone with ncat can understand, assemble, and send a request. The packet is readable. The error is readable. The response is readable. That reduces dependence on SDKs, libraries, or official clients. The city accepts humble tools.
But simplicity is not naivety. SOLED/2 defines boundaries: allowed paths, citizen status, maximum payload size, preview without writing, recovery with invalidation of the previous identity, IP-based rate limiting, and synchronized build execution to keep the site coherent.
4. Design principles
| Principle | Practical consequence |
|---|---|
| Terminal first | The protocol must be usable by a person in a shell, without a browser or a special client. |
| Text before abstraction | Headers and responses are readable lines, not mandatory JSON or opaque binary. |
| One connection, one operation | Each TCP packet represents a clear intention: register, publish, list, preview, or recover. |
| Symbolic civil identity | CITIZEN and IDENTITY are not merely username and password; they are how the city recognizes an inhabitant. |
| Disk as the editorial source of truth | The protocol does not serve HTML; it changes Markdown in content/ and triggers the static build. |
| Pragmatic compatibility | Legacy mode remains available for older administrative automation. |
5. How the protocol works
Every SOLED/2 message begins with a fixed first line:
SOLED/2
That line is the boundary between the second-generation parser and the legacy parser. If the first line is not SOLED/2, the server interprets the packet as legacy mode.
After that, headers follow the format:
KEY value
A blank line ends the headers and, when applicable, begins the Markdown body. The packet ends with a line containing only a single dot:
.
This convention makes the protocol easy to transmit manually from a terminal and easy to parse on the server.
Example preview request:
SOLED/2
ACTION PREVIEW
CITIZEN maria
IDENTITY <citizen-secret>
PATH citizens/maria/posts/note.md
---
title: "Note"
district: centro
---
Markdown publication text.
.
The operation above validates a draft without writing it to disk. Replacing ACTION PREVIEW with a normal publication action — or omitting ACTION when publication is treated as the default — changes the intention: the Markdown becomes a candidate for real writing into content/.
6. Main actions
| Action | Purpose | Controlled risk |
|---|---|---|
REGISTER |
Creates citizenship, handle, identity, and recovery code. The server stores only the identity hash. | Unauthorized entry through reserved or duplicate handles. |
| Publish | Writes or updates an authorized Markdown file inside the citizen's tree. | Writing outside the citizen's territory or sending invalid front matter. |
PREVIEW |
Runs full validation without altering the disk. It is the rehearsal before publication. | Accidentally publishing broken content. |
LIST |
Lists Markdown files inside the citizen's permitted territory. | Leaking file structure outside the citizen's scope. |
RECOVER |
Uses the recovery code to issue a new identity and invalidate the old one. | Permanent loss of access. |
DELETE |
As a special body, removes an authorized Markdown file. | Unauthorized deletion. |
7. Citizenship registration
Registration is the symbolic gate of the city. The client sends ACTION REGISTER, a HANDLE, and optionally a name. The server decides whether the handle is valid, whether it is reserved, and whether it has already been taken.
On success, the server responds with a secret identity and a recovery code.
SOLED/2
ACTION REGISTER
HANDLE maria
NAME Maria Silva
.
The response includes IDENTITY and RECOVERY. The identity should be stored locally. The recovery code should be treated as an emergency document.
The server does not store the identity in clear text. It stores a hash and compares future proofs against that hash.
8. Publishing Markdown
To publish, the citizen provides CITIZEN, IDENTITY, and PATH.
The PATH is not arbitrary. It must remain inside the permitted space, usually something like:
citizens/<handle>/
Validation blocks directory escapes, forbidden paths, oversized payloads, nonexistent districts, and inconsistent front matter.
When everything passes, the server writes the file into content/ and runs the site build. The final visitor does not talk to SOLED/2. They see HTML served later over HTTPS from the regenerated public folder.
Example publication:
SOLED/2
CITIZEN maria
IDENTITY <citizen-secret>
PATH citizens/maria/posts/first-post.md
---
title: "My first post"
district: centro
---
This is a publication sent directly from the terminal.
.
9. Preview: the brake that prevents disaster
PREVIEW exists because direct publishing to production is too powerful to be blind.
It runs validation, reports warnings or errors, and writes nothing. In practice, it is the safe mode for scripts, assistants, and humans to check whether a packet is publishable before touching the disk.
This action also separates transport from editorial judgment. The protocol carries the file; the validation layer decides whether that file respects the city's model.
10. Identity recovery
RECOVER solves an unavoidable failure in simple systems: people lose secrets.
Instead of relying on email, passwords, OAuth, or an administrative dashboard, Soledade issues a recovery code during registration. Whoever holds that code can request a new identity. The previous identity stops working.
This keeps the design coherent: the city remains textual, the terminal remains sufficient, and the server does not need to store a reversible password.
11. Operational security
SOLED/2 is not transport encryption. If port 1915 is exposed, the operation needs appropriate external protection: firewall rules, an SSH tunnel, IP policy, or an explicit decision to make the port public.
The protocol authenticates identity at the application level. It does not promise connection secrecy by itself.
Operational safeguards include:
- IP-based rate limiting to contain registration and publishing spam;
- citizen status such as
active,suspended, orbanned; - blocking dangerous paths, including attempts to escape
content/; - build locking to avoid regeneration races;
- logs containing protocol, citizen, action, and IP for basic auditing;
- preservation of legacy mode without mixing administrative privilege with ordinary citizenship.
12. Relationship with legacy mode
The first generation does not disappear. It remains available on the same port as legacy mode, identified by the absence of the SOLED/2 first line.
Its format is direct:
<path>
<administrative-token>
<body>
.
This preserves older scripts and allows mayor-level operations without forcing immediate migration.
But legacy mode is not citizenship. It is administration. That distinction matters: SOLED/2 was born for many authors with their own scope; legacy mode exists for centralized trusted automation.
13. What SOLED/2 is not
SOLED/2 is not:
- REST, JSON-RPC, or GraphQL;
- a universal standard;
- a replacement for Git;
- an HTML-serving protocol;
- the read protocol on port 1900;
- a substitute for firewall policy, exposure decisions, or operational hygiene.
It is the official write protocol of Soledade.
14. Why this choice makes sense
The choice behind SOLED/2 is stubbornly simple, and that is its virtue.
For a project like Soledade, adopting a conventional web stack would solve publishing, but it would erase part of the system's identity. The protocol makes the form match the content: a textual city, governed by files, accessible through a terminal, and understandable by direct reading.
The gain is not only technical. It is cultural.
Publishing stops being a click inside an invisible form and becomes the act of sending a formal letter to the city. The server reads it, validates it, records it, and rebuilds the public showcase. That minimal friction creates ritual without becoming bureaucracy.
In short: SOLED/2 exists because Soledade needed to grow from blog to city without losing its plain-text soul.
15. Quick specification
| Item | Value |
|---|---|
| Transport | TCP |
| Default port | 1915 |
| Encoding | UTF-8 |
| First line | SOLED/2 |
| Header format | KEY value |
| Separator | Blank line between headers and body |
| Packet terminator | A line containing only . |
| Editorial unit | Markdown file inside content/ |
| Canonical implementation | soledade/post_server.py |
| Citizenship state | data/citizens.json with identity hashes |
16. One-sentence pitch
I created SOLED/2 so that Soledade could publish Markdown through port 1915 as a textual city: each person registers a handle, receives a secret identity, sends terminal-readable packets, and the server validates, writes, and rebuilds the site without WordPress, without a web dashboard, and without abandoning the simplicity of TCP.
17. Future evolution
If SOLED/3 ever exists, the correct path is to preserve predictability: a new first line, temporary compatibility with SOLED/2, updated documentation, new tests, and old responses preserved whenever possible.
A protocol change without a clear contract is just a bug with marketing.
Until then, SOLED/2 can evolve through new ACTIONs and optional headers, as long as it does not break existing clients or change the meaning of fundamental responses.
Appendix A — Mental model of the flow
ncat/script client
|
| TCP :1915, UTF-8, packet terminated by dot
v
soledade.post_server
|
|-- first line == SOLED/2 -> SOLED/2 parser
| |-- REGISTER / RECOVER -> citizens and identity
| |-- LIST -> permitted files
| |-- PREVIEW -> validation without writing
| `-- publication -> validation, writing, and build
|
`-- otherwise -> legacy parser with administrative token
content/*.md -> build_site() -> public/*.html -> Caddy/HTTPS
Appendix B — Common errors
| Response | Meaning |
|---|---|
400 bad request |
Malformed message or missing required header. |
401 invalid identity |
Handle and identity do not match. |
401 invalid recovery |
Invalid recovery code. |
403 forbidden |
Operation not allowed for that citizen or path. |
403 handle reserved |
Handle reserved for the system or mayor. |
409 handle taken |
Handle already registered. |
413 payload too large |
Packet exceeds the allowed limit. |
429 rate limited |
Too many operations in a short interval. |
Final note
SOLED/2 is intentionally small. Its purpose is not to impress through complexity, but to create a clear, auditable contract that fits Soledade's technical aesthetic.
Member discussion