# Publishing to your name Every page Sirius Press serves can also exist as a static file in your name's storage, signed by the key that owns the name. This is what makes the site outlive its server. --- ## What gets published, and when Publishing or editing a post queues the pages it affects: - the post itself - the home page - the blog page, if you have one - every category, tag or other public archive it belongs to - any asset those pages reference — stylesheets, scripts, images — the first time it is seen Unpublishing or deleting a post removes its file and re-queues the pages that linked to it. A static mirror that keeps serving a post the author deleted is worse than no mirror at all, because the author believes it is gone. **Export everything** on the Publishing screen queues the whole site: every published post and page, every public archive, the home page. Password-protected posts are never exported. To the exporter they render as a password form, and publishing that form to permanent public storage would be a strange thing to do on purpose. --- ## Who signs, and where the key lives The BNS gateway only accepts a write signed by the name's **current on-chain owner**. That is the whole security model, and it has a consequence there is no way around: whatever signs your uploads holds the key that owns your name and whatever funds sit with it. There is no weaker credential to give a server. So the question is not *how much* of your key the server gets. It is whether it gets it at all. ### Manual — the default Nothing is stored. Exports queue up; when you open **Sirius Press → Publishing** you type your recovery phrase, and the page signs each file and uploads it straight from your browser to the gateway. The phrase is cleared from the form as soon as it has been used and the derived key is wiped when the run ends. - Nothing sensitive on the server. A compromised host leaks your posts, which were public anyway. - A post published on a schedule sits in the queue until somebody signs in. ### Automatic Your recovery phrase is encrypted with AES-256-GCM under a key derived from `SIRIUS_PRESS_KEY` in `wp-config.php`, and stored in the database. Cron drains the queue by itself. - Scheduled posts publish while you sleep. - Anyone who can read **both** your database and `wp-config.php` has your name and your coins. That is most people who get a shell on the box. The encryption protects one specific thing — a stolen database dump, a leaked backup — and the settings screen says exactly that rather than implying more. **A reasonable middle path:** run automatic mode with a wallet that holds the name and nothing else. Keep your coins somewhere that has never been typed into a web server. This does not protect the name, but it bounds what a compromise costs to "the attacker can publish to my name until I move it", which is recoverable. --- ## Derivation paths Sirius Press derives its publishing key at `m/44'/145'/0'/0/0` — BCH coin type, first account, first address. Same as the Sirius portal wallet, same as most BCH wallets. If your name was bought with a wallet minted somewhere else, the path may differ. The symptom is unmistakable once you know it: every upload returns 403, and **Sirius Press → Settings** shows two different addresses side by side — the one your phrase derives, and the one the chain says owns the name. Change the path in Settings. Operator wallets created from the Silent Mode CLI were derived on the BTC coin type, `m/44'/0'/0'/0/0`. The settings screen checks this for you as soon as you save a phrase: it derives the address, asks the gateway who owns the name, and tells you whether they match. A mismatch caught there is a sentence of explanation. The same mismatch caught later is a 403 in a cron log nobody reads. --- ## The queue Rows are keyed by path, not by post — several posts changing in a minute should not queue the home page five times. Each attempt renders the page, hashes the result, and compares it to what was last published at that path. Identical bytes are marked done without an upload, which is the common case: a WordPress page re-renders byte-for-byte far more often than it changes. Failures retry up to five times and then stop, and the first exhausted retry puts a message in your inbox — once an hour at most, because a misconfigured key fails on every row and four hundred identical messages are the same as none. ### From the command line ```bash wp sirius status # name, key, owner, queue depth wp sirius export --all # queue everything, then push it wp sirius export --limit=50 # work through part of the queue wp sirius export --all --dry-run # build every page, upload nothing ``` `--dry-run` is the fastest way to find a page that renders badly for the exporter without publishing anything. The first full export of an existing site is the one job genuinely better in a terminal: thousands of pages, a long run, and no browser tab that must stay open. Note that CLI publishing needs automatic mode, since there is no browser to sign in manual mode. --- ## What the exported pages look like Pages are fetched over a loopback HTTP request, not rendered in-process. That costs a round trip and is worth it: a theme's output depends on the whole request lifecycle, and reconstructing it by calling `get_the_content()` gives you something that resembles the page rather than the page. Links are rewritten to be **document-relative** — `../../about/index.html` rather than `/about/index.html` or an absolute URL. Absolute links would drag readers back to the origin server the export exists to make optional. Root-relative ones break when the same bucket is browsed under `/bns//` on the public gateway. Document-relative works in both places. Asset URLs lose their `?ver=` query, because the bucket stores one copy of each file and the query would only ever produce a 404. ### Things that cannot work in a static copy Anything needing PHP at read time: the search form, the comment form, a cart, a "related posts" widget that queries at render. They will appear and do nothing. If your theme has such a thing, hide it during export: ```php add_action( 'sirius_press_rendering_export', function () { add_filter( 'get_search_form', '__return_empty_string' ); remove_action( 'wp_footer', 'my_theme_live_widget' ); } ); ``` That action fires on the live request, while the exporter is fetching — which is the right moment, because removing something afterwards means also unpicking the styles and spacing it left behind. --- ## Hooks ```php // Skip a post entirely. add_filter( 'sirius_press_should_export_post', function ( $export, $post ) { return 'private-type' === $post->post_type ? false : $export; }, 10, 2 ); // Add to, or trim, what a full export covers. add_filter( 'sirius_press_export_targets', function ( $targets ) { $targets['feed/index.xml'] = array( 'url' => home_url( '/feed/' ), 'kind' => 'feed' ); return $targets; } ); // Change which paths a post edit invalidates. add_filter( 'sirius_press_affected_paths', function ( $paths, $post ) { … }, 10, 2 ); // React to a successful upload. add_action( 'sirius_press_exported', function ( $path, $bytes ) { … }, 10, 2 ); ```