Skip to content

feat: P2P sharing layer (share, receive, relay)#27

Draft
patrickSupernormal wants to merge 9 commits intostackwalnuts:mainfrom
patrickSupernormal:fn-5-dof
Draft

feat: P2P sharing layer (share, receive, relay)#27
patrickSupernormal wants to merge 9 commits intostackwalnuts:mainfrom
patrickSupernormal:fn-5-dof

Conversation

@patrickSupernormal
Copy link
Copy Markdown

Summary

  • Package format 2.0: .walnut archives (tar.gz + manifest.yaml) with three scopes (full, bundle, snapshot), SHA-256 integrity, dual encryption (AES-256-CBC passphrase + RSA-4096 OAEP relay)
  • GitHub relay transport: Private repo as mailbox, sparse checkout, RSA keypair management, session-start hook for package notifications
  • Three new skills: alive:share (9-step packaging + relay push), alive:receive (14-step import with v1 backward compat), alive:relay (setup, peer add/accept, status)
  • Cross-platform: macOS (BSD tar, LibreSSL) + Linux (GNU tar, OpenSSL), stdlib-only python3

Files added/changed

File Purpose
scripts/alive-p2p.py Package creation, extraction, manifest, encryption utilities
scripts/relay-probe.py GitHub API probe for pending packages
scripts/migrate-relay.py v1 relay.yaml to v2 relay.json migration
hooks/scripts/alive-relay-check.sh SessionStart hook for relay notifications
hooks/scripts/alive-log-guardian.sh Fix: allow Write to non-existent log.md
hooks/hooks.json Register relay-check hook
skills/share/SKILL.md alive:share skill
skills/receive/SKILL.md alive:receive skill
skills/relay/SKILL.md alive:relay skill
skills/bundle/SKILL.md P2P share reference added
skills/capture-context/SKILL.md .walnut file detection in inbox

Design decisions

  • JSON state files (relay.json, state.json) replace bash-stdout serialization -- eliminates the v1 PEERS[] fragility (10 iterations in fn-3)
  • Hooks target current v2 pattern (bash + python3/node) -- portable to Node.js when Ben's rewrite lands
  • now.json never shipped in packages -- receiver regenerates from kernel source files
  • Relay push confirmation is skill-mediated (external guard only catches mcp__ tools)
  • Sensitivity enum: open / private / restricted (per bundles.md rule)

Architecture doc

Full design at _core/_capsules/p2p-design/p2p-design-draft-02.md in the stackwalnuts walnut.

Test plan

  • Create .walnut package (all 3 scopes) and verify manifest + checksums
  • Passphrase encryption round-trip (encrypt -> decrypt -> validate)
  • RSA encryption round-trip with test keypair
  • Relay setup: create repo, generate keys, configure sparse checkout
  • Relay push: share to peer's inbox via GitHub Contents API
  • Relay pull: receive packages from own inbox
  • Session-start hook: detect pending packages and inject notification
  • v1 backward compat: import format 1.1.0 package with path mapping
  • Cross-platform: verify on macOS (LibreSSL + BSD tar)

🤖 Generated with Claude Code

patrickbrosnan11-spec and others added 9 commits April 1, 2026 13:04
The log guardian hook blocked ALL Write operations to log.md, which
prevented creating log.md for brand-new walnuts. Now checks if the
file exists first -- only blocks Write to existing log.md files.
Edit (prepend) to existing log.md is still allowed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- sha256_file: hashlib-based hashing (no subprocess)
- safe_tar_create/extract: macOS-safe archiving with Zip Slip protection
- atomic_json_write/read: crash-safe state files via temp+fsync+rename
- detect_openssl: LibreSSL vs OpenSSL version and capability detection
- b64_encode_file: single-line base64 via openssl CLI
- parse_yaml_frontmatter: hand-rolled YAML parser matching generate-index.py

Stdlib only, no pip dependencies. CLI smoke-test interface included.

Task: fn-5-dof.2

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- create_package() stages files by scope (full/bundle/snapshot), generates
  manifest.yaml with SHA-256 checksums, produces .walnut tar.gz archive
- extract_package() validates manifest (format_version 2.x), verifies all
  checksums, rejects tampered/unlisted files
- encrypt_package() supports passphrase (AES-256-CBC, PBKDF2 600k iter) and
  RSA (random AES key wrapped with pkeyutl OAEP-SHA256) modes
- decrypt_package() auto-detects mode (payload.key present = RSA)
- sign_manifest() / verify_manifest() for RSA-SHA256 manifest signing
- Strips _kernel/_generated/, .alive/_squirrels/, active_sessions: from packages
- Pre-flight size warning at 35 MB (GitHub Contents API limit)
- Passphrase via WALNUT_PASSPHRASE env var, never CLI arg

Task: fn-5-dof.3

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- relay-probe.py: checks GitHub relay via `gh api` for new commits,
  fetches into sparse clone, counts pending .walnut inbox packages,
  checks peer reachability, writes state.json atomically. Exits 0
  always (safe for SessionStart hook with 10s timeout).
- migrate-relay.py: converts v1 relay.yaml (flat or nested format)
  to v2 relay.json. Handles missing v1, already-migrated, and partial
  config. Records migration metadata.
- Both import atomic_json_read/write from alive-p2p.py via importlib
  (hyphenated filename).

Task: fn-5-dof.4

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Probes GitHub relay for pending .walnut packages at session start
- Fast path exits immediately when no relay.json configured
- Uses inline python3 to read state.json (not json_field which reads HOOK_INPUT)
- Injects notification with package count when pending > 0, silent otherwise
- Exits 0 on any error (network, missing python3, corrupt config)
- Registered in hooks.json startup matcher with 10s timeout

Task: fn-5-dof.5
- Setup: RSA-4096 keypair generation, GitHub private repo creation,
  sparse checkout clone, relay.json + state.json config
- Add peer: collaborator invite, inbox directory, relay.json update,
  person walnut resolution
- Accept: invitation listing, public key fetch, bidirectional
  auto-invite with confirmation
- Status: relay health, key permissions, peer reachability, clone state
- All external actions gated by confirmation prompts (external guard
  hook only catches mcp__ tools, not Bash)
- V1 migration support via migrate-relay.py
- Bordered blocks with squirrel visual conventions throughout

Task: fn-5-dof.6
14-step receive flow with three entry points (direct file, inbox scan,
relay pull). Handles encryption detection (passphrase/RSA), SHA-256
checksum verification, manifest signature validation, path safety
checks, scope-based routing (full/bundle/snapshot), conflict handling
for bundle merges, v1 format 1.1.0 backward compatibility with path
mapping, log entry via Edit (prepend), and now.json regeneration.

Task: fn-5-dof.8
- 9-step flow: scope, bundle picker, sensitivity gate, confirmation,
  encryption, package creation, output, metadata update, relay push
- Sensitivity gate blocks restricted/PII content without confirmation
- Passphrase via env var (never CLI arg, never disk)
- Relay push reads peers from state.json, confirms before GitHub API
- Account routing per platforms.md for GitHub API calls
- Pre-flight size check warns > 35MB for relay

Task: fn-5-dof.7
- Verify hooks.json: alive-relay-check.sh correctly registered in SessionStart:startup
- Update bundle/SKILL.md: add /alive:share reference for P2P packaging in Share section
- Update capture-context/SKILL.md: detect .walnut files in 03_Inputs/ inbox scan, suggest /alive:receive

Task: fn-5-dof.9
@patrickSupernormal patrickSupernormal marked this pull request as draft April 1, 2026 05:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants