Files
5chan/docs/agent-playbooks/known-surprises.md
T
Tommaso CasaburiandGitHub 85b782e934 feat(electron): sign and notarize mac release builds (#1171)
* feat(electron): sign and notarize mac release builds when Apple credentials are present

* fix(electron): work around codesign PID parsing for digit-leading app name in @electron/notarize

codesign interprets a bare '5chan.app' argument as process ID 5, so
@electron/notarize 2.5.0's pre-upload signature check fails with 'No such
process'. Backport the './' basename prefix from electron/notarize#245 as
a yarn patch until forge depends on notarize >= 3.x.

* docs(agent-playbooks): record codesign PID parsing surprise for digit-leading app name

* fix(ci): keep mac signing env consistent with certificate availability
2026-06-13 15:26:31 +07:00

12 KiB

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

### [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

react-doctor score reflects React-Compiler coverage, not code health — do not chase it

  • Date: 2026-06-05
  • Observed by: Tommaso + Claude
  • Context: Trying to raise the yarn doctor (react-doctor) score to 90 (PR #1155).
  • What was surprising: The score is overwhelmingly driven by React-Compiler optimizability diagnostics, not code quality. Most of the ~92 "errors" are the react-hooks-js plugin flagging valid, idiomatic code the React Compiler (v1.0) cannot optimize yetrefs (the deliberate latest-ref idiom for a stable callback) and todo (try/finally and throw-in-try/catch the compiler can't lower). The score also saturates on the fraction of files with zero diagnostics: removing 150 warnings moved it +1; suppressing all 76 compiler-bailout errors reached only 63; only suppressing essentially every rule reaches 90.
  • Impact: Agents/contributors can burn large effort (and risk real regressions) "fixing" the score by rewriting correct code into compiler-friendly-but-worse shapes, or by suppressing rules until the badge is meaningless. ~63 is the honest, no-regression ceiling.
  • Mitigation: Do NOT treat the aggregate react-doctor score as a target to grind up (the README badge was removed for this reason). Use react-doctor as a PR-diff reviewer — yarn doctor --diff <base> --annotations, already wired in .github/workflows/ci.yml — to catch newly introduced issues. doctor.config.jsonc deliberately does not enforce the react-hooks-js rules or react-compiler-no-manual-memoization (intentional patterns / current compiler limits). Only fix genuine bugs (e.g. clean no-adjust-state-on-prop-change cases). Full reasoning: docs/agent-runs/react-doctor-score/.
  • Status: confirmed

Portless 0.11 reuses legacy proxy state unless the launcher forces HTTPS

  • Date: 2026-04-28
  • Observed by: Tommaso + Codex
  • Context: Upgrading the normal yarn start flow from the old http://5chan.localhost:1355 proxy URL to https://5chan.localhost.
  • What was surprising: Even with portless@0.11.1 installed, Portless reused the existing ~/.portless/proxy.port = 1355 HTTP proxy and printed the legacy :1355 URL.
  • Impact: Updating package versions and docs is not enough; yarn start can still advertise and use the old URL when a contributor has legacy Portless state running.
  • Mitigation: Keep scripts/start-dev.js explicitly starting the Portless HTTPS proxy on port 443 before registering the app route, so the runtime flow migrates away from persisted 1355 state instead of inheriting it.
  • Status: confirmed

Android release signing still uses legacy keystore names

  • Date: 2026-04-23
  • Observed by: Codex
  • Context: Cutting the v0.8.0 release after the core terminology rename changed release workflow signing references.
  • What was surprising: The tracked Android release keystore is still android/plebbit.keystore, and the available GitHub secret is still PLEBBIT_REACT_KEYSTORE_PASSWORD; changing only the workflow references to bitsocial.keystore / BITSOCIAL_KEYSTORE_PASSWORD made the Android release artifact fail at signing.
  • Impact: Tag releases can pass the Android build and then fail before publishing because apksigner cannot find the keystore or password secret.
  • Mitigation: Until the keystore migration is done, keep release APK signing pointed at android/plebbit.keystore and PLEBBIT_REACT_KEYSTORE_PASSWORD. If renaming, migrate the tracked file, workflow path, and GitHub secret in one change and verify with a tag release dry run or full release.
  • Status: confirmed

5chan consumes a pinned hooks tarball instead of using the local hooks repo

  • Date: 2026-04-15
  • Observed by: Codex
  • Context: Debugging strict {name, publicKey} community refs after upstream fixes landed in bitsocial-react-hooks
  • What was surprising: 5chan does not consume the nearby /Users/Tommaso/Desktop/bitsocial/bitsocial-react-hooks checkout by default; package.json installs a pinned GitHub tarball of @bitsocialnet/bitsocial-react-hooks.
  • Impact: Agents can wrongly assume local hooks source changes are already active in 5chan, or debug the wrong package build when the app is really running a tarball revision from GitHub.
  • Mitigation: Before debugging hooks behavior from 5chan, check package.json to see whether the app points at a tarball commit or a local path. If you need fresh hooks behavior, update the tarball commit or temporarily switch 5chan to a local path intentionally.
  • Status: confirmed

Hooks source commits can land before the generated tarball payload

  • Date: 2026-04-18
  • Observed by: Codex
  • Context: 5chan CI failed after expandTimeWindow landed in bitsocial-react-hooks because the app was pinned to the feature source commit.
  • What was surprising: bitsocial-react-hooks uses dist/ as its published entrypoint, and the repo's CI writes that generated payload in a follow-up chore(ci): update dist and coverage badge commit after the source commit lands on master.
  • Impact: Pinning 5chan to the feature source SHA can install a tarball whose runtime and typings still omit the new API, causing downstream type errors even though the hooks repo's source and CI look green.
  • Mitigation: When updating 5chan to a new hooks change, verify whether hooks master has a newer follow-up chore(ci): update dist and coverage badge commit and pin 5chan to that dist-synced SHA rather than the source-only SHA.
  • Status: confirmed

Portless breaks Windows installs

  • Date: 2026-03-04
  • Observed by: Codex
  • Context: GitHub Actions Test Windows dependency install on windows-2022
  • What was surprising: portless@0.5.2 is a local dev-only tool, but keeping it in devDependencies makes yarn install fail on Windows because the package declares win32 unsupported.
  • Impact: Windows CI fails before build steps run, even though the app does not need portless there.
  • Mitigation: Keep portless in optionalDependencies and make yarn start fall back to direct vite startup when portless is unavailable.
  • Status: confirmed

Electron RPC uses direct pkc-js imports

  • Date: 2026-03-07
  • Observed by: Codex
  • Context: The desktop bootstrap now imports @pkcprotocol/pkc-js/rpc directly from electron/start-pkc-rpc.js.
  • What was surprising: Most app data access still goes through @bitsocialnet/bitsocial-react-hooks, but the Electron-local RPC bootstrap is intentionally a direct pkc-js integration.
  • Impact: Agents may try to route Electron RPC back through hooks, or reintroduce the legacy protocol package name while fixing dependency/tooling warnings.
  • Mitigation: Keep Electron RPC on direct @pkcprotocol/pkc-js imports. If knip flags electron/start-pkc-rpc.js, audit the actual dependency graph before adding ignores or legacy packages.
  • Status: confirmed

Electron packaging can ship a broken better-sqlite3 binary

  • Date: 2026-03-17
  • Observed by: Codex
  • Context: Investigating the v0.7.1 macOS arm64 DMG after the app showed a live IPFS node but never loaded boards or comments.
  • What was surprising: The packaged app can start IPFS successfully while electron/start-pkc-rpc.js loops forever because /Applications/5chan.app/.../better_sqlite3.node was built for plain Node 22 (NODE_MODULE_VERSION 127) instead of Electron 36 (NODE_MODULE_VERSION 135).
  • Impact: The local RPC server on ws://localhost:9138 never starts, so the desktop app cannot load boards, posts, or comments even though node stats look healthy.
  • Mitigation: Before any Electron package/build job, run yarn electron:prepare-package so better-sqlite3 is rebuilt for Electron and immediately verified via ELECTRON_RUN_AS_NODE=1 electron.
  • Status: confirmed

Plain Vite fallback used to hard-fail on port 1355

  • Date: 2026-03-30
  • Observed by: Codex
  • Context: Running PORTLESS=0 yarn start while another local service already owned port 3000
  • What was surprising: The non-Portless dev fallback forced Vite onto 5chan.localhost with --strictPort, so the fallback path could fail immediately even though the main Portless flow is collision-safe.
  • Impact: Contributors could lose the fallback dev path or interrupt their startup flow when 3000 was already busy.
  • Mitigation: Keep the fallback behind scripts/start-dev.js, which now probes from 3000 upward and starts Vite on the next free port instead of exiting.
  • Status: confirmed

Fixed Portless app names collide across 5chan worktrees

  • Date: 2026-03-30
  • Observed by: Codex
  • Context: Starting yarn start in one 5chan worktree while another 5chan worktree was already serving through Portless
  • What was surprising: Using the literal Portless app name 5chan in every worktree makes the route itself collide, even when the backing ports are different, so the second process fails with "5chan.localhost" is already registered.
  • Impact: Parallel 5chan branches can block each other even though Portless is meant to let them coexist safely.
  • Mitigation: Keep Portless startup behind scripts/start-dev.js, which now uses a branch-scoped *.5chan.localhost route outside the canonical case and automatically increments a -2, -3, ... suffix when that branch-scoped route is already occupied.
  • Status: confirmed

Toolchain model names are not interchangeable

  • Date: 2026-04-08
  • Observed by: contributor + Codex
  • Context: Reviewing repo-managed agent configs under .codex/agents, .cursor/agents, and .claude/agents
  • What was surprising: composer-2 is only available for Cursor in this repo, while Codex agents using gpt-5.3-codex or gpt-5.3-codex-spark perform poorly enough that they should not be configured by default.
  • Impact: Agents can silently inherit invalid or weak model settings, leading to broken subagent runs or degraded implementation quality.
  • Mitigation: Keep .cursor agent configs on Cursor-supported models only, never use composer-2 in .claude, and standardize .codex/agents/*.toml on gpt-5.4 unless a contributor explicitly requests an override.
  • Status: confirmed

codesign parses "5chan.app" as process ID 5

  • Date: 2026-06-12
  • Observed by: contributor + Claude
  • Context: Running the first signed + notarized mac Electron build (yarn electron:build:mac:arm64 with Apple credentials set)
  • What was surprising: @electron/notarize 2.x runs its pre-upload signature check as codesign -dv 5chan.app from the bundle's parent directory, and codesign accepts a process ID in place of a path — so it parses the digit-leading basename as PID 5 and fails with 5chan.app: No such process even though the app is signed correctly.
  • Impact: Notarization aborts after a successful signing pass; the error message looks like a signing failure and invites debugging the certificate/keychain instead of the real cause. Any tool that shells out to codesign with a bare relative path can hit this because the app is literally named 5chan.
  • Mitigation: Keep the yarn patch .yarn/patches/@electron-notarize-npm-2.5.0-*.patch (backport of electron/notarize#245, prefixes the basename with ./) until electron-forge depends on @electron/notarize >= 3.x. When invoking codesign manually on the app bundle, always use an absolute or ./-prefixed path.
  • Status: confirmed