Editing a video with a newly-uploaded file produced a new content-addressed
object and orphaned the old one. editModalController.handleSubmit now removes the
old object (best-effort) when the hosted URL was genuinely replaced — guarded so
it only fires when both old and new URLs are present and different (so clearing
the URL, which may still be referenced by a magnet web-seed, never deletes it),
and it deliberately leaves thumbnails alone (the new note may still point at
them). Reuses R2Service.deleteVideoStorage (owned-objects-only, never throws).
Documented the cleanup contract in AGENTS.md §4a.
Test: tests/ui/edit-modal-storage-cleanup.test.mjs (3). Full suite green.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Removes the TORCH task-locking/scheduler-memory subsystem in full:
- delete torch/ (4900+ files), torch-config.json, and tracked .scheduler-memory/
- drop torch:* npm scripts and the torch-lock dependency; regenerate
package-lock.json (only torch-lock removed)
- strip the dead "TORCH Memory Integration" / "Task Claiming Protocol (TORCH)"
sections from AGENTS.md and CLAUDE.md (agent coordination is now PR-based) and
the torch/TORCH.md doc-table row
- drop the stale `torch` ignore entries from check-hex / check-inline-styles /
check-design-tokens
Build + touched lints pass. Note: views/dev/agent-dashboard.html still embeds
the external TORCH dashboard URL — left in place (separate dev-tools view).
Co-Authored-By: Claude Opus 4.8 <[email protected]>
buildR2Key fell back to a static "uploads" namespace (and "video" slug) when
no torrent info-hash was available, so two distinct URL-first uploads sharing a
filename produced the SAME R2/S3 key — the second silently overwrote the first
object while the first video note still pointed at that URL (data loss).
WebTorrent uploads were already safe because the info-hash namespaces the key.
Add computeStorageContentHash(file) in js/r2.js: when no info-hash is present it
derives a deterministic content-based namespace — full SHA-256 of the bytes for
files ≤512 MB (idempotent: re-uploading the same file reuses the key), and a
SHA-256 fingerprint over name/size/mtime + sampled head/tail bytes above that,
so we never buffer a multi-GB video in memory. Wired into BOTH upload paths
(r2Service + s3UploadService) via a new storageIdentifier kept separate from the
info-hash, so magnet generation is unchanged.
Test: tests/storage-key-collision.test.mjs (distinct same-named uploads get
distinct keys; same content is idempotent; large-file fingerprint path samples
edges without buffering and stays deterministic). Full unit suite green.
test_integrity_note:
change_type: ["new_tests"]
scenarios:
- id: SCN-upload-key-no-collision
given: "a URL-first upload with no torrent info-hash"
when: "the storage key is derived (computeStorageContentHash -> buildR2Key)"
then: "distinct same-named files get distinct keys, same content is idempotent, and no key uses the colliding 'uploads' namespace"
observable_outcomes:
- "returned key strings for real Blob/File content and a fake >512MB file"
determinism_controls:
- "fixed byte content; fake large file with stubbed slice() and fixed lastModified"
anti_cheat_rationale:
prevents:
- "hard-coded return value"
- "over-mocking internal logic"
relaxation:
did_relax_any_assertion: false
Co-Authored-By: Claude Opus 4.8 <[email protected]>
- Add 'Scenario-First Tests & Test Integrity' section to AGENTS.md
- Add 'Testing & Validation: Scenario-First, Cheat-Resistant' rules to CLAUDE.md
- Update docs/agents/prompts/daily/bitvid-test-audit-agent.md to serve as the 'Enforcer' agent, integrating the new Constitution and Mission while preserving operational steps.
- Ensure PR guidelines in the agent prompt require the 'Test Integrity Note'.
Co-authored-by: PR0M3TH3AN <[email protected]>
TORCH (Task Orchestration via Relay-Coordinated Handoff) is the name
for the Nostr-based distributed task locking system used to coordinate
multi-agent development.
Adds docs/agents/TORCH.md covering:
- Protocol overview with sequence diagram
- NIP-78 event schema with tag breakdown
- Ephemeral key lifecycle and why no secrets are needed
- Race detection mechanism
- Auto-expiration via NIP-40
- Configuration reference
- Architecture diagram
- Path toward a generalizable drop-in package for any repo
Also references TORCH by name in AGENTS.md, scheduler-flow.md,
nostr-lock.mjs header, and CLAUDE.md key documentation table.
https://claude.ai/code/session_01BpDsVSAkVWtJLnfKxsB9ib
Remove the git push and GitHub API fallback methods from the scheduler
flow, leaving only the Nostr lock as the single locking mechanism.
This significantly reduces the agent reasoning chain:
- scheduler-flow.md: 10 steps → 8 steps, single code path
- META_PROMPTS.md: 5 MUST blocks → 4, no jq pipeline or branching
- AGENTS.md: 3-method protocol → 2 commands (check + lock)
The agent no longer needs to parse jq output, decide between methods,
handle cascading fallbacks, or perform manual race detection. It runs
two scripts and checks exit codes.
https://claude.ai/code/session_01BpDsVSAkVWtJLnfKxsB9ib
Replace GitHub draft PR as the primary locking mechanism with Nostr
relay-based locks. Each agent generates an ephemeral keypair, publishes
a NIP-78 (Kind 30078) lock event with NIP-40 auto-expiration, and
discards the key. No tokens, no secrets, no git push required.
New script: scripts/agent/nostr-lock.mjs
- check: query relays for active locks, return JSON exclusion set
- lock: claim a task with built-in race detection (exit 3 = lost)
- list: human-readable table of all active locks
The locking fallback chain is now:
1. Nostr lock (no credentials needed, works in any sandbox)
2. git push + draft PR (traditional method)
3. GitHub API via curl (needs GITHUB_TOKEN)
Updated scheduler-flow.md, META_PROMPTS.md, and AGENTS.md to document
all three methods with Nostr as the preferred primary.
https://claude.ai/code/session_01BpDsVSAkVWtJLnfKxsB9ib
Jules agents cannot git push due to sandbox restrictions, which breaks the
draft PR-based distributed lock mechanism. Multiple agents can pick up the
same task because the claim is never visible remotely.
This adds scripts/agent/claim-task-api.sh which creates the remote branch,
started.md log file, and draft PR entirely via curl and the GitHub REST API,
bypassing git push. The scheduler-flow.md, META_PROMPTS.md, and AGENTS.md
are updated to document the fallback: try git push first, fall back to the
API script if push is blocked, fail-closed if neither method works.
https://claude.ai/code/session_01BpDsVSAkVWtJLnfKxsB9ib
Replace shared CSV files (AGENT_TASK_LOG.csv, WEEKLY_AGENT_TASK_LOG.csv)
with per-entry files in docs/agents/task-logs/{daily,weekly}/. Each log
entry is now a separate file named YYYY-MM-DD_HH-MM-SS_<agent>_<status>.md,
eliminating git merge conflicts and race conditions when multiple agents
run concurrently.
Updated files:
- daily-scheduler.md: rewritten for directory-based log format
- weekly-scheduler.md: rewritten for directory-based log format
- META_PROMPTS.md: updated pre-flight scan and claiming instructions
- AGENTS.md: updated scheduler reference from CSV to directory-based
Migrated all existing CSV entries to individual files in the new
directory structure.
https://claude.ai/code/session_01P62EWUXwupgxPhpnRejUuz
- Move `CONTEXT.md`, `TODO.md`, `DECISIONS.md`, `TEST_LOG.md` to `context/`, `todo/`, `decisions/`, `test_logs/` directories with timestamps.
- Update `AGENTS.md` and `CLAUDE.md` to define the new workflow: agents must read the latest timestamped file and create a new one when updating.
- Update `daily-scheduler.md` and `weekly-scheduler.md` to initialize tasks using the new file structure.
- Update all daily agent prompts to reference the new directory structure.
- This change prevents merge conflicts on persistent state files by treating them as an append-only log of snapshots.
Co-authored-by: PR0M3TH3AN <[email protected]>
When multiple agents (Claude Code, Codex, Jules) run schedulers concurrently,
they can pick up the same task because neither has committed yet. This adds a
"Draft PR Lock" protocol: agents must check for and create a draft PR before
starting work, acting as a distributed lock visible to all platforms.
Changes:
- AGENTS.md §12: new "Task Claiming Protocol" subsection with check/claim/race
handling steps
- daily-scheduler.md: new Step 1.5 with concrete gh CLI commands
- weekly-scheduler.md: same Step 1.5 addition
https://claude.ai/code/session_01Vnih5ZARbEmnh3EGTDQAXX
Introduces a structured meta-workflow for AI agents that ensures
safe incremental changes, persistent state across context resets,
and a clear decision trail for multi-agent coordination.
Key additions:
- Work scoping (goal, success criteria, non-goals)
- External notes files (CONTEXT.md, TODO.md, DECISIONS.md, TEST_LOG.md)
- Locate → Implement → Verify → Update notes work loop
- Context recovery procedure for new agent sessions
- Quality bar principles
- Cross-references from CLAUDE.md to the new section
https://claude.ai/code/session_0159eSJrqKvKpgDiwYZ2iGxK
Updates AGENTS.md and README.md to reflect the configurable hybrid playback strategy (URL vs. WebTorrent) instead of asserting a strict "URL-First" rule, which contradicted the default configuration.
- Updated "Mission" in AGENTS.md to "Hybrid Playback Strategy".
- Clarified that `DEFAULT_PLAYBACK_SOURCE` controls priority.
- Updated README.md "How playback works" section.
- Adjusted QA checklists to focus on "configured priority" rather than "URL-first".
Co-authored-by: PR0M3TH3AN <[email protected]>
Section 14 in AGENTS.md covers the full test harness API, mock relay
HTTP endpoints, Playwright fixture usage, and data-testid selector
reference. CLAUDE.md testing section updated with quick-start example.
https://claude.ai/code/session_01XnrszNmdqrAGd8g8qhAn4G
Three CI-enforced lint scripts to prevent common codebase growth problems:
- lint:file-size — enforces 1000-line max for new JS files, grandfathers
existing oversized files and prevents them from growing further
- lint:innerhtml — tracks innerHTML usage per-file with a baseline count,
blocks new innerHTML additions (guides agents toward safe DOM APIs)
- Relay constants consolidated from duplicate definitions in client.js and
ConnectionManager.js into shared js/nostr/relayConstants.js
- AGENTS.md Section 13: documents all three rules with examples
- docs/scheduled-agent-prompts.md: copy-paste prompts for recurring
file decomposition, innerHTML migration, and constant dedup tasks
https://claude.ai/code/session_01LzErpH9FNw4hAPsjoYb1v9
- AGENTS.md Section 12: subsystem boundary table, PR discipline rules,
in-flight work reservation section, and signaling conventions for
parallel AI agent workflows (Claude Code, Codex, Jules)
- CLAUDE.md: document the unstable→beta→main promotion pipeline,
add multi-agent workflow section with coordination rules for both
agents and human maintainers, fix Node.js version reference (20→22)
https://claude.ai/code/session_01LzErpH9FNw4hAPsjoYb1v9
Updates documentation to match current codebase implementation:
- Deprecates `nostrClient.fetchVideos` in README.md, pointing to `subscribeVideos`.
- Clarifies `playVideoWithFallback` implementation location in `docs/playback-fallback.md` and `AGENTS.md` (moved to `js/app/playbackCoordinator.js`).
- Corrects `WATCH_HISTORY` d-tag description in `docs/nostr-event-schemas.md` to match actual code behavior (`<YYYY-MM>`).
Co-authored-by: PR0M3TH3AN <[email protected]>
Updates AGENTS.md to explicitly instruct AI agents to review
KNOWN_ISSUES.md before starting development or debugging. This
ensures awareness of pre-existing test failures and environmental
quirks, preventing unnecessary investigation.
Update AGENTS.md to explicitly require support for both legacy NIP-04 and newer NIP-44 Direct Messages, as many users still rely on the legacy standard.
Adds a new section to `AGENTS.md` documenting the importance of using
the `d` tag (network identifier) over logical IDs (like `videoRootId`)
when creating pointers for parameterized replaceable events (NIP-33).
This captures the lessons learned from recent watch history bugs where
mismatched identifiers caused hydration failures.