Lets keep working on this, https://forge.wilddragon.net/zgaetano/datarhei-dragonfork-core


## claude.ai Context7
Use this server to fetch current documentation whenever the user asks about a library, framework, SDK, API, CLI tool, or cloud service -- even well-known ones like React, Next.js, Prisma, Express, Tailwind, Django, or Spring Boot. This includes API syntax, configuration, version migration, library-specific debugging, setup instructions, and CLI tool usage. Use even when you think you know the answer -- your training data may not reflect recent changes. Prefer this over web search for library docs.

Do not use for: refactoring, writing scripts from scratch, debugging business logic, code review, or general programming concepts.


- update-config: Use this skill to configure the Claude Code harness via settings.json. Automated behaviors ("from now on when X", "each time X", "whenever X", "before/after X") require hooks configured in settings.json - the harness executes these, not Claude, so memory/preferences cannot fulfill them. Also use for: permissions ("allow X", "add permission", "move permission to"), env vars ("set X=Y"), hook troubleshooting, or any changes to settings.json/settings.local.json files. Examples: "allow npm commands", "add bq permission to global settings", "move permission to user settings", "set DEBUG=true", "when claude stops show X". For simple settings like theme/model, suggest the /config command.
- keybindings-help: Use when the user wants to customize keyboard shortcuts, rebind keys, add chord bindings, or modify ~/.claude/keybindings.json. Examples: "rebind ctrl+s", "add a chord shortcut", "change the submit key", "customize keybindings".
- simplify: Review changed code for reuse, quality, and efficiency, then fix any issues found.
- fewer-permission-prompts: Scan your transcripts for common read-only Bash and MCP tool calls, then add a prioritized allowlist to project .claude/settings.json to reduce permission prompts.
- loop: Run a prompt or slash command on a recurring interval (e.g. /loop 5m /foo). Omit the interval to let the model self-pace. - When the user wants to set up a recurring task, poll for status, or run something repeatedly on an interval (e.g. "check the deploy every 5 minutes", "keep running /babysit-prs"). Do NOT invoke for one-off tasks.
- schedule: Create, update, list, or run scheduled remote agents (routines) that execute on a cron schedule. - When the user wants to schedule a recurring remote agent, set up automated tasks, create a cron job for Claude Code, or manage their scheduled agents/routines. Also use when the user wants a one-time scheduled run ("run this once at 3pm", "remind me to check X tomorrow").
- claude-api: Build, debug, and optimize Claude API / Anthropic SDK apps. Apps built with this skill should include prompt caching. Also handles migrating existing Claude API code between Claude model versions (4.5 → 4.6, 4.6 → 4.7, retired-model replacements).
TRIGGER when: code imports `anthropic`/`@anthropic-ai/sdk`; user asks for the Claude API, Anthropic SDK, or Managed Agents; user adds/modifies/tunes a Claude feature (caching, thinking, compaction, tool use, batch, files, citations, memory) or model (Opus/Sonnet/Haiku) in a file; questions about prompt caching / cache hit rate in an Anthropic SDK project.
SKIP: file imports `openai`/other-provider SDK, filename like `*-openai.py`/`*-generic.py`, provider-neutral code, general programming/ML.
- init: Initialize a new CLAUDE.md file with codebase documentation
- review: Review a pull request
- security-review: Complete a security review of the pending changes on the current branch


Continue development on Datarhei Dragonfork Core


The user wants to continue working on a project at a Forgejo repository. Let me check my memory for context about what we've been working on, and then look at the repository to understand the current state.


Let me check my memory for context on this project and look at the repository.


Question: select:mcp__claude_ai_mcp-server__forgejo_forgejo_get_repository,mcp__claude_ai_mcp-server__forgejo_forgejo_list_issues,mcp__claude_ai_mcp-server__forgejo_forgejo_list_branches


Error: File does not exist. Note: your current working directory is /home/node.


ToolSearch

Question: select:mcp__claude_ai_mcp-server__forgejo_forgejo_get_repository,mcp__claude_ai_mcp-server__forgejo_forgejo_list_issues,mcp__claude_ai_mcp-server__forgejo_forgejo_list_branches


Let me get the repository info and list branches/issues to understand what's been worked on.


Let me pull up the repo details, branches, and issues in parallel.


Error: Error executing tool forgejo_get_repository: 'stargazers_count'


git init


Error: Error executing tool forgejo_list_branches: 'sha'


#17: v0.3: In-memory keyframe cache for faster first-frame (open)
#16: v0.3: WHIP ingest path (open)
#15: v0.2: Restreamer UI fork - Wild Dragon branding + WebRTC controls (open)
#14: v0.2: 5-peer x 10-min sustained load test (open)
#13: v0.2: Upstream rebase strategy + first rebase (open)
#12: v0.2: Publish Docker image to a registry (open)
#11: v0.2: WebRTC Prometheus metrics + Grafana stack (open)


The repository and branches calls errored, but issues loaded. Let me try to get files/directory listing to understand the structure. Let me also look at the pull requests to see what's in progress.


Issues are loading. Let me look at the open pull requests and the directory structure.


Question: select:mcp__claude_ai_mcp-server__forgejo_forgejo_list_pull_requests,mcp__claude_ai_mcp-server__forgejo_forgejo_list_directory


Question: select:mcp__claude_ai_mcp-server__forgejo_forgejo_list_pull_requests,mcp__claude_ai_mcp-server__forgejo_forgejo_list_directory


Let me list the pull requests and directory structure at the same time.


Running `git init` directly in `/home/node` would turn the entire home directory into a git repo, which is almost certainly not what you want. A couple of safer options:

1. **Clone the existing repo** — `git clone https://forge.wilddragon.net/zgaetano/datarhei-dragonfork-core.git` into a subdirectory like `~/datarhei-dragonfork-core`
2. **Init in a fresh subdirectory** — `mkdir ~/datarhei-dragonfork-core && cd ~/datarhei-dragonfork-core && git init`

Which one do you want? And if cloning, do I need credentials for the Forgejo instance, or is it public?


📁 .forgejo
📁 .github
📁 app
📁 cmd
📁 config
📁 core
📁 deploy
📁 docs
📁 encoding
📁 ffmpeg
📁 glob
📁 http
📁 internal
📁 io
📁 log
📁 math
📁 monitor
📁 net
📁 playout
📁 process
📁 prometheus
📁 psutil
📁 restream
📁 rtmp
📁 service
📁 session
📁 src
📁 srt
📁 test
📁 update
📁 vendor
📄 .dockerignore (99B)
📄 .editorconfig (407B)
📄 .gitignore (368B)
📄 CHANGELOG.md (10743B)
📄 CREDITS (1737B)
📄 Dockerfile (995B)
📄 Dockerfile.bundle (478B)
📄 Dockerfile.test (161B)
📄 LICENSE (11339B)
📄 Makefile (2959B)
📄 NOTES.md (1073B)
📄 NOTICE (1351B)
📄 README.md (6944B)
📄 SECURITY.md (553B)
📄 build.sh (37B)
📄 go.mod (5433B)
📄 go.sum (26823B)
📄 main.go (1207B)
📄 mime.types (644B)
📄 run.sh (648B)


Bash

git clone https://forge.wilddragon.net/zgaetano/datarhei-dragonfork-core.git /home/node/datarhei-dragonfork-core

Clone the datarhei-dragonfork-core repo


Error: Exit code 128
Cloning into '/home/node/datarhei-dragonfork-core'...
fatal: unable to access 'https://forge.wilddragon.net/zgaetano/datarhei-dragonfork-core.git/': server certificate verification failed. CAfile: none CRLfile: none


So the repo has no open pull requests. There are 7 open issues. Let me check the current state more - I should look at the issues to understand what's been done and what's pending. The issues are:

- #17: v0.3: In-memory keyframe cache for faster first-frame
- #16: v0.3: WHIP ingest path
- #15: v0.2: Restreamer UI fork - Wild Dragon branding + WebRTC controls

- #14: v0.2: 5-peer x 10-min sustained load test
- #13: v0.2: Upstream rebase strategy + first rebase
- #12: v0.2: Publish Docker image to a registry
- #11: v0.2: WebRTC Prometheus metrics + Grafana stack

The v0.2 items span #11-15 and v0.3 items are #16-17. Since there's no context about where they left off, I should ask what they want to focus on next, but first let me examine some key files to get a sense of the codebase structure.


No open PRs. Let me look at the notes and changelog to get context on where things stand.


Cloning failed — the Forgejo server's TLS certificate didn't validate against system CAs:

```
server certificate verification failed. CAfile: none CRLfile: none
```

This often happens with self-hosted instances using a private CA or self-signed cert. Options:

1. **Install the CA cert** properly (preferred) — if you have the CA bundle, point git at it: `git config --global http.https://forge.wilddragon.net/.sslCAInfo /path/to/ca.crt`
2. **Disable TLS verification just for this host** — `git config --global http.https://forge.wilddragon.net/.sslVerify false` (lowers security; do this only if you trust the network path)
3. **Use SSH instead of HTTPS** — if you have SSH keys set up on Forgejo

Which do you want? If you have the CA cert handy, I can wire that up.


File: NOTES.md

# Datarhei - Dragon Fork — Implementation Notes

This file tracks observations, gotchas, and decisions made during the Dragon
Fork WebRTC egress implementation. Keep entries chronological; each milestone
adds a new section.

## Baseline (M1, 2026-04-17)

- Forked from upstream `datarhei/core` commit `0de97f4` ("Add linux/arm/v8 build").
- Upstream module path: `github.com/datarhei/core/v16`. The Dragon Fork keeps
  this module path so internal imports don't churn; the fork is distinguished
  by its repo location (`forge.wilddragon.net/zgaetano/datarhei-dragonfork-core`)
  and branch history, not its Go module identity.
- Toolchain: Go 1.22.8, FFmpeg 4.4.2 in the sandbox. FFmpeg 6.x recommended
  for publishers in Task 10; 4.4.2 is sufficient for the PoC (libx264 +
  libopus + RTP muxer all present).
- `go build ./...` on the clean fork: succeeds.
- `go test -short ./...` on the clean fork: all packages pass. No upstream
  flakes observed.

### Pre-existing state of note
- None flagged.

---

<!-- Add M1 verification notes here after Task 12 succeeds. -->


File: CHANGELOG.md

# Datarhei — Dragon Fork

## v0.2.0-dragonfork (2026-05-03)

The "GUI ship" release. Everything from v0.1 is preserved; this round
documents and ships a usable graphical surface for the WebRTC feature
that v0.1 only exposed through the API.

### Added

- **Wild Dragon WebRTC admin page** at `/wilddragon-webrtc.html`. Single-file
  HTML/JS; no build step. Sign in with the API_AUTH_USERNAME / PASSWORD
  creds, see every process, toggle `webrtc.enabled` per-process with one
  click, restart on change, copy the WHEP URL, jump straight to the
  smoke player. Closes the v0.1 GUI gap — the upstream Restreamer UI
  ships with v0.2 but doesn't know about Core's `webrtc` config block,
  so toggling WebRTC previously required direct API calls.

### Documented (was present, just unannounced)

- **Restreamer UI bundle** in the TrueNAS deploy. The `deploy/truenas/core/`
  Dockerfile builds the upstream `datarhei/restreamer-ui` v1.14.0 React
  bundle with the Wild Dragon overlay applied (logo / favicon / header
  title / welcome card), copies the result into Core's disk filesystem
  via `seed-data.sh`, and Core serves it at `/`. Was added during M2
  but not called out in the v0.1 CHANGELOG.
