# 5chan Full LLM Context > 5chan is a static, serverless, adminless, decentralized imageboard client built on the Bitsocial protocol. This file is generated by `scripts/generate-llms-files.mjs`. Do not hand-edit it; update the source docs or generator config, then run `yarn llms:generate`. Use this as compiled context only. Source files, tests, manifests, and live/runtime evidence remain authoritative. ## Index - [README.md](#readmemd) - [AGENTS.md](#agentsmd) - [PRODUCT.md](#productmd) - [DESIGN.md](#designmd) - [src/AGENTS.md](#srcagentsmd) - [scripts/AGENTS.md](#scriptsagentsmd) - [docs/agent-playbooks/known-surprises.md](#docsagent-playbooksknown-surprisesmd) - [docs/agent-playbooks/long-running-agent-workflow.md](#docsagent-playbookslong-running-agent-workflowmd) - [docs/agent-playbooks/bug-investigation.md](#docsagent-playbooksbug-investigationmd) - [docs/agent-playbooks/translations.md](#docsagent-playbookstranslationsmd) - [docs/agent-playbooks/skills-and-tools.md](#docsagent-playbooksskills-and-toolsmd) - [docs/agent-playbooks/verification.md](#docsagent-playbooksverificationmd) - [docs/agent-playbooks/hooks-setup.md](#docsagent-playbookshooks-setupmd) - [docs/upload-automation-retest-checklist.md](#docsupload-automation-retest-checklistmd) --- ## README.md Source: https://github.com/bitsocialnet/5chan/blob/master/README.md ```markdown [![Build Status](https://img.shields.io/github/actions/workflow/status/bitsocialnet/5chan/ci.yml?branch=master)](https://github.com/bitsocialnet/5chan/actions/workflows/ci.yml) [![Coverage](https://img.shields.io/endpoint?url=https://bitsocialnet.github.io/5chan/badges/coverage.json)](https://github.com/bitsocialnet/5chan/blob/master/scripts/write-coverage-badge.mjs) [![Release](https://img.shields.io/github/v/release/bitsocialnet/5chan)](https://github.com/bitsocialnet/5chan/releases/latest) [![License](https://img.shields.io/badge/license-GPL--3.0--or--later-red.svg)](https://github.com/bitsocialnet/5chan/blob/master/LICENSE) [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/) [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/bitsocialnet/5chan) _Telegram group for this repo https://t.me/fivechandev_ # 5chan 5chan is a serverless, adminless, decentralized and open-source imageboard built on the [Bitsocial protocol](https://bitsocial.net). It features the classic imageboard directory structure, but with a crucial difference: **anyone can create and own boards, and multiple boards can compete for each directory slot**. ## Key Features ### Decentralized Board Ownership Unlike traditional imageboards, 5chan has no global admins or central authority. Anyone can create unlimited boards using [5chan Board Manager](https://github.com/bitsocialnet/5chan-board-manager). Each board owner runs their own P2P node that users connect to peer-to-peer, giving them complete control over their board's content, moderation, and rules. ### Competitive Directory System 5chan maintains the familiar imageboard directory structure (Japanese Culture, Video Games, Interests, Creative, etc.), but introduces competition: **multiple boards can compete for each directory slot**. For example, there can be unlimited "Business & Finance" boards, but only the highest-voted one appears in the directory on the homepage. Currently, directory assignments are temporarily handpicked by developers through GitHub pull requests. In the future, each directory will have its own voting page. 5chan Pass holders are expected to participate in directory voting, while final governance mechanics are still being designed to include BSO-holder alignment instead of pass-only final control. ### How It Works - **Current System**: Developers manually curate directory assignments by reviewing pull requests to the [5chan directory files](https://github.com/bitsocialnet/lists/tree/master/5chan-directories). - **Future System**: Each directory will have its own voting page listing the boards competing for that slot. 5chan Pass holders are expected to participate in directory voting, while final governance mechanics are still being designed to include BSO-holder alignment instead of pass-only final control. - **Accessing Boards**: Users can access any board at any time using its address, regardless of directory assignment. Boards can be accessed via the search bar, by subscribing to them (which adds them to the top bar), or by directly navigating to their address. ### Future Roadmap #### In-App Board Creation Creating boards directly from the 5chan web app (5chan.app) is planned. This requires connecting via RPC to a bitsocial node—technically already possible, but there's no default connection configured. A default connection would require a public RPC service (similar to what Infura provides for crypto wallets, but for bitsocial nodes). This would allow all users to be connected to a P2P node by default using a free tier subscription in the background, potentially monetized via ads injected in the RPC service-owned boards. #### Directory Voting Directory voting pages are planned for each slot on 5chan. These pages will list the competing boards for that directory, and 5chan Pass holders are expected to participate in voting. Final governance mechanics are still being designed to include BSO-holder alignment instead of pass-only final control. ## Downloads - **Web version**: https://5chan.app (also available using Brave/IPFS Companion on https://5chan.eth) - **Desktop version** (full P2P bitsocial node, seeds automatically): Available for Mac/Windows/Linux, [download from the release page](https://github.com/bitsocialnet/5chan/releases/latest) - **Mobile version**: Available for Android, [download from the release page](https://github.com/bitsocialnet/5chan/releases/latest) ## Run 5chan in Your Browser With a Local Node If you want the full P2P node but prefer opening 5chan in your normal browser instead of using the desktop app, use [bitsocial-cli](https://github.com/bitsocialnet/bitsocial-cli). It runs the Bitsocial/IPFS node and serves the bundled 5chan Web UI locally, so you do not need to run this repository separately. ```sh-session npm install -g @bitsocial/bitsocial-cli bitsocial daemon ``` When the daemon starts, it prints a `WebUI (5chan - Imageboard-style UI)` URL. Open that URL in your browser to use 5chan through your local node. See the [bitsocial-cli daemon docs](https://github.com/bitsocialnet/bitsocial-cli#running-daemon) for details. ## Creating a Board In the bitsocial protocol, a 5chan board is called a _community_. To deliver the expected 5chan imageboard UX, a board should run on a bitsocial node together with [5chan Board Manager](https://github.com/bitsocialnet/5chan-board-manager). The board manager applies imageboard-style lifecycle rules that bitsocial communities do not enforce by themselves: thread limits, bump limits, archived-thread retention, and purging of author-deleted content. To create and run a board: 1. Follow the Docker Compose flow in the [5chan-board-manager README](https://github.com/bitsocialnet/5chan-board-manager#docker-compose-recommended); 2. Create your community and add it to 5chan Board Manager using the commands shown there; 3. Keep the manager running so it can apply 5chan board behavior such as thread archiving, bump limits, and retention cleanup. Once created, anyone can connect to your community using any bitsocial client (such as 5chan) by using the community address. The address is not stored in any central database—bitsocial is a pure peer-to-peer protocol. Without 5chan Board Manager, a community can still be opened in 5chan, but it will not behave like a conventional imageboard board: old threads will not be archived when they fall past the last page, bump limits will not be enforced, archived threads will not be purged after the retention window, and author-deleted content will not be automatically purged. **Note**: Creating boards directly from the 5chan web app is planned for the future (see [Future Roadmap](#future-roadmap)). ## Submitting Your Board to a Directory To have your board appear in a directory on the 5chan homepage: 1. Ensure your board meets these requirements: - Active and well-moderated - Relevant to the directory category - **99% uptime** (since a board acts like its own server—it's a P2P node) 2. Open a pull request on GitHub by editing the relevant file in the [5chan-directories folder](https://github.com/bitsocialnet/lists/tree/master/5chan-directories) 3. Add your board's entry with: - Title: in the format `/directoryCode/ - Title`, e.g. "/biz/ - Business & Finance"; - Address: the bitsocial community address, whether IPNS key (`12KooW...`) or readable crypto address (`mydomain.eth`); - NSFW status: `true` or `false`, must match the standard classification for the directory code. 4. The developers will review your PR and merge it if approved **Note**: Even if your board isn't assigned to a directory, users can still access it at any time using its bitsocial community address. Directory assignment only affects visibility on the homepage. ## Development ### Prerequisites - Node.js 22.12.0, pinned in [`.nvmrc`](./.nvmrc) - Corepack enabled once per machine: `corepack enable` ### Contributor Setup 1. Run `nvm install && nvm use` 2. Run `corepack enable` once 3. Use plain `yarn install`, `yarn build`, and `yarn test` ### Setup 1. Clone the repository 2. Install dependencies: `yarn install` 3. Start the web client: `yarn start` The dev server normally runs at https://5chan.localhost via [Portless](https://github.com/vercel-labs/portless), which gives each Bitsocial project a stable, named URL instead of a random port. Portless 0.11 serves this URL through an HTTPS proxy on port 443, so the first `yarn start` after install or proxy reset may prompt for sudo; accept the prompt so the URL can stay portless. On non-`master` branches, or when another legacy process is already holding the canonical route, `yarn start` will automatically use a branch-scoped `*.5chan.localhost` URL instead of failing. To bypass Portless and use a plain Vite dev server, run `PORTLESS=0 yarn start`; it will start at `http://localhost:3000` and automatically fall forward to the next free port if `3000` is already in use. For device testing on a USB-connected Android phone (without relying on `5chan.localhost` DNS from the device): - `yarn start:android-usb` starts Vite bound to `127.0.0.1` and runs `adb reverse`, so the phone can load the dev site at `http://localhost:3000`. When the server is up, it opens that URL in each connected device’s default browser via `adb`. Set `ANDROID_USB_OPEN_BROWSER=0` to skip auto-open. Requires [Android platform-tools](https://developer.android.com/tools/releases/platform-tools) (`adb` on your `PATH`), USB debugging enabled, and the device showing as `device` in `adb devices`. ### Scripts - **Web client**: `yarn start` (https://5chan.localhost) - **Web client (Android phone over USB)**: `yarn start:android-usb` (see above) - **Electron client** (must start web client first): `yarn electron` - **Electron client** (don't delete data): `yarn electron:no-delete-data` - **Web client and electron client**: `yarn electron:start` - **Web client and electron client** (don't delete data): `yarn electron:start:no-delete-data` ### Challenge Types Bitsocial communities can require users to solve one or more anti-spam challenges before a publication is accepted. 5chan already supports multiple challenge types, including `url/iframe` challenges so [Mintpass](https://github.com/bitsocialnet/mintpass) communities can run their iframe flow directly inside a modal. The modal first shows a hostname confirmation (showing only the host for mintpass.org, full URL otherwise), then opens the HTTPS iframe with the current theme, replaces `{userAddress}` tokens with the signed-in address, and submits automatically when the user finishes. 5chan also has an optional UX integration with [`@bitsocial/ai-moderation-challenge`](https://github.com/bitsocialnet/ai-moderation-challenge): when a failed verification contains the exact message `This media was already posted recently.`, 5chan abandons the rejected pending publication, returns to the originating post form, preserves the draft, and shows the message inline. This string is an intentionally small cross-package contract rather than a package dependency. Challenges that omit it, or return any other error, continue through the normal generic challenge-error flow. While waiting for a challenge or answer verification, unpublished posts explain that the board is checking the post or verifying its challenge answers. The AI moderation notice appears only after challenge answers have been submitted, while waiting for verification, so it does not appear before Spamblocker opens. It also requires the target board's cached public `community.challenges` to contain the package's exact description, `Moderate Bitsocial publications with AI.`, with type `text/plain`. Unknown or customized metadata gets no AI notice. This describes the board's configuration, not live AI progress or confirmation that its earlier checks passed; other publishing states and errors retain their existing messages. ### Build The Linux/Windows/macOS/Android build scripts are in [.github/workflows/release.yml](https://github.com/bitsocialnet/5chan/blob/master/.github/workflows/release.yml) ## License 5chan is open-source software (GPL-3.0-or-later) with no owner—anyone can host their own instance on any domain. The operator of any domain is merely hosting the web app and does not own, create, moderate, or control 5chan or any board content, which is stored peer-to-peer and generated by board owners and users. ``` --- ## AGENTS.md Source: https://github.com/bitsocialnet/5chan/blob/master/AGENTS.md ```markdown # AGENTS.md ## Purpose and priority These are the shared instructions for agents working on 5chan. Explicit user instructions take precedence over repository workflow guidance. MUST rules are mandatory; SHOULD rules are defaults. Read linked playbooks only when the task needs them. Use judgment for routine implementation choices and continue authorized work. Ask only when missing information materially changes the outcome or an action needs authorization that has not already been given. Do not turn a skill's suggested procedure into an extra approval gate. ## Product and source of truth 5chan is a static, serverless, adminless, decentralized imageboard client built on the Bitsocial protocol. Board content comes from peers, not the app origin. Preserve hash routing and static deployment unless the user requests an architectural change. Code, tests, manifests, source docs, and runtime evidence establish behavior. This file, skills, playbooks, task logs, and generated `llms*.txt` are orientation and policy; verify their technical claims against source before editing. Check the installed dependency version before assuming a nearby repository supplies its code. For an unexpected repo-specific issue, tell the contributor and continue independent work. After confirmation, record only recurring issues with a concrete mitigation in [known-surprises.md](docs/agent-playbooks/known-surprises.md). ## Working principles - Define completion for non-trivial work. Continue through implementation, relevant verification, and fixes until the requested outcome is complete; stop at the user’s requested boundary. - Understand the flow before editing. Prefer skipping unnecessary work, reusing repository code, standard-library/native features, then installed dependencies, before writing new code. - Keep diffs scoped. Preserve unrelated edits; do not reformat, rename, or refactor adjacent code without a task-related reason. - Simplicity must preserve correctness, clarity, accessibility, validation, security, and useful tests. - For a bug tied to a file or line, inspect `git log`/`git blame`, then relevant `git show`, before fixing it. See [bug-investigation.md](docs/agent-playbooks/bug-investigation.md). - Use existing evidence or a focused test before adding instrumentation. Add runtime logging when it resolves uncertainty; remove task-owned instrumentation after verification. ## Task router | Task | Required guidance/check | |---|---| | Visual design, layout, CSS, or themes | Read the relevant guidance in [DESIGN.md](DESIGN.md); review against its Do/Don't list | | Files under `src/` or `scripts/` | Read the directory's `AGENTS.md` | | Code or automation changed | Select affected checks using [verification.md](docs/agent-playbooks/verification.md); use `agent:verify` for integration/build changes or an explicitly requested full pass | | React state, effects, data flow, or rendering performance changed | Review relevant React guidance; run `yarn doctor:check` and affected `yarn perf:check` scenarios | | UI behavior/layout changed | Verify the affected flow; select browsers/viewports using [verification.md](docs/agent-playbooks/verification.md) | | Loading/navigation/performance work | Add a throttled Chromium pass; see [low-spec-verification.md](docs/agent-playbooks/low-spec-verification.md) | | Translation keys/values | Use the `translate` skill; one process applies locale changes at a time | | `package.json` changed | Run `corepack yarn install` to synchronize `yarn.lock` | | Dependencies, moved files, or imports changed | `yarn boundaries` (part of `yarn lint`) must pass; see module boundaries in [src/AGENTS.md](src/AGENTS.md). Run advisory `yarn knip`; resolve relevant new findings | | AI workflow files changed | Edit shared sources, run `yarn ai-workflow:sync`, then `yarn ai-workflow:check` and `yarn ai-workflow:test` | | Public English docs or AI context changed | Run `yarn llms:generate` and include resulting `public/llms*.txt` changes | | Version or changelog changed | Run `yarn blotter:check`; follow the `release` skill's user-facing wording rules | | Open PR feedback or merge readiness | Use `review-and-merge-pr` within the user's requested scope | | Work needs a durable handoff/resumption | Use [long-running-agent-workflow.md](docs/agent-playbooks/long-running-agent-workflow.md) | ## Code and design - Use Corepack-managed Yarn 4, never npm for project dependency changes. Pin exact versions and keep the lockfile synchronized. - Stack: React 19, TypeScript, Zustand, React Router v6, Vite, `@bitsocial/bitsocial-react-hooks`, i18next, oxlint, oxfmt. - Keep page composition in `src/views/`, reusable UI in `src/components/`, hooks in `src/hooks/`, shared state in `src/stores/`, helpers in `src/lib/`, static data in `src/data/`. Dependencies flow one way between those layers; see module boundaries in [src/AGENTS.md](src/AGENTS.md). - Use Zustand for shared/global state; local component state may use `useState`. - Use Bitsocial hooks for protocol data access. Do not fetch data in effects or synchronize derived state with effects; derive values during render. - Reuse hooks for repeated logic. Model complex flows clearly instead of accumulating boolean flags. - Use React Router for navigation, not manual history manipulation. - Add comments for non-obvious constraints or logic, not for obvious code. - Preserve the classic imageboard appearance: square edges, 1px theme borders, flat surfaces, compact text, and the theme palette. - No rounded corners, decorative pills/badges, row/card hover background fills, CSS transitions/animations, soft shadows, glass, gradients, or new marketing colors on product UI. - Small flat per-entity color indicators are allowed when functional. Technical surfaces follow the same compact, theme-aware design. ## Git and ownership - Keep `master` releasable. Start new changes on short-lived `codex/feature/*`, `codex/fix/*`, `codex/docs/*`, or `codex/chore/*` branches unless the user requests otherwise. - For an unrelated task while another branch is active, create a separate descriptive worktree from `master`. Prefer `./scripts/create-task-worktree.sh `; it installs dependencies. - Related delegated slices may share the task worktree with non-overlapping file ownership. Never switch branches underneath another agent. - Stage only task-owned changes, using a selective index patch when files contain mixed edits. Do not use `git add -A` as a default. - Never commit secrets or generated build output. Preserve preexisting artifacts and unrelated changes during cleanup. - Only commit, push, publish, or merge when authorized. Permission already given for the action persists through its necessary steps. - When opening a requested PR, target `master` and make it ready for review so review bots run. - After an authorized merge, clean up only the verified merged branch/worktree; preserve any later or unrelated work. Do not run Git cleanup from lifecycle hooks. - Use `gh` for GitHub operations. Commit/issue formatting lives in [commit-issue-format.md](docs/agent-playbooks/commit-issue-format.md); provide suggestions when requested, not on every answer. ## Verification and resource ownership - Verify the affected behavior with the narrowest reliable checks. Add regression tests for non-trivial, testable bugs; do not add tests that merely restate a reversible wording or formatting edit. - Run applicable checks for the final change once. Repeat or broaden them only after relevant edits, failures, or unresolved concerns. Preserve explicit user, CI, and release requirements. Documentation-only changes need document/workflow checks. - Before heavy work, inspect existing processes. Stop only stale processes owned by this task; never stop a process of unclear ownership. - Serialize installs, builds, full tests/coverage, React Doctor, Android/Electron work, and browser profiling across the task. One agent owns heavy verification. - Use `corepack yarn exec vitest run --maxWorkers=2 [paths]` for agent-run tests. Do not use watch mode or the package's default four-worker setting. - React Doctor is guidance for newly introduced issues, not a score target. Knip and coverage are advisory; do not invent new repository-wide gates. - Default to fresh isolated Playwright sessions. Reuse a contributor's current browser only when explicitly authorized; do not ask again after session mode is established. - Use `./scripts/pw-session.sh open ...` and `close ` for every browser session. One browser may be active machine-wide. Exit 75 means busy; defer or use the wrapper's bounded wait. - Run browser engines sequentially. Reuse each session for desktop/mobile and close the exact session in cleanup even after failure. Never use `close-all` or `kill-all`. - Reuse a compatible dev server in the same worktree when safe. Otherwise record and clean up the server/process you start. Never start a server for a documentation-only task. - Review the final task-owned diff. Use `code-quality-review` for non-trivial changes or an explicit review request; apply high-confidence findings within existing authorization. - After a bug fix or substantive review correction exposes a preventable mistake, use [retro](.agents/skills/retro/SKILL.md) before finishing to consider the smallest useful prevention. Existing coverage or no additional check can be the right outcome. ## Skills and delegation - Shared skills live in `.agents/skills/`; shared roles in `.agents/roles/`. `.claude/skills/` and harness agent files are generated compatibility outputs. See [skills-and-tools.md](docs/agent-playbooks/skills-and-tools.md). - Keep harness-specific hooks, permissions, and metadata explicit; byte-identical files do not establish equivalent runtime behavior. - Keep model and reasoning choices out of committed skills and custom agents. Use the app’s runtime defaults, parent inheritance, and supported invocation-time choices; do not invent a `latest` alias or require model research for ordinary tasks. - Delegate substantial independent work when it improves speed, context isolation, or independent review. Small or tightly coupled tasks can stay with the parent. - Give each child its scope, acceptance criteria, context, file ownership, and evidence to return. For an independent review, omit the parent's verdict. - Parallelize read-heavy work and non-overlapping edits; use at most four active workers by default. Children do not each run full builds. Browser work always remains serialized. - Use built-in worker/explorer roles where available; custom roles cover browser checks, profiling, Android, translation, and review. Avoid a compulsory chain of specialist agents. - Use relevant React skill guidance for state/effect/data-flow or performance work. Load only rules that fit this Vite client; use `you-might-not-need-an-effect` for a focused effect review when the reason is unclear. - Prefer existing tools and local CLIs. Use external documentation when versions matter. Do not search for or install additional skills merely because a normal coding task mentions their domain. - Keep tool catalogs relevant. Deferred MCP loading can reduce context overhead, but unnecessary integrations still add choices; disable unused tools when their overhead is observable. Playwright CLI remains the project browser verification path. ## React diagnostics and runtime performance `yarn agent:verify` and CI run `yarn doctor:check` for task-diff source diagnostics and `yarn perf:check` for deterministic runtime scenarios. Doctor remains advisory for relevant new findings; a score is not a target. Run affected scenarios after React state/effect/subscription/rendering changes, and `yarn perf:test` after React, Bippy, or collector upgrades. Install the pinned browser once with `yarn perf:install`; ordinary edit hooks still only format files. Development builds initialize the bounded Bippy collector before React and expose `window.__REACT_PERF__.reset()` / `.snapshot()`. It counts committed component updates by instance; it does not identify wasted work or count aborted renders. A root React Profiler supplies measured render duration. Missing instrumentation, dropped events, and exceeded scenario budgets fail the runtime check. Use `yarn perf:record --scenario ` for JSON and native Chrome traces; use `profile-browsing` for the evidence contract and broader investigations. `yarn build:profile` creates a separate `build-profile/` output with `react-dom/profiling` and sourcemaps; `yarn preview:profile` serves it. Ordinary production excludes the collector and Profiler boundary. A normal production preview can measure page timing but cannot provide these React timing/count checks. Development builds retain Agentation and `window.__ELEMENT_SOURCE__` for visual feedback/source inspection. The runner suppresses Agentation during capture. Run browser tools and heavy checks serially; the performance runner owns its browser/server lifecycle and uses the shared browser resource lock. Stop or wait for an existing browser owner before starting another capture. ## Local commands and playbooks Canonical dev URL: `https://5chan.localhost`; other worktrees may use branch-scoped `*.5chan.localhost`. Preserve the launcher's HTTPS proxy on port 443. Direct Vite fallback: `PORTLESS=0 yarn start`. USB Android: `yarn start:android-usb` (`ANDROID_USB_OPEN_BROWSER=0` skips opening the phone browser). Common checks: `yarn agent:verify`, `yarn doctor`, `yarn knip`, `yarn ai-workflow:sync`, `yarn ai-workflow:check`, `yarn ai-workflow:test`, `yarn llms:generate`, `./scripts/pw-session.sh status`. Load details on demand: [hooks](docs/agent-playbooks/hooks-setup.md), [verification](docs/agent-playbooks/verification.md), [translations](docs/agent-playbooks/translations.md), [skills/tools](docs/agent-playbooks/skills-and-tools.md), [long-running work](docs/agent-playbooks/long-running-agent-workflow.md), [known surprises](docs/agent-playbooks/known-surprises.md). ``` --- ## PRODUCT.md Source: https://github.com/bitsocialnet/5chan/blob/master/PRODUCT.md ```markdown # Product ## Register product ## Users 5chan is for people who already understand classic imageboards, especially users whose habits depend on dense boards, terse navigation, reply flows, catalog scanning, familiar colors, and old-school post mechanics. The primary user should be able to land on 5chan and feel that the interface behaves like an imageboard they already know. Secondary users include board owners, board moderators, and contributors building decentralized features around Bitsocial. Their tools should still feel native to the same imageboard environment instead of becoming a separate admin dashboard aesthetic. ## Product Purpose 5chan exists to preserve the classic imageboard habit while removing the dependency on global admins. It keeps the familiar imageboard directory structure and browsing experience, but runs on the Bitsocial protocol so anyone can create, own, and moderate boards independently. Success means experienced imageboard users do not need to relearn how to browse, post, reply, search, use catalogs, read threads, or understand board identity. The decentralization should matter structurally, but it should not make the core user experience feel unfamiliar. ## Brand Personality 5chan should feel familiar, blunt, resilient, and low-friction. It is not polished in the startup sense. It should feel like a functional old internet place that kept its original interface discipline while replacing the governance layer underneath. The voice is plain and direct. Prefer short labels, conventional imageboard wording, and visible system behavior over explanatory product copy. ## Anti-references Do not make 5chan look like a modern social network, crypto app, SaaS dashboard, mobile-first content platform, or polished community product. Avoid feed algorithms, engagement framing, large hero layouts, decorative cards, rounded modern controls, soft gradients, animated brand flourishes, and "Web3" visual language. Do not modernize classic imageboard affordances unless there is a concrete usability, accessibility, or protocol-driven reason. When 5chan needs custom decentralized features, they should look like they belong inside the existing classic imageboard UI. Do not imply official affiliation with any existing imageboard. The design goal is alignment with long-standing imageboard user expectations, not brand ownership or endorsement. ## Text and Expression 5chan adds no emoji affordances: no emoji picker, no shortcode or custom-emote system, and no Twemoji-style emoji styling. Emoji a user types or pastes pass through as raw, unstyled Unicode, neither encouraged nor blocked — the same posture 4chan itself takes, which renders Unicode but ships no emoji tooling. This is deliberate. On imageboards the expressive vocabulary is greentext, reaction images, and text faces (kaomoji and ASCII / Shift-JIS art), not graphical emoji. Heavy emoji use reads as an outsider, other-platform, or phone-poster marker, and persistent personal-expression tokens cut against the anonymous, no-personal-branding norm the format depends on. The native surfaces — greentext, image replies, and plain-Unicode text faces — already do what emoji do elsewhere. It is also strategic. 5chan improves on classic imageboards structurally — independent board ownership, no global admins, the Bitsocial protocol underneath — not by modernizing the posting experience. Imageboard history is consistent: "more modern UX" does not win users and erodes the authenticity that does, and an emoji picker is exactly that kind of modernization. With no global admins to run wordfilters or per-board character rules, the norm holds simply by not building the affordances and by leaving emoji as plain Unicode; board-level moderation can address the rest. ## Design Principles 1. Classic parity first. For boards, threads, posts, replies, catalogs, post forms, navigation, and theme behavior, familiar imageboard behavior is the baseline. 2. Preserve muscle memory. Existing imageboard users should not have to learn new interaction patterns for familiar tasks. 3. Make decentralization invisible until it matters. Board ownership, competing directories, Bitsocial addresses, and moderation differences should be clear when relevant, but should not dominate routine browsing. 4. Custom features inherit the old UI language. Passes, board creation, mod queues, challenges, subscriptions, and directory competition should use compact, flat, text-first imageboard patterns. 5. Favor density over polish. The interface should optimize for scanning, comparison, and repeated use, not marketing impact. ## Accessibility & Inclusion Keep the nostalgic interface, but do not use nostalgia as an excuse for broken accessibility. Preserve keyboard access, readable focus states, sufficient contrast within each theme, reduced-motion safety, predictable tab order, and responsive behavior on mobile. When accessibility improvements conflict with exact visual parity, choose the smallest adjustment that fixes the usability issue while preserving the classic imageboard feel. ``` --- ## DESIGN.md Source: https://github.com/bitsocialnet/5chan/blob/master/DESIGN.md ```markdown --- version: alpha name: 5chan description: A decentralized imageboard with a classic imageboard user experience. colors: yotsuba-body-bg: "#ffffee" yotsuba-reply-bg: "#f0e0d6" yotsuba-mobile-reply-bg: "#f5e9e1" yotsuba-border: "#d9bfb7" yotsuba-title: "#880000" yotsuba-link: "#0000ee" yotsuba-hover: "#ff0000" yotsuba-name: "#117743" yotsuba-subject: "#cc1105" yotsuba-greentext: "#789922" yotsuba-b-body-bg: "#eef2ff" yotsuba-b-reply-bg: "#d6daf0" yotsuba-b-border: "#b7c5d9" yotsuba-b-title: "#af0a0f" yotsuba-b-link: "#34345c" futaba-body-bg: "#ffffee" modal-preview-bg: "#181f24" neutral-white: "#ffffff" neutral-black: "#000000" typography: board-title: fontFamily: "Tahoma, sans-serif" fontSize: "28px" fontWeight: 700 lineHeight: 1.2 letterSpacing: "normal" body: fontFamily: "Arial, Helvetica, sans-serif" fontSize: "13px" fontWeight: 400 lineHeight: 1.3 letterSpacing: "normal" form-label: fontFamily: "Arial, Helvetica, sans-serif" fontSize: "10pt" fontWeight: 700 lineHeight: 1.2 letterSpacing: "normal" mobile-post: fontFamily: "Arial, Helvetica, sans-serif" fontSize: "11pt" fontWeight: 400 lineHeight: 1.3 letterSpacing: "normal" rounded: square: "0" spacing: page-edge: "5px" field-padding: "2px" compact-padding: "0.5em" hairline: "1px" components: desktop-text-button: textColor: "{colors.yotsuba-link}" typography: "{typography.body}" rounded: "{rounded.square}" padding: "0" mobile-button: backgroundColor: "{colors.yotsuba-reply-bg}" textColor: "{colors.yotsuba-title}" typography: "{typography.form-label}" rounded: "{rounded.square}" padding: "3px 5px" input: backgroundColor: "{colors.neutral-white}" textColor: "{colors.neutral-black}" typography: "{typography.body}" rounded: "{rounded.square}" padding: "2px" reply-surface: backgroundColor: "{colors.yotsuba-reply-bg}" textColor: "{colors.yotsuba-title}" rounded: "{rounded.square}" --- ## Overview **Creative North Star: "The Preserved Imageboard"** 5chan's visual system is intentionally conservative. The product should feel like a classic imageboard with a decentralized substrate, not like a redesigned forum or a modern community platform. The default answer for any board, thread, catalog, post, reply, or post-form UI is to preserve familiar imageboard density, typography, color, and interaction shape. Most surfaces are flat, compact, text-first, and visibly old web. Controls may look plain by modern standards because that plainness is part of the product promise. New decentralized features should enter through the same visual language: small links, square fields, compact tables, simple modal bars, terse labels, and theme-aware colors. **Key Characteristics:** - Dense layouts with minimal padding. - Square edges and 1px borders. - Arial/Helvetica body text with Tahoma board titles. - Yotsuba, Yotsuba B, and Futaba-style palettes as first-class themes. - Text links and bracketed actions over large button components. - Visual compatibility with classic imageboard user expectations. ## Colors The palette is inherited from classic imageboard themes and should remain recognizable. Use the existing CSS variables in `src/themes.css` as the source of truth for implementation. ### Primary - **Yotsuba Body** (`#ffffee`): default warm page background for NSFW-style boards. - **Yotsuba Reply** (`#f0e0d6`): reply containers, modal surfaces, pagination, menu backgrounds, and compact UI panels. - **Yotsuba Title Red** (`#880000`): board headers, bars, button text, and theme-defining chrome. - **Yotsuba B Body** (`#eef2ff`): default cool page background for SFW-style boards. - **Yotsuba B Reply** (`#d6daf0`): reply containers and panel surfaces in the blue theme. ### Secondary - **Classic Link Blue** (`#0000ee` / `#34345c`): links, post actions, desktop text buttons, and navigational affordances. - **Hover Red** (`#ff0000` / `#dd0000`): hover states for links and compact actions. - **Name Green** (`#117743`): poster names and identity markers. - **Subject Red** (`#cc1105`): post subjects and title emphasis. - **Greentext** (`#789922`): quote text and imageboard-specific content convention. ### Neutral - **Black** (`#000000`): body text in light themes and table borders where the original style calls for it. - **White** (`#ffffff`): homepage boxes, input fields, and legacy modal surfaces where defined by the theme. - **Hairline Borders** (`#d9bfb7` / `#b7c5d9`): dividers, reply borders, modal edges, pagination, and mobile post separators. - **Preview Dark** (`#181f24`): catalog and quote preview overlays only. ### Named Rules **The Theme Fidelity Rule.** Use existing theme variables before adding new colors. If a color is needed for a new feature, derive its role from the closest established imageboard component in the active theme. **The No Modern Accent Rule.** Do not introduce a new brand accent, gradient palette, neon crypto palette, or marketing color system for core product UI. **The Functional Color Exception.** Small, deterministic per-entity colors used as data — for example a hashed swatch that gives each connected peer a stable identity — are allowed. Render them as flat, square, small indicators (not gradients, glows, or large fills). This exception is for conveying data, not for decoration or branding. ## Typography **Display Font:** Tahoma, sans-serif. **Body Font:** Arial, Helvetica, sans-serif. **Label/Mono Font:** Use inherited body fonts unless a compact error or technical address requires monospace. **Character:** Typography should feel like a browser-native imageboard, not a designed publication. Small sizes, simple weights, default line wrapping, and dense text are expected. ### Hierarchy - **Board Title** (bold, `28px`, Tahoma): board names and top-level board identity. - **Box Heading** (bold, `131%`, Arial/Helvetica): homepage bars and compact panel headings. - **Body** (regular, `13px`, Arial/Helvetica): global app text, board chrome, metadata, and link rows. - **Post Content** (regular, `11pt` on mobile): comment bodies and mobile post content. - **Form Label** (bold, `10pt`): post form field headers, modal bars, and compact control labels. - **Small Metadata** (`9pt` to `10pt`): board bars, file info, timestamps, addresses, and post counts. ### Named Rules **The Browser-Native Rule.** Do not add custom web fonts, variable-font display systems, negative letter spacing, oversized headings, or marketing typography to product surfaces. ## Layout Layouts are dense, compact, and text-first, mirroring classic imageboard information density. Spacing is small and deliberate rather than generous, and structure comes from tables, inline rows, and slash-separated links instead of large spaced-out cards. - **Page edge** (`5px`): outer gutters around boards, catalogs, and threads. - **Field padding** (`2px`): inputs, table cells, and compact controls. - **Compact padding** (`0.5em`): reply blocks, menus, and small panels. - **Hairline** (`1px`): borders and separators between rows, posts, and panels. Desktop and mobile intentionally differ: desktop stays maximally compact, while mobile raises tap-target and text sizes only as much as needed to stay usable and avoid browser zoom. ### Named Rules **The Density Rule.** When in doubt, choose the more compact layout. Whitespace is not a feature on core imageboard surfaces. ## Elevation & Depth 5chan is flat by default. Depth is conveyed through background color, 1px borders, hard separators, and occasional legacy-style hard shadows on small menus. Avoid soft elevation, glass, blur, ambient shadows, floating cards, and layered dashboard surfaces. ### Shadow Vocabulary - **Small Legacy Menu Shadow** (`box-shadow: 2px 2px 0 1px rgba(0, 0, 0, .1)`): small popover menus such as compact filters, when a flat border alone is not enough. ### Named Rules **The Flat Surface Rule.** If a surface can be separated with a border or theme background, do that instead of adding shadow. ## Shapes 5chan is uniformly square. Corner radius is `0` everywhere on product surfaces, and structure comes from 1px theme borders rather than rounding or elevation. - **Corners:** square (`0` radius) on buttons, inputs, cards, replies, modals, and menus. - **Borders:** 1px theme border colors (for example Yotsuba `#d9bfb7`, Yotsuba B `#b7c5d9`). - **Indicators:** functional per-entity swatches render as small flat squares, never rounded chips. ### Named Rules **The No Rounding Rule.** Do not introduce `border-radius`, pill, capsule, chip, or rounded badge shapes on product UI. A label is square text, not a rounded token. ## Components ### Buttons - **Shape:** square corners (`0` radius). - **Desktop:** prefer text links, bracketed actions, or image-backed icon buttons over filled button components. - **Mobile:** use theme-colored rectangular buttons with compact padding, bold `10pt` text, and existing button fade assets. - **Hover / Focus:** hover changes color to the theme hover red; focus must stay visible and keyboard accessible. ### Cards / Containers - **Corner Style:** square. - **Background:** theme surfaces such as Yotsuba reply, Yotsuba B reply, homepage white, or the active post/mobile background token. - **Shadow Strategy:** none except the small legacy menu shadow. - **Border:** 1px theme borders. - **Internal Padding:** compact, commonly `2px`, `5px`, or `0.5em`. - **Hover:** do not change a row's or card's background on hover, and do not add CSS transitions or animations to them. Reserve hover feedback for text-link color changes. - **Inline labels:** plain text, bold for emphasis. Do not wrap labels (tags, statuses, transports, counts) in pill, capsule, chip, or rounded badge shapes; a label is text, not a button. ### Inputs / Fields - **Style:** square native fields, white or theme-defined background, `1px solid #aaa` by default. - **Focus:** border shifts to the theme focus color, such as Yotsuba `#ea8`. - **Sizing:** preserve compact desktop sizes; on mobile, raise text size where needed to prevent browser zoom. ### Navigation - **Boards bar:** compact slash-separated board links, small text, theme separators, no pill navigation. - **Pagination:** small flat cells using theme background and border colors. - **Directory navigation:** preserve classic board code patterns such as `/a/`, `/b/`, and category groupings. ### Posts And Replies - **Post metadata:** compact inline text, subject red, name green, timestamps, IDs, roles, and action links in the expected order. - **Replies:** theme-colored blocks with square borders and minimal padding. - **Greentext and quote links:** preserve classic color behavior and hover states. - **Media:** thumbnails should fit the existing imageboard layout and should not create modern card previews unless the current surface already uses that pattern. - **Emoji and text faces:** pass post text through as raw Unicode. Do not add an emoji picker, shortcode/emote system, or Twemoji-style emoji rendering. Kaomoji and ASCII / Shift-JIS art are the native text-face vocabulary; preserve them and their alignment where used. See `PRODUCT.md` → Text and Expression for the rationale. ### Modals And Popovers - **Style:** compact movable bars, square borders, theme backgrounds, and legacy close icons where available. - **Copy:** short labels and direct status messages. - **Behavior:** custom features such as challenges, settings, and posting flows should feel like imageboard utilities, not app dialogs. ## Do's and Don'ts ### Do - Start UI changes by checking the closest established imageboard behavior and the existing 5chan implementation. - Preserve theme variables and add new variables only when a new role is genuinely needed. - Keep layouts dense, square, and text-first. - Make decentralized concepts understandable without redesigning the familiar browsing flow. - Verify desktop and mobile because 5chan intentionally has different post and control treatments across viewports. ### Don't - Do not modernize core imageboard UI for taste. - Do not add rounded cards, gradient hero areas, glass panels, soft shadows, dark-mode defaults, or large marketing sections to product surfaces. - Do not use pill, capsule, chip, or rounded badge shapes for labels, tags, statuses, transports, or counts. - Do not add hover background fills, color fades, or CSS transitions/animations to rows, cards, or list items. - Do not replace compact text links with large icon-button toolbars unless the existing surface already uses that pattern. - Do not introduce a new design system that competes with Yotsuba, Yotsuba B, Futaba, or the existing theme variable model. - Do not make Bitsocial, crypto, or decentralization visuals dominate routine browsing. - Do not add an emoji picker, emoji shortcode/emote system, or Twemoji-style emoji rendering; emoji pass through as raw Unicode only. ``` --- ## src/AGENTS.md Source: https://github.com/bitsocialnet/5chan/blob/master/src/AGENTS.md ```markdown # src/AGENTS.md These rules apply to `src/**`. Follow the repo-root `AGENTS.md` first, then use this file for code inside the application source tree. - Before adding new state, decide whether it belongs in render, a reusable hook, or a Zustand store. Do not duplicate the same state logic across views. - Use `@bitsocial/bitsocial-react-hooks` for data access. Do not add data-fetching `useEffect` calls or effects that only synchronize derived state. - For state/effect/data-flow or rendering-performance changes, review relevant React guidance. Choose checks and browser/viewports using `docs/agent-playbooks/verification.md`; a copy edit alone does not require React Doctor or a full build. - Prefer extending nearby tests under `src/**/__tests__/` when touching already-covered behavior. ## Module boundaries `yarn boundaries` (run by `yarn lint`, so also by `yarn agent:verify` and CI) checks these rules over static imports, re-exports, dynamic `import()`, `import.meta.glob()` patterns and stylesheet `@import` rules; `__tests__/` folders and `*.test.*` files are skipped. Fix a reported violation by moving code, not by widening the import. There is no allowlist: if a rule conflicts with the requested change, restructure within scope or raise it with the user rather than editing the checker. - Dependencies flow one way: `constants`/`data`/`types`/`generated` → `lib`/`plugins` → `stores` → `hooks` → `components` → `views` → the root files (`app.tsx`, `index.tsx`, `bootstrap.ts`, `sw.ts`) and the `e2e/` harnesses. A lower layer never imports a higher one; when a `lib` helper needs a type or function that lives in a hook or component, the shared part belongs in `lib`. - `views`, `components`, `hooks`, `stores`, `constants`, `data`, `plugins`, `types`, `generated`, `lib`, and every folder directly under `lib` (`lib/utils`, `lib/media-hosting`, ...) are category folders, not modules. A folder inside one (`components/post-form`, `lib/media-hosting/`) is a module, and its subfolders are private to it; a nested folder is likewise private to its parent, so a module reaches its own sub-modules only through their index. - Import a module only through its `index.ts` (`../../components/post-form`), never its inner files, subfolders, or stylesheets. A file that sits directly in a category folder (`lib/utils/url-utils.ts`, `hooks/use-directories.ts`) and anything under `data/` may be imported directly. Anything used by more than one module lives at category level (`components/`). - Views never import other views, their stylesheets included. Shared page layout or styles go in a `components/` module. - Every route target is a top-level view at `views/`. A subfolder of a view is a private section of that view, not a route. - Keep the import graph acyclic. When two modules need each other, pass the dependency in as a prop or a context provided by the parent, or move the shared part down a layer. ``` --- ## scripts/AGENTS.md Source: https://github.com/bitsocialnet/5chan/blob/master/scripts/AGENTS.md ```markdown # scripts/AGENTS.md These rules apply to `scripts/**`. Follow the repo-root `AGENTS.md` first, then use this file for automation and workflow helpers. - Keep scripts non-interactive and idempotent. Print the command, URL, branch, or path being acted on so failures are diagnosable. - Use repo-relative paths and environment variables instead of user-specific absolute paths. - For dev-server helpers, default to `https://5chan.localhost`, but allow a branch-scoped `*.5chan.localhost` route when the launcher is avoiding a Portless name collision. Start the Portless HTTPS proxy on port 443 before registering routes so legacy `~/.portless` state on port 1355 is not reused. Respect the existing `PORTLESS=0` fallback instead of hard-coding alternate ports. For USB Android preview, `scripts/start-android-usb.mjs` mirrors bitsocial-web: `adb reverse` plus Vite on `127.0.0.1`, then `am start` VIEW to open the default browser when the port is listening (disable with `ANDROID_USB_OPEN_BROWSER=0`). - Keep shell helpers thin. When logic becomes stateful or cross-platform, prefer a Node script. - `scripts/pw-session.sh` owns the machine-wide Playwright resource lock shared by every worktree and checkout, so its default lock path must stay repository-independent. Keep acquisition atomic, treat `playwright-cli list --all` as the only liveness oracle and leave the lock alone when it cannot be read, require exact-owner release, and close the named browser before normal release; never broaden cleanup to unrelated sessions. - Git and worktree helpers must validate input and default to safe operations. - If a helper deletes local branches automatically, document the exact eligibility checks and keep the behavior conservative. ``` --- ## docs/agent-playbooks/known-surprises.md Source: https://github.com/bitsocialnet/5chan/blob/master/docs/agent-playbooks/known-surprises.md ```markdown # Known Surprises This file tracks repository-specific confusion points that caused agent mistakes. ## Entry Criteria Add an entry only if all are true: - It is specific to this repository (not generic advice). - It is likely to recur for future agents. - It has a concrete mitigation that can be followed. If uncertain, ask the developer before adding an entry. ## Entry Template ```md ### [Short title] - **Date:** YYYY-MM-DD - **Observed by:** agent name or contributor - **Context:** where/when it happened - **What was surprising:** concrete unexpected behavior - **Impact:** what went wrong or could go wrong - **Mitigation:** exact step future agents should take - **Status:** confirmed | superseded ``` ## Entries ### 5archive rejects branch-scoped dev origins - **Date:** 2026-09-13 - **Observed by:** Tommaso + Claude - **Context:** Browser-verifying `/search/` changes from a task worktree, which the launcher served at a branch-scoped route (`https://codex-feature-search-board-results.5chan.localhost`). - **What was surprising:** Every `api.5archive.org` request failed in the browser with `net::ERR_FAILED` and `/search/` showed "The search provider is unavailable", while `curl` from the shell answered normally. The indexer only sends `access-control-allow-origin` for `https://5chan.localhost` and `https://5chan.app`, and the launcher picks a branch-scoped portless name for any non-master branch, so a worktree never gets an allowed origin. - **Impact:** Anything that calls the indexer looks broken in every worktree browser check; an agent can burn time debugging the client or report a working change as failing. - **Mitigation:** Confirm the cause with `curl -s -D - -o /dev/null -H "Origin: https://" https://api.5archive.org/api/communities | grep -i access-control`. For the browser check, serve the worktree on the canonical route when it is free (`NODE_EXTRA_CA_CERTS=~/.portless/ca.pem corepack yarn exec portless 5chan vite` from the worktree) and open `https://5chan.localhost`; stop that server afterwards. Do not treat the failure as a client bug. - **Status:** confirmed ### `yarn changelog` regenerates every release and reverts the changelog rebrand - **Date:** 2026-09-12 - **Observed by:** Claude Opus 5 - **Context:** Preparing the `v0.9.20` release with the `release` skill, which instructs running `corepack yarn changelog`. - **What was surprising:** The script is `conventional-changelog -p angular -i CHANGELOG.md -s -r 0`. The `-r 0` flag regenerates *every* release section from raw commit messages, not just the new one. Commit `cdfeb13` had hand-edited 90 lines of `CHANGELOG.md` to scrub pre-rebrand terminology (`subplebbit` -> `community`, `plebbit-js` -> `bitsocial-js`, `Plebbit.` -> `Bitsocial.`), and those edits exist only in the file: the underlying commit subjects still carry the old words. - **Impact:** Running the documented command reintroduces 45 `plebbit`/`subplebbit` references into historical entries, silently undoing the rebrand inside the release commit itself. Confirmed by diffing a dry run against the committed file. - **Mitigation:** Do not run `corepack yarn changelog` as-is. Generate only the new section with `corepack yarn exec conventional-changelog -p angular` (no `-i`, `-s` or `-r`), prepend it to `CHANGELOG.md`, then verify the untouched remainder is byte-identical to the previous file before committing. The generated section already ends with the three blank lines the file uses between releases, so plain concatenation preserves the format. The durable fix is to drop `-r 0` from the `changelog` script in `package.json` so it only ever prepends. - **Status:** confirmed ### AI hook payloads and concurrent locale writes need behavioral checks - **Date:** 2026-09-11 - **Observed by:** contributor + Codex - **Context:** Approved audit of the repository's AI workflows for GPT-6 Astra. - **What was surprising:** Mirrored hook files passed parity checks while Codex supplied patch text in `tool_input.command`, not `file_path`. Stop hooks also mutated Git and repeated builds. Per-key translator agents rewrote the same locale files concurrently. - **Impact:** Edit hooks could silently skip work; routine conversations could trigger unrelated work; overlapping locale writers could lose keys. - **Mitigation:** Keep only the payload-tested formatter on edit events, use explicit `agent:verify`, and apply translation maps serially with the writer lock. Run `ai-workflow:test` as well as schema/generated-file checks after workflow changes. - **Status:** confirmed ### Yarn Berry never runs `pre*`/`post*` hooks on user-defined scripts - **Date:** 2026-09-02 - **Observed by:** Tommaso + Claude - **Context:** Investigating why the vendored directory mirror in `src/data/5chan-directories/` went stale (it lacked `/r/` until a manual `yarn sync:directories`) even though `package.json` had `prebuild`/`prestart` entries that called `sync:directories` and `generate:assets`. - **What was surprising:** This repo uses Corepack-managed Yarn 4 (Berry), which by design does not run npm-style `pre