From 9ddf51712838c152d892d9dcd2e1a678db01ca1d Mon Sep 17 00:00:00 2001 From: lashman Date: Thu, 20 Aug 2026 12:41:00 +0300 Subject: [PATCH] install notes for the published image --- README.md | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 187 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 79bc981..57c5b16 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,197 @@ -# cruciverb +
-Crossword puzzles with a handwriting-first twist: daily grids in five difficulty presets, a community clue pool, and ActivityPub federation between instances. +# βœ’οΈ Cruciverb -## Features +**Daily crosswords that respect you - and your handwriting.** -- Daily puzzles generated with seeds so every solver gets the same grid and clues -- Handwriting and stylus input recognized through ONNX and the browser handwriting api, with tesseract as a fallback -- Puzzle editor, clue trainer, multiplayer rooms, and party games -- Receipts and federation: instances follow each other and exchange clue submissions and puzzles +Handwriting-first grids, a community clue pool, and federation +between self-hosted instances. No ads. No tracking. No accounts required. -## Layout +
-- cruciverb-core: the generator (grid construction, fill, exports) -- cruciverb-server: the axum api, sqlite storage, and activitypub plumbing -- cruciverb-cli: command line generation -- frontend: the vite and react client +![License: CC0-1.0](https://img.shields.io/badge/license-CC0--1.0-bb4444?style=flat-square) +![Self-hosted](https://img.shields.io/badge/self--hosted-docker-2496ED?style=flat-square&logo=docker&logoColor=white) +![Built with Rust](https://img.shields.io/badge/built%20with-Rust-d4652a?style=flat-square) +![React + TypeScript](https://img.shields.io/badge/React_19%20%2B%20TS-61DAFB?style=flat-square&logo=react&logoColor=black) +![ActivityPub](https://img.shields.io/badge/federated-ActivityPub-8B5CF6?style=flat-square) +![WCAG 2.2 AAA](https://img.shields.io/badge/WCAG%202.2-AAA-228833?style=flat-square) +![No Telemetry](https://img.shields.io/badge/telemetry-none-778899?style=flat-square) -## Running it +
+*Write the answer with your pen. Your instance, your rules.* +*No algorithmic feeds, no engagement tricks, no paywall. Just crosswords.* + +
+ +--- + +## 🌍 What is Cruciverb? + +Cruciverb is a self-hosted daily crossword server with a web frontend that treats the puzzle like something worth doing properly. Every day it generates a fresh set of grids - five difficulty levels from a tiny 5x5 warm-up to a punishing 21x21 - seeded so every solver gets the same puzzle, the same clues, the same bragging rights. + +The twist is the input. You can type like everyone else, or you can draw the letters. Handwriting recognition runs in your browser through ONNX, the browser's own handwriting API, and a tesseract fallback, with an ink overlay that makes a touchscreen or stylus feel like a pen on paper. + +Instances talk to each other over ActivityPub, and nobody stands in the middle. Your solves turn into signed receipts that survive when you move between instances. Clue submissions travel across the network. It's crosswords run the way a co-op should run: each community owns its own place, shares with its neighbors, and answers to no head office because there isn't one. + +--- + +## 🧩 Everything in it + +**Daily puzzles** +- Five presets each day - Glyph, Rune, Scroll, Codex, Grimoire - same seeds for the whole instance +- Streaks, solve history, and personalized ratings per puzzle +- A rotating daily challenge per preset: purist (no hints), speed demon (beat the speedrun clock), surgeon (no wrong letters), no regrets (no deleted cells), iron will (never pause), inkwell (no pencil marks), trust fall (no autocheck), and time-of-day challenges like night owl and early bird +- Speedrun mode with per-preset time limits, plus marathon mode: a stream of 120-second puzzles where one failed grid ends the run + +**Inputs** +- Handwriting via ONNX, the browser handwriting API, and tesseract fallback, fused by an ensemble +- Stylus support with pressure, an ink overlay, a magnifying zoom strip, and a disambiguation popup when a letter is ambiguous +- Pencil marks, undo and redo stacks, cell flipping animations that reserve space instead of shifting the grid +- Blind mode for practice: clue text stays hidden until you fill the word + +**Community** +- A clue pool where anyone can submit and vote; approved clues flow into future generations +- Community puzzles: build one in the editor, publish it, and see it on everyone's boards +- Clue trainer with per-difficulty practice rounds and a running accuracy score +- Ratings, daily leaderboards (global, local-clean, weekly, streaks, completionists), and reports with human moderation + +**Play together** +- Multiplayer rooms sharing a grid live, with visible cursors for the people solving beside you +- Party games: submit a fake answer, vote on which one is real, then race to type the actual answer before your friends + +**Around the puzzle** +- Portable solve receipts: signed, claimable records that follow you to another instance +- Achievements - 28 badges across speed, consistency, and community +- RSS and Atom feeds of your solves +- An embeddable player build, shareables with QR codes, and og-images for puzzle posts +- First-run onboarding that never asks for an email: pick a display name, optionally plug in a passkey, optionally import your history from another instance +- PWA offline support with an IndexedDB cache and offline progress sync + +**Comfort and access** +- Light, dark, and system themes, warm palettes, and text scaling up to 200% +- Colorblind palettes, a screen-reader narrator, keyboard-only play, and reduced-motion cell animations +- Sound effects and a tor-friendly mode that keeps the page light for slow connections + +--- + +## πŸ•ΈοΈ The Fediverse + +Cruciverb speaks ActivityPub, the protocol behind Mastodon, Pixelfed, and the rest of the federated social web. + +The heart of it: states federate with visitors and their own community, daily puzzles are announced to followers as forum posts, and everyone's solves stay as their own Outbox history. Nobody's data lives on a server they don't run. There's no "main" instance, no center - just neighbors. + +Following another instance isn't just a greeting, it's trade. Once you federate: + +- **Common puzzle pages** - remote puzzles appear on your boards as first-class citizens, with reputation context +- **Clue exchange** - community clues flow both ways, each carrying blind reputation scores from the delivering domain +- **Federated leaderboards** - see who's fast on this puzzle across every connected instance +- **Portable receipts** - solves are cryptographically signed, so claiming your work on a new instance verifies rather than trusts +- **Discovery without stalking** - fresh instances announce themselves, you decide who gets to federate +- **Your own moderation** - freeze federation, block domains, or approve followers manually. Nobody gets to decide your community's norms but your community + +--- + +## πŸ›‘οΈ Security and privacy + +**For solvers** +- No email, no passwords, no signup wall: you're an anonymous session the moment you arrive +- Optional WebAuthn passkeys for a durable identity - and only then, if you want it, cookie binding to your browser fingerprint +- Everything you submit (clues, puzzles, votes) is tied to your community's reputation, and you can export your entire history and take it with you +- Tor-friendly mode, cookie lifetimes you control, and no analytics or trackers anywhere on the page + +**For admins and moderators** +- An admin panel with real teeth: user bans, word blocklists with import and export, clue queue moderation, audit logging, and report handling +- Fine-grained federation controls: allowlist mode, follower approval, new-peer review gates, and an outbox rate limit +- Federation freeze switch, per-domain blocks with reasons, and automatic key-change detection with alerting +- Signed receipts that let any instance verify a claimed solve from any other instance + +**Under the hood** +- Encrypted at rest: AES-256-GCM over display names and personal fields, key held in the environment, never in the database +- Rate limits applied per session and per IP address, at the socket, not from spoofable headers: the server reads the real connection address behind the proxy +- In-memory anti-replay and challenge-consumption handling, with the public API v1 endpoints behind keyed limits + +--- + +## πŸ—‚οΈ Project Structure + +``` +cruciverb/ +β”œβ”€β”€ cruciverb-core/ Generator engine +β”‚ └── src/ +β”‚ β”œβ”€β”€ grid/ Grid construction, slots, symmetry +β”‚ β”œβ”€β”€ dict/ Word lists and indices +β”‚ β”œβ”€β”€ solver/ Fill CSP with AC-3 propagation +β”‚ β”œβ”€β”€ import/ IPUZ and PUZ readers +β”‚ β”œβ”€β”€ export/ IPUZ, PUZ, PDF writers +β”‚ └── clue/ Clue seeds and blocklists +β”œβ”€β”€ cruciverb-server/ Axum API +β”‚ └── src/ +β”‚ β”œβ”€β”€ activitypub/ Actor, inbox, outbox, signatures +β”‚ β”œβ”€β”€ routes.rs Main route handlers +β”‚ └── db.rs SQLite storage layer +β”œβ”€β”€ cruciverb-cli/ Command line generation +β”œβ”€β”€ frontend/ Vite + React client +β”‚ └── src/ +β”‚ β”œβ”€β”€ components/ Grid, panels, overlays +β”‚ β”œβ”€β”€ recognition/ Handwriting engines +β”‚ └── hooks/ Input, focus, narrator hooks +β”œβ”€β”€ scripts/ Template and preview tools +└── Dockerfile Multi-stage server image +``` + +--- + +## πŸƒ Running it + +The built image is published on the git server, so there's nothing to compile: + +```bash +docker login git.lashman.live +docker compose up -d +``` + +That pulls the image, mounts a ./data directory, and serves the puzzle on port 8484. Before first start, edit the compose file: set `INSTANCE_URL` and the federation names to your real domain, and add a `DATA_ENC_KEY` if you want storage encryption. + +Prefer to run from source? + +```bash cargo run -p cruciverb-server cd frontend && npm install && npm run dev +``` -Point the client at the api on localhost:8080. Environment variables configure the instance domain, actor name, and data directory. +The server needs a data directory and, ideally, a domain: `INSTANCE_URL` and `AP_DOMAIN` tell the federation layer who you are, `DATA_ENC_KEY` locks the private columns, and an optional `TRUST_PROXY` tells it to take the reverse proxy's word for connection addresses. Full config stays on the host, where it belongs. + +--- + +## 🀝 Contributing + +Cruciverb is public domain software. No contributor license agreements, no assignment forms, no gatekeepers. If you want to help, help. Fork it, bend it, run your own instance with your own house rules. The code belongs to everyone equally. + +Some ways to contribute: report bugs, build puzzles in the editor, submit clues through the trainer (that counts), improve recognition accuracy, add translations, or run an instance and federate with a neighbor. + +Good ideas get merged. Decisions are made by the people doing the work. + +--- + +## πŸ“œ License + +

+ + CC0 + +

+ +Dedicated to the **public domain** under [CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/). No copyright, no restrictions, no permission needed. Take it, use it, change it, share it. + +Crosswords have belonged to the commons for over a century. No reason to stop now. + +--- + +

+ + Built for people who like their puzzles hard and their software honest.
+ No ads. No tracking. No engagement dark patterns.
+ No profit motive. Just a grid, a pen, and a deadline. +
+

\ No newline at end of file