Commit graph

314 commits

Author SHA1 Message Date
81344da09a
fix: PDF body fills page width (override pandoc CSS max-width)
Pandoc's --standalone HTML5 template applies max-width: 36em + margin: 0
auto + padding: 50px to body, centering content in a narrow column on
any page size. With wkhtmltopdf at 15mm page margins, effective content
margins were measuring ~55mm because pandoc's CSS added ~40mm of inner
padding on top.

Inject a header-includes <style> block that strips body's max-width,
margin, and padding so content fills the page minus wkhtmltopdf's own
page margins. Measured: 55mm → 15mm left margin.
2026-04-26 15:55:55 -04:00
d7fa7d1b93
feat: tighter PDF margins + shorter QR caption
wkhtmltopdf default top margin is ~25mm — leaves a half-page of empty
space above the provenance header on every PDF. Set explicit 12mm
top/bottom and 15mm left/right via pandoc -V margin-* options.

Shorten QR caption from 'Scan to visit the living source' (six words,
wrapped onto four lines in the 160px cell) to 'Scan for living source'
(four words). Widen the QR cell from 160px to 200px so the caption
sits on one or two lines without crowding the QR.
2026-04-26 15:16:47 -04:00
63a5a939c0
ci: retry pipeline (245c5c7 test stage failed flakily)
Local pytest run shows 584 pass on the same code; previous CI test
job hit a transient failure. Retry to validate the auto-restart fix in
foxhop-states 591cb4f end-to-end through CI.
2026-04-26 15:03:38 -04:00
245c5c7d8c
ci: rebuild to test foxhop-states 591cb4f auto-restart in caddy_sites
Empty commit triggers a salt highstate so the new auto-restart cmd.run
in uwsgi.caddy_sites lands and (assuming akuma's clone of foxhop-states
has been pulled to 591cb4f) fires the catch-up restart of foxhop.net
and westworld2.com onto whatever commit hash this build produces.
2026-04-26 10:39:25 -04:00
b35c136f7f
feat: side-by-side provenance header (text left, QR right)
Wraps the provenance header in an HTML table so the source/snapshot/
generator block sits left and the QR sits right at the same horizontal
level. Pandoc converts the table cleanly into native table cells across
HTML, PDF (wkhtmltopdf), DOCX, ODT, EPUB.

Without a QR (qr_data_uri=None) we fall back to the plain blockquote.
2026-04-25 16:26:21 -04:00
37350324ea
ci: rebuild to pick up foxhop-states ce4edcc
Triggers a salt highstate so the content-based skip_deploy auto-restart
state lands on origin and finally drives the catch-up restart of
westworld2 (:6002) and foxhop.net (:6003) onto the current commit.
2026-04-25 13:39:58 -04:00
38475eceeb
feat: provenance + QR codes on every export
Every exported document (PDF, EPUB, DOCX, HTML, markdown, plain, ...)
now points back to its living source on Remarkbox so a printed snapshot
remains traceable years later.

What's injected:
  - Top banner: source URI, snapshot ISO timestamp, generator commit hash,
    plus a notice the document is a snapshot of a living source.
  - QR code (PNG, embedded as data URI) linking back to the canonical URI.
    Scannable from print, survives the pandoc image pipeline across
    HTML, PDF (via wkhtmltopdf), DOCX, EPUB, ODT.
  - Per-reply permalinks: each reply heading hyperlinks its date to the
    deep-link permalink (thread-uri#node-id), academic-citation style.
  - Footer repeating the source URI + commit hash.
  - Namespace exports also hyperlink each chapter title to the live
    thread.

Canonical URI = https://{namespace.name}{node.path} — namespace name is
its host on the public web.

New module: remarkbox/lib/provenance.py — header_md, footer_md,
reply_heading_md, qr_png_data_uri, canonical_uri helpers, and a one-shot
build() bundler.

Dep added: segno (pure-Python QR generator, BSD, zero deps).
2026-04-25 06:14:39 -04:00
9e22c0d768
fix: always-visible export menu + wiki history rev creation
Export menu: dropped the details/summary toggle so format options are
visible at all times; added flex layout with gap for breathing room.

Wiki history: the browser edit form path was calling node.edit() instead
of node.wiki_edit() so revisions were never recorded — /api/v1/nodes/.../revisions
returned empty after every edit. Also tightened the access gate to
can_wiki_edit so non-owner authenticated users can edit wiki-mode root
nodes through the UI (matching the gate already used by the edit-button
macro).
2026-04-25 06:14:27 -04:00
dded1622e8 fix: export markdown from data_html, not data+source_format
Observed defect: a node's source_format column can disagree with the
actual bytes in data. A Collatz thread on foxhop.net has data filled
with RST (======, ---, :: blocks) yet source_format="markdown". The
earlier helper trusted source_format and returned the RST untouched,
so GET /api/v1/export/.../thread.md served raw RST to anyone who asked
for markdown.

data_html is the canonical rendered form — set at every write via
set_data() regardless of input syntax — so converting data_html → markdown
via pandoc sidesteps the label mismatch entirely. Falls back to raw
data if data_html is missing or pandoc fails.
2026-04-24 15:09:31 -04:00
f5e453d6ba ci: rebuild to exercise foxhop-states 04ad310 auto-restart rule 2026-04-24 14:55:08 -04:00
8b6dac4dd7 fix: stop tripling thread titles in exports; convert non-markdown node data
Three fixes to thread/namespace export:

1. Nodes authored in non-markdown source_format (rst, mediawiki, latex, ...)
   had their raw source dumped directly into the markdown renderer. A RST
   thread exported as .md therefore yielded RST, not markdown. New
   _node_data_as_markdown helper converts node.data through pandoc when
   source_format != markdown, with a raw-source fallback on pandoc failure.

2. node_tree_to_markdown prepended '# {root_node.title}' on top of data
   that already carries its own H1 (either native markdown or a converted
   RST underline heading). Drop the prepend — the data owns the title.

3. convert() passed --metadata title=X which makes pandoc render a visible
   title-block in HTML/PDF above the body. Combined with (2) and the data's
   own H1 this showed the title three times in exported HTML/PDF. For
   html-family outputs (and pdf via wkhtmltopdf) switch to -V pagetitle=X
   so only the <title> tag gets populated; other formats still use the
   proper --metadata title=X for real document metadata.
2026-04-24 14:38:26 -04:00
2fd71e9029 feat: map user-facing file extensions to pandoc format names in export URIs
Users hitting /api/v1/export/threads/{id}.md got 'Unsupported format: md'
because pandoc's internal name is 'markdown'. Add EXTENSION_ALIASES +
resolve_format() so common extensions map to the right pandoc format:
  .md    -> markdown
  .html  -> html5
  .tex   -> latex
  .txt   -> plain
  .epub  -> epub3
  .wiki  -> mediawiki
  .adoc  -> asciidoc
  ...
Pandoc's own format names pass through unchanged (commonmark_x, docbook5,
fb2, etc.) via fallback.
2026-04-24 12:53:53 -04:00
586f2366df ci: rebuild to pull remarkbox-theme-chaostheory fed3eea (call_to_action in wikibar-right) 2026-04-24 07:47:29 -04:00
1bf5111638 ci: rebuild to pull remarkbox-theme-chaostheory df04c0d (call_to_action block fix) 2026-04-23 19:17:51 -04:00
9db2407395 feat: wiki revision history — HTML tabs, diff view, export links
- New route /{node_id}/revisions rendered by revision-history.j2
- Show content/history tabs on wiki root nodes
- Export dropdown includes history (json + html) links on wiki namespaces
- Node action buttons now gate on can_wiki_edit (not can_alter_node)
  so wiki-mode members can edit their own root nodes
- Suppress Topic link when URI matches current domain (self-reference)
- Tests covering revision timestamps, wiki_edit(), can_wiki_edit(),
  /revisions endpoints, CSRF trusted origins, export menu gating,
  pandoc rst→html rendering
