Skip to content

About

No description, website, or topics provided.

Resources

Contributing

Stars

14 stars

Watchers

0 watching

Forks

Latest commit

 

History

361 Commits

Folders and files

Repository files navigation

Nostr Compass

Technical resource for the Nostr protocol. A weekly newsletter covering NIP proposals, client updates, relay developments, and notable code changes; a weekly podcast with the developers whose work each issue covers; and a topic index documenting protocol concepts with links to primary sources.

Published at nostrcompass.org in ten languages, and to Nostr as a NIP-23 long-form article. All materials MIT licensed.

Repository layout

content/<lang>/       Hugo content. en is authoritative; the other nine are translations.
  newsletters/        One file per issue, YYYY-MM-DD-newsletter.md
  topics/             Topic and NIP reference pages
data/
  projects.yml        Tracked projects: repo, website, category, npub
  npubs.yml           Verified Nostr identities and their roles
  nip34_tracked.yml   NIP-34 repositories whose subject matter is Nostr
  newsletter_workspace/  Per-issue editorial record (triage, reviews, publication logs)
  <fetcher>/          Fetcher output, regenerated weekly and gitignored
publish/              Publication pipeline (Bun/TypeScript). Signs and broadcasts to Nostr.
scripts/              Discovery fetchers, editorial gates, translation, build
skills/_COMPASS/      Agent definitions for the weekly editorial workflow
tests/                Python tests for scripts/
layouts/ assets/ i18n/ static/   Hugo theme

CLAUDE.md holds the editorial rules every issue must satisfy. AGENTS.md describes the weekly workflow stages. STRATEGY.md covers direction and audience.

Development

bun install
bun run build            # full build including Pagefind search index, output in public/
hugo server              # live reload at localhost:1313, no search index
docker-compose up        # same, containerised

bun run build reserves two CPU cores for headroom. Override with BUILD_HEADROOM_CORES=<n>, or cap directly with BUILD_MAX_CORES=<n>.

Tests

python3 -m unittest discover -s tests    # scripts/
bun test                                 # publish/ and scripts/*.test.ts

Weekly workflow

Discover. scripts/fetch_all.sh runs every fetcher: tracked-repository releases and merged PRs, NIP discussions, NIP-34 repositories, Zapstore listings, NIP-89 application handlers, and a GitHub sweep for projects Compass does not track yet. It finishes by writing data/newsletter_workspace/release_digest_<date>.md, which names every release in the window so a release cannot exist in the data and in no editorial artifact.

Use one explicit --pass-id with absolute --since/--until bounds. Before starting, inspect REST core, GraphQL, and search separately with gh api rate_limit. The tracked-project sweep uses roughly 3,650 REST-core requests, and app discovery then spends about one more core request for each distinct tracked GitHub owner (418 on 2026-09-16), for roughly 4,100 before unrelated same-hour traffic. Require enough core budget for both plus the 500-request guard reserve. Never run two collectors against the same artifact or repeat --fresh after an immutable receipt exists. Invoke fetch_all.sh exactly once per pass; do not run a standalone project collector and then replay it through fetch_all.sh. Resume the pass, use a receipt-producing GraphQL collector for bounded verification, or wait for the recorded reset rather than burning the same REST window repeatedly. If a receipt/artifact conflict has already made an unfinalized pass unusable, abandon it and use one new pass ID over the same frozen window while resuming the completed project journal without --fresh.

App discovery automatically moves its exhaustively paginated tracked-owner sweep to GraphQL when REST core cannot cover all owners plus the reserve and the separate GraphQL budget can. If neither bucket can finish, it returns source_errors and must not satisfy the family gate. Wait for the recorded reset and resume that missing family under the same pass/window; do not treat partial discovery JSON as a receipt.

Cross-run discovery baselines live under $COMPASS_STATE_DIR (default /opt/data/compass-state), deliberately outside the repository. Each issue is drafted in its own worktree, and a baseline stored inside a fresh worktree starts empty, which makes every project look new and suppresses real signal. Run scripts/migrate_discovery_state.py after adding a worktree or moving that state.

Triage and select. Every release in the digest needs a written-up-or-skipped decision recorded in data/newsletter_workspace/. A project may be omitted only when the previous issue already covered it and it shipped nothing substantive; the digest computes that as suppression_allowed. This gate blocks:

python3 scripts/check_triage_coverage.py \
  --digest data/project_updates/release_digest_<date>.json \
  --triage data/newsletter_workspace/triage_<date>.md

Write and check. Draft into content/en/newsletters/<date>-newsletter.md. The blocking gates:

python3 scripts/check_newsletter_style.py <file>            # filler, opaque advisory anchors
python3 scripts/check_newsletter_continuity.py <file>       # back-references resolve
python3 scripts/check_newsletter_paragraph_links.py <file>  # every claim is sourced
python3 scripts/check_newsletter_event_examples.py <file>   # example events are valid
python3 scripts/check_topic_backlinks.py                    # topic pages link the issue
python3 scripts/check_month_end_history.py <file>           # month-end retrospective rules
bun run check:npubs                                         # identities and roles

Publish. Publication is journal-driven: parse and ingest exact-head quality, feedback, and Wednesday authorization receipts; merge the pinned PR; verify the exact Pages deployment; then sign, broadcast, independently recover both Nostr events from at least five durable relays, and project the evidence log:

bun publish/publish.ts <issue> --stage all \
  --pr-number <pr> --head-sha <head> --base-sha <base> \
  --page-url https://nostrcompass.org/en/newsletters/<date>-newsletter/ \
  --quality-receipt-dir <review-receipts> --feedback-receipt <feedback.json> \
  --authorization-receipt <edition-authorization.json> \
  --really-merge --really-broadcast

The --really-* switches confirm an operator intends to execute a prepared effect; they grant no authority. publish/out/<issue>/state.json must already contain matching, byte-hashed receipts and exact identities. Signing is refused until merge and deployment are confirmed, and broadcasting is refused until both exact signed payloads are retained. The log stage derives data/newsletter_workspace/publish_log_<date>.md from the run's own receipts, the matched Pages deploy, and a fresh relay readback, then opens a PR for it. See publish/README.md for stages and configuration, and publish/BUNKER.md for the NIP-46 remote-signing session.

Signing keys are never in this repository. The pipeline holds a NIP-46 session against an external signer; the bunker URI and client key live in ~/.config/compass-publish/.

Translate. After publication, into all nine other languages:

bash scripts/translate.sh next                 # oldest published issue still untranslated
bash scripts/translate.sh commit <lang> <date> # checkpoint one language
bash scripts/translate.sh ship <date>          # push, open PR, merge on green

Cross-newsletter back-references inside a translation keep their /en/ path, because their anchors are English heading slugs.

Contributing

See the contributing guidelines. Newsletter PRs are kept to exactly one commit; update one by squashing and force-pushing with --force-with-lease.

If you build on Nostr and would like to contribute or appear on the podcast, reach out via NIP-17 DM to npub1wav4fae3gyfy3xj298kxj2mj8phavz7vavps34przq02j7w902qq902923.

Deployment

GitHub Actions builds and deploys to GitHub Pages on every push. Custom domain nostrcompass.org; DNS A records point at the GitHub Pages addresses (185.199.108-111.153). Repository settings: Pages source "GitHub Actions", and github-pages environment deployment branches set to "All branches".

License

MIT.

About

No description, website, or topics provided.

Resources

Contributing

Stars

14 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages