Files
gbrain/skills/publish/SKILL.md
Garry Tan baf3517868 feat: v0.9.0 -- smart file storage, publish, production-grade skills (#62)
* feat: battle-tested skill patterns from production deployment

Backport production-learned brain-operations patterns:
- Iron Law of Back-Linking (mandatory bidirectional linking)
- Brain filing rules (file by primary subject, not format)
- Enrichment protocol (7-step pipeline, 3-tier system, person/company templates)
- Media ingest workflows (articles, videos, podcasts, PDFs, screenshots)
- Citation requirements (mandatory [Source: ...] on every fact)
- Test Before Bulk operating principle
- Voice recipe: unicode crash fix, PII scrub, identity-first prompt, DIY STT+LLM+TTS
- X-to-Brain recipe: image OCR, Filtered Stream, tweet rating rubric, cron stagger

* chore: bump version and changelog (v0.8.1)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add _brain-filing-rules.md to CLAUDE.md key files

* feat: smart file upload with TUS resumable and .redirect.yaml pointers

- Supabase Storage auto-selects upload method by file size:
  < 100 MB standard POST, >= 100 MB TUS resumable (6 MB chunks + retry)
- Signed URL generation for private bucket access (1-hour expiry)
- New `upload-raw` command with size routing: small text stays in git,
  large/media files go to cloud with .redirect.yaml pointer
- New `signed-url` command for generating access links
- File resolver supports both .redirect.yaml (v0.9+) and .redirect (legacy)
- Redirect format upgraded: 10 fields with full metadata
- All migration commands (mirror, redirect, restore, clean) handle both formats

* feat: skills reference actual gbrain file commands

- Filing rules document upload-raw, signed-url, and .redirect.yaml format
- Ingest skill uses gbrain files upload-raw for raw source preservation
- Maintain skill adds file storage health checks
- Setup skill adds storage configuration phase with migration guidance
- Voice recipe uses upload-raw for call audio storage
- Migration v0.9.0 with complete storage setup instructions

* chore: bump version and changelog (v0.9.0)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: gbrain publish -- shareable HTML with password protection

First code+skill pair: deterministic code does the work (strip private data,
encrypt with AES-256-GCM, generate self-contained HTML), the skill tells the
agent when and how to use it. 34 new tests.

See: https://x.com/garrytan/status/2042925773300908103

* feat: backlinks check/fix, page lint, and report commands

Three new deterministic tools (zero LLM calls):

- gbrain backlinks check/fix -- scans brain for entity mentions without
  back-links, creates them. Enforces the Iron Law from the skills.
- gbrain lint [--fix] -- catches LLM preambles, code fence wrapping,
  placeholder dates, missing frontmatter, broken citations, empty sections.
  --fix auto-strips fixable artifacts.
- gbrain report --type <name> -- saves timestamped reports to
  brain/reports/{type}/YYYY-MM-DD-HHMM.md for audit trails.

33 new tests (409 total, 0 fail).

* feat: v0.9.0 migration tells agents to swap scripts for built-in commands

Migration file now:
- Lists all 5 new deterministic commands with usage examples
- Includes a script-to-command replacement table (old -> new)
- Tells the agent to find custom script references in AGENTS.md,
  skills, and cron jobs and replace with gbrain commands
- Adds recommended cron jobs for daily backlink fix + weekly lint
- References the Thin Harness, Fat Skills thread

* fix: CLI routing bugs found during DX review

- Fixed subArgs reference error in handleCliOnly (used wrong variable name)
- Renamed gbrain backlinks check/fix to gbrain check-backlinks to avoid
  conflict with existing backlinks operation (per-page incoming links)
- Added TOOLS section to --help output showing publish, check-backlinks,
  lint, report
- Added upload-raw and signed-url to FILES section in --help
- Updated all docs/migration references to use check-backlinks

* fix: security hardening from adversarial review

- XSS: sanitize marked.parse() output (strip script/iframe/on* attrs)
- Path traversal: validate report --type against [a-z0-9-] pattern
- TUS: HEAD request before retry to get server's actual offset (TUS spec)
- Pointer: upload-raw now includes pointer content in JSON output
- Symlinks: use lstatSync in all walkers to prevent directory escape

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 21:46:07 -10:00

4.2 KiB

Publish Skill

Share brain pages as beautiful, self-contained HTML documents. Optionally password-protected with client-side AES-256-GCM encryption. No server needed.

This is a code + skill pair: the deterministic code (gbrain publish) does the stripping, encrypting, and HTML generation. This skill tells you when and how to use it. See Thin Harness, Fat Skills for the architecture philosophy.

When to Publish

  • User asks to share a brain page, create a shareable link, or says "give me a page"
  • User wants to send a deal memo, person briefing, or research to someone external
  • User asks to publish a data room analysis or trip plan
  • Any time brain content needs to leave the brain without exposing the whole system

Default: ALWAYS ENCRYPT

Brain content is private. Default to password-protected unless the user explicitly says "open", "no password", or "public".

If no password is specified, auto-generate one. Share the password via a different channel than the URL.

Quick Reference

# Basic publish (outputs local HTML file)
gbrain publish brain/companies/acme.md

# Password protected (auto-generate password)
gbrain publish brain/companies/acme.md --password

# Password protected (specific password)
gbrain publish brain/companies/acme.md --password "secret123"

# Custom title
gbrain publish brain/companies/acme.md --password --title "Acme -- Deal Analysis"

# Custom output path
gbrain publish brain/companies/acme.md --out /tmp/acme-share.html

What Gets Stripped

The publish command automatically removes all private/internal data:

Stripped Example Why
YAML frontmatter title:, type:, tags: Internal metadata
[Source: ...] citations All formats Provenance is internal
Confirmation numbers ABC123DEF -> "on file" PII/booking data
Brain cross-links [Jane](../people/jane.md) -> Jane Internal paths
Timeline section Everything below --- / ## Timeline Raw evidence log
"See also" lines Internal references Brain navigation

Preserved: external URLs (https://...), all other content.

Sharing Workflows

Option A: Local file (simplest)

gbrain publish brain/people/jane-doe.md --password --out ~/Desktop/jane-briefing.html

Share the HTML file via email, Slack, Airdrop. Share the password separately.

Option B: Upload to cloud storage

# Publish locally first
gbrain publish brain/companies/acme.md --password "secret" --out /tmp/acme.html

# Upload to Supabase Storage
gbrain files upload /tmp/acme.html --page shares/acme

# Get a signed URL (1-hour expiry)
gbrain files signed-url shares/acme/acme.html

Share the signed URL + password. URL expires in 1 hour. Re-generate as needed.

Option C: Static hosting (Render, Netlify, S3)

Upload the HTML file to any static hosting service. The file is self-contained, no server logic needed. Password-protected files work entirely client-side via Web Crypto API.

Option D: GitHub Pages / Gist

gbrain publish brain/trips/japan-2026.md --out trip.html
# Upload to a GitHub Gist or Pages repo

Password Protection Details

  • Algorithm: AES-256-GCM
  • Key derivation: PBKDF2 with 100K iterations, SHA-256
  • Salt: Random 16 bytes per encryption
  • IV: Random 12 bytes per encryption
  • Decryption: Client-side via Web Crypto API (SubtleCrypto)
  • No server auth needed -- the HTML file is self-contained
  • "Remember on this device" -- saves password in localStorage

When encrypted, the published HTML contains ONLY ciphertext. The plaintext is not present anywhere in the file.

Updating a Published Page

Re-run the publish command with the same output path:

gbrain publish brain/companies/acme.md --password "same-password" --out shares/acme.html

Same file, same URL (if hosted), updated content.

Revoking Access

Delete the file. If using signed URLs, the URL expires automatically (1 hour). If using static hosting, remove the file from the host.

Tools Used

  • gbrain publish -- deterministic HTML generation (no LLM calls)
  • gbrain files upload -- upload to cloud storage (optional)
  • gbrain files signed-url -- generate access links (optional)