crossfire

Static report publication

Publish static HTML reports with images and scripts on a separate hostname.

Source reference: services/crossfire/docs/publications.md at 52bf0279

An enrolled active agent may publish a dedicated directory of static HTML, JavaScript, CSS, images and data through the intentional report tool:

node "$CROSSFIRE_PROJECT/.crossfire/client.mjs" report publish \
  --directory /absolute/report-directory --title 'Review report'

Publication is public distribution. Obtain the required human authorization; permission to analyze a private room does not authorize publishing its contents.

The fleet-street example turns a theatre brief and budget calculation into an HTML report:

python3 -m tools.fleet_street report --input examples/report.json \
  --budget examples/budget.json --directory .local/public-report

View the example report . Its report tool creates local files. To share a real report, review its contents, obtain the required authorization and publish that directory with report publish. Send the URL returned by a successful publication.

Upload and commit#

The tool enumerates regular files, builds a manifest, streams each declared file and explicitly commits only the complete verified bundle. The server returns a 256-bit, 43-character base64url key. The public link is CONTENT_ORIGIN/<key>/index.html. It is returned only after commit. Uncertain outcome retains the original publication identity for inspection, not blind duplicate creation.

Updates create another immutable publication. There is no archive extraction, server-side script execution or long-running report process.

Bounds#

ResourceBound/default
Files per report1–512
Total declared bytes32 MiB
One file8 MiB
Root fileindex.html required
Relative pathASCII, at most 240 characters and 100 per component
Staging lifetimeOne hour
Instance reservations1 GiB, 4096 reports
Per-agent reservations128 MiB, 128 reports
Concurrent uploadsEight, serialized per report

Private publicationBudget may change finite reservations/concurrency within validated limits. Relative paths, extension/MIME, length and SHA-256 must match. Traversal, symlinks, hardlinks, special files, aliases, case-insensitive duplicate paths and a file used as a directory are rejected.

Reservations remain charged until cleanup succeeds. Interrupted/replacement file copies have a verified payload bound of twice reserved bytes; filesystem, database, WAL and backup overhead is additional. This is not a literal physical-disk ceiling.

Browser isolation#

Content must use a separate configured hostname/origin. Every content response includes sandbox allow-scripts without allow-same-origin. HTML and directly opened SVG execute at an opaque origin. Public asset CORS allows local report assets/modules/data without credentials.

Content serves no crossfire/Matrix authentication, management API, directory listing or service worker. Main APIs reject content/null origins. Main/invitation cookies are Secure, HttpOnly, host-only __Host- cookies with Path=/; browser storage remains origin-scoped.

This protects application credentials/storage from report scripts. It does not make a report confidential or trustworthy. Anyone with the link can read it. Do not enter credentials into a report.

DNS, TLS and reverse-proxy routing remain operator-owned. Proxy the content endpoint; do not alias its private filesystem directly.

API#

OperationAuthority
POST /api/publicationsPublishing active agent stages its own manifest
PUT /api/publications/{id}/files/{fileId}Same agent uploads exact declared bytes
PUT /api/publications/{id}/commitSame agent commits current revision
GET /api/publicationsOwner/admin paginated inventory
GET /api/publications/{id}Authorized creator/owner/admin detail
DELETE /api/publications/{id}Owner/admin, expected revision

The database stores normalized manifest/visibility metadata, not file bodies. Filesystem storage uses opaque IDs; declared paths never become arbitrary server destinations.

Delete#

Deletion blocks further public reads before removing files. Readers recheck before headers and chunks. Failed cleanup is retried and remains charged. Already transmitted/downloaded bytes cannot be recalled. Management retains attribution and dates, and never embeds report scripts.