2026-04-22 11:37:06 -04:00
a5c3e36fce fix: Namespace.moderators returned all members; owners now imply mod
moderators property returned self.enabled_users (every enabled member),
so every user who had ever posted got moderator powers: spam
approve/deny, edit/delete other users' comments, moderator Slack
notifications. Bug was universal across all namespaces — any site where
users post was affected.

Fix: moderators now returns only users with role='moderator'.
Owners now implicitly pass is_moderator() checks, since NamespaceUser
is single-role per user per namespace; this keeps owners functional
without needing a data migration.
2026-04-21 19:59:40 -04:00
e1952cb1c4 ci: fix chaostheory requirement name (pip distribution is remarkbox-chaostheory) 2026-04-21 18:31:49 -04:00
ddbcdfa094 ci: install and bundle remarkbox-theme-chaostheory
Adds chaostheory theme to the shared env.tar.gz build so foxhop.net
(which sets app.theme = chaostheory and shares /opt/remarkbox/env with
my.remarkbox.com) has the theme's templates + static assets available
after deploy.
2026-04-21 18:27:49 -04:00
68ca0ef6e7 feat: foxhop.net support — /attachment/ static view, pandoc standalone fix, figure/figcaption tags, avatar null guard, html5lib body fragment, chaostheory palette in common.css 2026-04-08 15:05:22 -04:00
176be89319 docs: use make migration — never hand-write revision IDs 2026-04-06 14:23:16 -04:00
604c8407ee style: avoid "the", use "our" — writing style rule + sweep 2026-03-31 13:20:22 -04:00
f3815eb0ce fix: CWE-407 content length cap on browser form paths; tighten bleach pin; add tests
- views/__init__.py: add MAX_CONTENT_LENGTH = 500_000 (shared constant with comment
  explaining the CWE-407 / bleach ReDoS rationale)
- reply_node.py: reject oversized content before set_data() / clean_raw_html()
- modify_node.py: same guard on edit path
- new_thread.py: same guard on new thread path
- requirements.py3.txt: tighten bleach>=2.1.4 -> bleach>=6.0.0 with CVE note
- test_render.py: unit tests for bleach version contract, API stability,
  sanitization correctness, and ReDoS resistance timing
- test_views.py: functional tests for content length enforcement on all three
  browser form paths (reply, new thread)
2026-03-30 09:27:59 -04:00
d37c60481d docs: CWE-407 audit — bleach sanitization pipeline and build tools 2026-03-30 08:25:27 -04:00
67483f2b98 ops: operation voyeur — credential opsec protocol 2026-03-29 15:46:07 -04:00
b51cf4574d chore: trigger CI to pull updated meta theme 2026-03-29 09:47:07 -04:00
06d70b9e92 docs: never access credentials without explicit instruction 2026-03-28 15:44:13 -04:00
c87fb0bd1f fix: cap search keywords and query results to prevent CWE-407 amplification
- list_nodes.py: strip empty tokens, cap keywords to 10 before passing to model
- node.py: add .limit(200) per keyword query — was unbounded .all()
- namespace.py: add .limit(500) on root.children in dict_dump — was unbounded iteration
- __init__.py: cap page_number to 1000 — large offsets force full table scans
2026-03-28 15:12:39 -04:00
2061097e13 Skip PDF tests when wkhtmltopdf unavailable (fixes CI). 2026-03-10 11:22:01 -04:00
46bdf3a217 Add revision diff endpoint and progressive enhancement export/wiki UI.
Diff: GET /api/v1/revisions/{id}/diff/{other_id} — unified diff between two revisions.
UI: <details>-based export menus on thread and node views (works without JS).
UI: Revision history link for wiki-mode namespaces.
2026-03-10 11:13:39 -04:00
75bec564b2 Replace ASCII diagrams with Graphviz DOT in architecture and ticket docs. 2026-03-10 09:29:36 -04:00
b63277e4d1 Update docs for Operation Undigg: API reference, testing guide, architecture diagram. 2026-03-10 09:07:32 -04:00
6d1cfff91d Operation Undigg: multi-syntax input, pandoc export, wiki mode, auto-themes.
Phase 1: Pandoc export pipeline — 67 output formats for threads, namespaces, nodes.
Phase 2: Multi-syntax input — accept markdown, HTML, RST, MediaWiki, LaTeX, etc.
Phase 3: Wiki mode — per-namespace toggle, revision tracking, wiki-edit endpoint.
Phase 4: Auto-generated themes — deterministic CSS per namespace, light + dark mode.

Includes unit, integration, and functional tests (95 new, 544 total).
2026-03-10 00:35:51 -04:00
f45c42d343 modified: remarkbox/__init__.py
modified:   requirements.py3.txt
2026-03-09 19:50:36 -04:00
5bcd7df585 Document proxy architecture and domain routing in CLAUDE.md.
Maps which domains go through the edge proxy (142.93.73.64) vs direct to
origin (162.243.167.224). Prevents repeat of the 5-day meta/faq SSL outage
caused by missing proxy blocks.
2026-03-02 15:51:56 -05:00
a57187672c Update postmortem with actual root cause and add T14.
The 5-day meta/faq SSL outage was caused by missing proxy blocks in
proxy.unturf.com, not a Caddy cold-start issue. Fixed in proxy commit f12a56d.
2026-03-02 15:22:39 -05:00
4287aeee2c Add postmortem for 2026-02-25 SSL/TLS outage on meta and faq subdomains. 2026-02-26 07:06:48 -05:00
2d64d79b80 Trigger salt highstate: migrate from nginx to caddy 2026-02-13 13:51:40 -05:00
fa6b3aab73 Prevent long inline code from blowing out page width on mobile. 2026-02-09 09:44:38 -05:00
165aea2ca3 Document related repos and footer duplication in CLAUDE.md. 2026-02-09 07:32:10 -05:00
12f8364a61 Redeploy to pick up meta theme footer fix 2026-02-09 07:11:53 -05:00
7c85b6e77e Document theme system and deployment workflow in CLAUDE.md 2026-02-08 15:46:51 -05:00
f5c09d873e Pin setuptools<81 — version 82 removed pkg_resources
Pyramid imports pkg_resources which was removed in setuptools 82.
Pin across requirements, Makefile, and CI scripts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 12:19:33 -05:00
37bffe29aa Install setuptools directly in CI scripts before make targets
Belt-and-suspenders: ensure setuptools is in the cached venv
before any Make target runs. Shell executor preserves env/
between builds but Python 3.12+ venvs lack setuptools.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 12:16:01 -05:00
a2e574d6b9 Install setuptools before editable install, not just in venv target
The venv target is a no-op on cached CI runners where env/bin/activate
already exists. Move setuptools install into install-source-dev-and-test
and install-source-prod so it runs every time, regardless of venv cache.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 12:11:09 -05:00
568e8757fe Bump version to 1.0.6
Forces pip to re-resolve dependencies on cached CI venvs,
pulling in setuptools.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 12:04:27 -05:00
ef4d6da410 Install setuptools in venv creation step for Python 3.12+
The requirements.py3.txt change alone wasn't enough — pip treats
setuptools specially during editable installs and may not install
it as a runtime dependency. Installing it immediately after venv
creation ensures pkg_resources is available for Pyramid and theme
loading.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 12:03:44 -05:00
8d64fa11e4 Add setuptools to requirements for Python 3.12+ compatibility
pkg_resources (used for theme entry point loading) lives in
setuptools, which Python 3.12+ no longer bundles in venvs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 11:57:26 -05:00
7575f74837 Add C SDK (rb.h + rb.c) with API download endpoint and namespace settings links. 2026-02-08 11:11:54 -05:00
f661938820 AJAX progressive enhancement for all action buttons.
Lock/unlock, watch/unwatch, disable/enable, verify, approve/deny
now return JSON for XHR requests and swap client-side without a
page reload. Falls back to normal POST + redirect when JS is off.
2026-02-08 08:38:27 -05:00
637f5a7073 Respect preview visibility preference on AJAX-inserted nodes. 2026-02-08 08:27:37 -05:00