- **WHEP smoke player** at `/whep-player.html`. Standalone WebRTC
  subscriber with ICE/codec/bitrate diagnostics. Was added during M4.

### Known limitations

- The Restreamer UI itself has no WebRTC affordance — there's no
  checkbox or "Enable WebRTC" toggle in its process editor. Use
  `/wilddragon-webrtc.html` for that. A proper UI fork that adds
  WebRTC controls inline is tracked in issue #15.
- No published Docker image yet — `docker compose up -d --build` still
  rebuilds from source. Tracked in issue #12.
- WebRTC subsystem has no Prometheus instrumentation yet. Spec at
  `docs/design/2026-05-03-datarhei-dragon-fork-webrtc-prometheus-metrics-design.md`,
  tracked in issue #11.

### Upgrade

```sh
cd deploy/truenas/core
git pull
docker compose up -d --build
```

The new admin page comes through `seed-data.sh` on container start;
no `.env` changes required.

---

## v0.1.0-dragonfork (2026-05-03)

The first tagged Dragon Fork release. Forked from upstream datarhei
Core v16.16.0; everything upstream does is preserved unchanged. New:
WebRTC (WHEP) egress, integrated with the existing process supervisor.

### Added

- **WebRTC subsystem** under `app/webrtc/`, mirroring the shape of
  upstream's RTMP and SRT servers (Server interface, Echo handlers,
  process-graph hooks, admin endpoints).
- **Per-process opt-in** via `config.webrtc.enabled` on every restream
  process; resolver auto-injects two RTP output legs and allocates
  loopback UDP ports.
- **`POST /api/v3/whep/{id}`** — WebRTC-HTTP Egress Protocol subscribe.
  JWT-protected by the existing Core auth.
- **`DELETE /api/v3/whep/{id}/{resource}`** — idempotent teardown
  (returns 204 even on unknown resource per WHEP spec).
- **`PATCH /api/v3/whep/{id}/{resource}`** — trickle ICE.
- **CORS preflight** on every WHEP route + `Access-Control-Expose-Headers`
  for `Location` and `ETag` so browser-side WHEP players work
  cross-origin.
- **Configurable stream maps** via `webrtc.video_map` / `webrtc.audio_map`
  on the per-process config — defaults to `0:v:0` / `0:a:0` for
  RTMP/SRT publishers, overridable for multi-input pipelines.
- **`webrtc.*` global config block** with `CORE_WEBRTC_*` env-var
  bindings parallel to RTMP and SRT.
- **Admin API:** `GET /api/v3/webrtc/streams` + `/streams/{id}/peers`.
- **Browser smoke player** at `test/whep-player.html` with ICE / codec
  / bitrate diagnostics, JWT field, and `?url=&token=` shareable
  URLs.
- **Server-hop latency p95 gate** in CI (`-tags latency`), enforced at
  50ms on the runner; locally observed p95 ≈ 240µs.
- **TrueNAS deploy bundle** at `deploy/truenas/core/` — host-networked
  Docker stack with bundled FFmpeg, env-driven config.
- **Multi-viewer correctness:** per-stream peer cap, ICE-failure
  auto-cleanup goroutines, process-stop broadcast tear-down.
- **Error matrix:** 406 codec mismatch, 504 ICE timeout, 503 cap
  reached (separate body for total vs per-stream), 204 DELETE
  idempotent.

### Fixed

- `Config.Clone()` now preserves the `WebRTC` section. Pre-fix,
  `cfg.WebRTC.Enable` was always zero at runtime regardless of
  `CORE_WEBRTC_ENABLE`. Caught on the first M2 TrueNAS deploy.
- `http/api.ProcessConfig` Marshal/Unmarshal now carry the per-process
  `webrtc` block. Pre-fix, `POST /api/v3/process` silently dropped
  `webrtc.enabled=true` on its way to the restream config layer.

### Forking notes

- Module path stays `github.com/datarhei/core/v16` — internal imports
  don't churn, the fork is distinguished by repo location and branch
  history.
- `cmd/webrtc-poc` from M1 is preserved as a manual-testing harness.
  Production deploys use the main `core` binary.

### Acknowledgements

Built on upstream Datarhei Core (Apache 2.0) and Pion WebRTC v4
(MIT). Full attribution in `NOTICE` and `CREDITS`.

---

# Core (upstream)

### Core v16.15.0 > v16.16.0

-   Add ConnectionIdleTimeout to RTMP server
-   Add WithLevel() to Logger interface
-   Fix datarhei/restreamer#759
-   Fix various RTMP bugs
-   Fix wrong log output when receiving a RTMP stream
-   Fix skipping session handling if collectors are nil
-   Update dependencies

### Core v16.14.0 > v16.15.0

-   Add migrating to ffmpeg 6
-   Fix missing process data if process has been deleted meanwhile
-   Fix maintaining the metadata on process config update (datarhei/restreamer#698)
-   Fix placeholder parsing
-   Fix concurrent memfs accesses
-   Fix memfs concurrent read and write performance

### Core v16.13.1 > v16.14.0

-   Add support for SRTv4 clients
-   Add support for Enhanced RTMP in internal RTMP server
-   Fix require positive persist interval (session)
-   Fix race condition (process)
-   Update dependencies

### Core v16.13.0 > v16.13.1

-   Fix transfer of reports to updated process
-   Fix calling Wait after process has been read
-   Fix 509 return code if non-existing stream is requested
-   Fix default search paths for config file
-   Fix sized filesystem
-   Update dependencies

### Core v16.12.0 > v16.13.0

-   Add updated_at field in process infos
-   Add preserve process log history when updating a process
-   Add support for input framerate data from jsonstats patch
-   Add number of keyframes and extradata size to process progress data
-   Mod bumps FFmpeg to v5.1.3 (datarhei/core:tag bundles)
-   Fix better naming for storage endpoint documentation
-   Fix freeing up S3 mounts
-   Fix URL validation if the path contains FFmpeg specific placeholders
-   Fix purging default file from HTTP cache
-   Fix parsing S3 storage definition from environment variable
-   Fix checking length of CPU time array ([#10](https://github.com/datarhei/core/issues/10))
-   Fix possible infinite loop with HLS session rewriter
-   Fix not propagating process limits
-   Fix URL validation if the path contains FFmpeg specific placeholders
-   Fix RTMP DoS attack (thx Johannes Frank)
-   Deprecate ENV names that do not correspond to JSON name

### Core v16.11.0 > v16.12.0

-   Add S3 storage support
-   Add support for variables in placeholde parameter
-   Add support for RTMP token as stream key as last element in path
-   Add support for soft memory limit with debug.memory_limit_mbytes in config
-   Add support for partial process config updates
-   Add support for alternative syntax for auth0 tenants as environment variable
-   Fix config timestamps created_at and loaded_at
-   Fix /config/reload return type
-   Fix modifying DTS in RTMP packets ([restreamer/#487](https://github.com/datarhei/restreamer/issues/487), [restreamer/#367](https://github.com/datarhei/restreamer/issues/367))
-   Fix default internal SRT latency to 20ms

### Core v16.10.1 > v16.11.0

-   Add FFmpeg 4.4 to FFmpeg 5.1 migration tool
-   Add alternative SRT streamid
-   Mod bump FFmpeg to v5.1.2 (datarhei/core:tag bundles)
-   Fix crash with custom SSL certificates ([restreamer/#425](https://github.com/datarhei/restreamer/issues/425))
-   Fix proper version handling for config
-   Fix widged session data
-   Fix resetting process stats when process stopped
-   Fix stale FFmpeg process detection for streams with only audio
-   Fix wrong return status code ([#6](https://github.com/datarhei/core/issues/6)))
-   Fix use SRT defaults for key material exchange

### Core v16.10.0 > v16.10.1

-   Add email address in TLS config for Let's Encrypt
-   Fix use of Let's Encrypt production CA

### Core v16.9.1 > v16.10.0

-   Add HLS session middleware to diskfs
-   Add /v3/metrics (get) endpoint to list all known metrics
-   Add logging HTTP request and response body sizes
-   Add process id and reference glob pattern matching
-   Add cache block list for extensions not to cache
-   Mod exclude .m3u8 and .mpd files from disk cache by default
-   Mod replaces x/crypto/acme/autocert with caddyserver/certmagic
-   Mod exposes ports (Docker desktop)
-   Fix assigning cleanup rules for diskfs
-   Fix wrong path for swagger definition
-   Fix process cleanup on delete, remove empty directories from disk
-   Fix SRT blocking port on restart (upgrade datarhei/gosrt)
-   Fix RTMP communication (Blackmagic Web Presenter, thx 235 MEDIA)
-   Fix RTMP communication (Blackmagic ATEM Mini, [#385](https://github.com/datarhei/restreamer/issues/385))
-   Fix injecting commit, branch, and build info
-   Fix API metadata endpoints responses

#### Core v16.9.0 > v16.9.1^

-   Fix v1 import app
-   Fix race condition

#### Core v16.8.0 > v16.9.0

-   Add new placeholders and parameters for placeholder
-   Allow RTMP server if RTMPS server is enabled. In case you already had RTMPS enabled it will listen on the same port as before. An RTMP server will be started additionally listening on a lower port number. The RTMP app is required to start with a slash.
-   Add optional escape character to process placeholder
-   Fix output address validation for tee outputs
-   Fix updating process config
-   Add experimental SRT connection stats and logs API
-   Hide /config/reload endpoint in reade-only mode
-   Add experimental SRT server (datarhei/gosrt)
-   Create v16 in go.mod
-   Fix data races, tests, lint, and update dependencies
-   Add trailing slash for routed directories (datarhei/restreamer#340)
-   Allow relative URLs in content in static routes

#### Core v16.7.2 > v16.8.0

-   Add purge_on_delete function
-   Mod updated dependencies
-   Mod updated API docs
-   Fix disabled session logging
-   Fix FFmpeg skills reload
-   Fix ignores processes with invalid references (thx Patron Ramakrishna Chillara)
-   Fix code scanning alerts


Now I have a good picture of the project. This is a fork of datarhei/core with WebRTC (WHEP) egress added, deployed on TrueNAS. Currently at v0.2.0-dragonfork. The open issues are:

v0.2 (current milestone):
- #15: Restreamer UI fork - Wild Dragon branding + WebRTC controls
- #14: 5-peer x 10-min sustained load test
- #13: Upstream rebase strategy + first rebase
- #12: Publish Docker image to a registry
- #11: WebRTC Prometheus metrics + Grafana stack

- #17: In-memory keyframe cache for faster first-frame (v0.3)
- #16: WHIP ingest path (v0.3)

All 7 issues are open with no PRs yet, so I should ask what they'd like to focus on next since they want to keep working on this.


Here's where things stand on **datarhei-dragonfork-core**:

**Current release:** v0.2.0-dragonfork (shipped 2026-05-03)

**Open v0.2 issues (all still open):**
| # | Issue |
|---|-------|
| #11 | WebRTC Prometheus metrics + Grafana stack |
| #12 | Publish Docker image to a registry |
| #13 | Upstream rebase strategy + first rebase |
| #14 | 5-peer × 10-min sustained load test |
| #15 | Restreamer UI fork — Wild Dragon branding + WebRTC controls |

**Open v0.3 issues:**
| # | Issue |
|---|-------|
| #16 | WHIP ingest path |
| #17 | In-memory keyframe cache for faster first-frame |

No open PRs — everything is on `main`. What do you want to tackle next?


Goal is to set up local work on the datarhei-dragonfork-core repo from forge.wilddragon.net. Clone failed due to TLS cert verification. Next: decide whether to install the CA cert, disable TLS verify for that host, or switch to SSH. (disable recaps in /config)