Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
b00dfff
quest: scope JS announce interest and close sessions gracefully (#4209)
kixelated Sep 25, 2026
3e52c7c
fix(nvenc): commit rate changes and cleanup only once the driver acce…
kixelated Sep 25, 2026
9cb5416
feat(moq-net): sans-IO session benchmark over a relay mesh (#4160)
kixelated Sep 26, 2026
a05a2d5
fix(uring): bound io_uring tests by the shared memlock budget (#4167)
kixelated Sep 26, 2026
a1d993c
chore(skills): spawn-quests judges readiness from line branches (#4161)
kixelated Sep 26, 2026
394c755
docs(quest): plan partial moxygen compatibility (#4205)
kixelated Sep 26, 2026
bc051b7
fix(net): skip old groups without reporting them as lost (#4208)
kixelated Sep 26, 2026
f70eba8
fix(video): run the capture clock tests on a LocalSet (#4210)
kixelated Sep 26, 2026
322d887
fix(quic): pin noq 1.3.1 for the BBR correctness fixes (#4206)
kixelated Sep 26, 2026
c6412ee
quest: dropped sources, video keyframe flag, interop flakes (#4201)
kixelated Sep 26, 2026
43fa4f7
fix(transcode): choose a source rendition this host can decode (#4182)
kixelated Sep 26, 2026
e5d1f1c
fix(relay): bind smoke-test listeners on :0 instead of probing for a …
kixelated Sep 26, 2026
33c9c9f
quest: SETUP AUTHORIZATION TOKEN becomes a standalone m1 quest (#4211)
kixelated Sep 26, 2026
a0dc197
test: bind :0 up front instead of probing for a free port (#4212)
kixelated Sep 26, 2026
ad48f03
fix(net): resolve a lite fetch only once the publisher answers (#4164)
kixelated Sep 26, 2026
01e1e4d
fix(moq-net): serve only the lite routes a request woke, and bound ki…
kixelated Sep 26, 2026
d537caf
fix(uring): halve the completion queue and lift the relay's memlock l…
kixelated Sep 26, 2026
bb426d9
fix(watch): keep media-captions external so the package imports outsi…
kixelated Sep 26, 2026
cd379fe
feat(net): compress lite-07 announcements against live bases (#4196)
kixelated Sep 26, 2026
df392d8
fix(relay): bind every listener in Relay::load so tests read ports ba…
kixelated Sep 26, 2026
50313f2
chore: release (#4199)
moq-bot[bot] Sep 26, 2026
b99cad9
fix(net): end a track with its session's error when the session dies …
kixelated Sep 26, 2026
7461eca
chore(moq-net): bench lite-06, smoke-run benches nightly, refresh per…
kixelated Sep 26, 2026
b33e926
chore: bump package versions
kixelated Sep 26, 2026
bd0376f
fix(net): await the publisher answer for lite fetches (#4221)
kixelated Sep 26, 2026
c81aaae
fix(cli): keep delayed playback at the live edge (#4241)
kixelated Sep 26, 2026
ce123c8
feat(moq-mux): catalog delay measures cross-rendition encoder latenes…
kixelated Sep 26, 2026
c280683
chore(claude): share skills through kixelated/skills, tighten quest s…
kixelated Sep 26, 2026
ea7db01
perf(kio): keep a parked waiter that quiet lists still hold (#4240)
kixelated Sep 26, 2026
d2d5d78
fix(auth): keep accepted grants on fixed expiry deadlines (#4237)
kixelated Sep 26, 2026
f63b295
fix(net): retain retired counters in host snapshots (#4238)
kixelated Sep 26, 2026
3431e3d
fix(net): make JS origin refusals terminal to match moq-net (#4230)
kixelated Sep 26, 2026
33a00ce
docs(quest): plan BBR ECN and ACK cleanup fixes (#4245)
kixelated Sep 26, 2026
05d7815
docs(quest): drop proposed binding route APIs (#4236)
kixelated Sep 26, 2026
760d884
test(relay): run the outage lease test on the real clock (#4244)
kixelated Sep 26, 2026
cbc63ea
fix(libmoq): write moq.h and moq.pc into OUT_DIR only (#4243)
kixelated Sep 26, 2026
b08ba83
bench(moq-net): model the dash aggregator's stats load in the session…
kixelated Sep 26, 2026
a5af309
feat(net): scope origin announcement interest (#4234)
kixelated Sep 26, 2026
aec87cc
fix(net): reject undeclared subscription ends (#4231)
kixelated Sep 26, 2026
7cb6e57
feat(mux): forward importer discontinuities through publishers (#4239)
kixelated Sep 26, 2026
bb44944
chore: rename CLAUDE.md to AGENTS.md (#4235)
kixelated Sep 26, 2026
76571fa
quest: origin narrowing joins auth, drop relay peer set, plan hop-lis…
kixelated Sep 26, 2026
a9f638e
docs(quest): plan quests for issues #4219, #4246-#4249 (#4250)
kixelated Sep 26, 2026
6a02f51
feat: end a broadcast with close() in every language (#4031)
kixelated Sep 26, 2026
daff231
Merge remote-tracking branch 'origin/main' into claude/merge-main-int…
kixelated Sep 26, 2026
2bf3e6f
quest: point origin-mount at auth/narrowing
kixelated Sep 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .claude/rules/prompting.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
paths:
- "**/CLAUDE.md"
- "**/AGENTS.md"
- "CONTRIBUTING.md"
- "PROMPTING.md"
Expand Down
2 changes: 1 addition & 1 deletion .claude/skills/plan-quests/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: plan-quests
description: Scope, create, and publish a quest through an interactive grilling interview. Use when the user invokes /plan-quests, asks to plan a quest, or wants unsettled work split into quests.
---

Before you begin, read `quest/CLAUDE.md` completely.
Before you begin, read `quest/AGENTS.md` completely.

Interview the user until you reach a shared understanding.

Expand Down
2 changes: 1 addition & 1 deletion .claude/skills/spawn-quests/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: spawn-quests
description: Spawn background agents work on quests in parallel.
---

Before you begin, read `quest/CLAUDE.md` completely.
Before you begin, read `quest/AGENTS.md` completely.

Your goal is to execute, plan, and/or merge quests in parallel.
If you are unsure of the best course of action, ask the user for clarification before proceeding.
Expand Down
4 changes: 2 additions & 2 deletions .claude/skills/start-quest/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ name: start-quest
description: Start work on a quest.
---

Before you begin, read `quest/CLAUDE.md` completely.
Before you begin, read `quest/AGENTS.md` completely.

Your goal is to implement the quest, or as much of it as possible, and create a draft PR.
The argument is the quest to work on.

If you are unsure on the best course of action, ask the user for direction.

Confirm the quest is ready and unclaimed.
Claim it as `quest/CLAUDE.md` describes: `quest branch` names the branch and its bases, missing line branches get a draft PR, and the quest branch gets an empty commit.
Claim it as `quest/AGENTS.md` describes: `quest branch` names the branch and its bases, missing line branches get a draft PR, and the quest branch gets an empty commit.

Implement the quest until it is complete, or some blocker is hit, then create a PR against the base.
Keep scratch files (PR body, logs, notes) in the worktree's gitignored `.scratch/`.
Expand Down
2 changes: 1 addition & 1 deletion .config/nextest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
slow-timeout = { period = "30s", terminate-after = 2 }

# Retries hide flakes, and this repo treats an intermittent failure as a real
# race until proven otherwise (see Root Cause First in CLAUDE.md).
# race until proven otherwise (see Root Cause First in AGENTS.md).
retries = 0

# `--all-targets` still compiles the criterion benches, which is what catches a
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/interop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ jobs:
run: nix develop --command just test max-age
shell: bash -leo pipefail {0}

- name: Subscription termination interop
run: nix develop --command just test bare-fin
shell: bash -leo pipefail {0}

- name: Interop (full matrix)
run: nix develop --command just test interop --all
shell: bash -leo pipefail {0}
Expand Down
2 changes: 1 addition & 1 deletion .opencode/agent/review.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ it like a prompt: terse, specific, and nothing the reader has to re-derive.
## Before reviewing

Read `AGENTS.md`, `CONTRIBUTING.md`, and `PROMPTING.md` at the repo root, then
the nested `CLAUDE.md` beside any touched code. They hold the rules you enforce
the nested `AGENTS.md` beside any touched code. They hold the rules you enforce
and how to write for an agent reader; cite them by file and heading.

Confirm the base with `gh pr view <number> --json baseRefName`, then diff
Expand Down
1 change: 0 additions & 1 deletion AGENTS.md

This file was deleted.

113 changes: 113 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
MoQ (Media over QUIC) is a live media delivery protocol providing real-time latency at massive scale.
This is a polyglot monorepo with Rust (server/native) and TypeScript (browser) implementations.

# Context

This file is split into nested `AGENTS.md` files based on the language/situation.

- Read `CONTRIBUTING.md` when dealing with PRs.
- Read `PROMPTING.md` before instructing other agents via context, memory, plans, or reviews.
- Read `*/AGENTS.md` if the file exists before touching a root directory.
- Read (and keep up-to-date) `doc/*.md` for user-facing documentation.

# Required

- Pull the latest origin changes before working.
- Dig into the root cause and fix it at the source. Never work around a fixable bug with a retry, sleep, or timeout.
- Fail loud and early. Error on unsupported or malformed input rather than warn and continue: supported or refused.
- Reproduce bugs before fixing them. Land each fix with a regression test that fails without it, when one is easy.
- Keep the PR focused. No unrelated refactors, formatting churn, or drive-by changes; split when in doubt.
- Refactor aggressively for long-term maintainability, but re-evaluate the direction as you learn.
- Propose a course change, even suggest abandoning a PR, rather than finish a half-solution.
- When a decision is the maintainer's (API shape, naming, scope), ask with 2-3 options and a recommendation.
- All tests need to be wired into CI, at least a nightly.
- Never edit an `AGENTS.md`, `CONTRIBUTING.md`, or skill without being prompted, and read `PROMPTING.md` first.
- No em dashes.
- Match the existing conventions, patterns, and naming when possible.
- Fix any outdated docs and comments inline; don't add a separate PR for it.
- Add the AI marker `(Written by <model>)` to any posts on GitHub, excluding commit messages that contain `Co-Authored-By:` trailers.
- Any AI comments may be challenged, and not confused with human maintainers.
- Prompt the user to decide when unsure, but always provide recommendations.

# Guidelines

- Prefer a maintained crate over hand-rolling non-core functionality.
- Anything that fans out (N publishers, M subscribers, routes, sessions) gets a benchmark swept over both axes, so a cost that grows with the table instead of the touched path shows up as a slope.
- New dependencies should use the newest, stable version.
- Do not bump package versions unless asked. Releases are cut separately.
- Comments should explain the non-obvious why, and never the history.
- Inline simple helpers.
- Question whether functionality is needed at all before adding it.
- Deleting code is better than adding code.
- Suggest follow up sessions and quests when finished, interactively prompting the user.
- Prefer the simple solution.
- Say it once, in the fewest words that hold up.
- Critically think, and decide if the complexity is worth it. Simple is better.
- Prefer a quest over a GitHub issue for work needing durable scope.
- Use interactive prompts when possible.
- Try to do stuff asynchronously. ex. ask about follow-ups while tests run.
- Try to recognize when you're stuck, or making minimal progress, and stop early.
- If the core problem is addressed, ship it instead of spinning your wheels on meaningless revisions.
- Add or extend a benchmark for any performance-sensitive change so later regressions show up, and measure optimizations instead of relying on intuition.

# Public API

The API is the most important thing to get right.
A bad shape costs a breaking change in every language, and the surface is huge.

- Report the public API and wire impact of every change, in the PR description and whenever asked.
- Keep things private until a consumer needs them. Scrutinize every new exported item.
- Never add `foo_with_x`, `foo_checked`, or a compatibility shim. Make the breaking change to `foo` on `dev` instead. Additive changes stay on `main`.
- Let the type system make misuse unrepresentable
- Avoid callback parameters. Return a handle, an event, or a Producer/Consumer split.
- Avoid 4+ args; use a struct or object.
- Name by role, not today's implementation.
- When a name or shape feels awkward, propose alternatives with a recommendation instead of shipping it.
- Short names under a module namespace (`encode::Config`, not `EncoderConfig`). Mirror names across Rust, JS, and the bindings.
- Document every exported symbol in one plain line, the way you'd say it out loud.
- Prefer refactoring and simplification when working on the `dev` branch; many APIs have have not been published yet.

MoQ is split into many layers as part of the public API.
The boundary between packages is extremely important to keep things modular and reusable.

# Development

PRs target `main`.
`dev` is reserved for semver-breaking API changes, except for `0.0.x` and unpublished/private packages.
Wire changes should be backwards compatible for any *published* drafts/versions.

Before starting, `git fetch origin` and set the upstream to the base branch.
If a published API break requires `dev`, retarget the PR to `dev`, set the upstream to `origin/dev`, then rebase onto it.

Use the Nix dev shell so tooling matches CI.
direnv loads it automatically, but if not: `nix develop --command ...`.

```bash
just check # Lint, compile, and test what the branch changed
just fix # Auto-fix lint/formatting, same scope
```

These diff the branch against its base and only run the affected packages.

# Cross-Package Sync

| Change in | Also update |
|---|---|
| `rs/moq-ffi` | `rs/libmoq`, `{py,swift,kt,dart}/`, `go/wrapper/moq/*.go` (the `go/ffi` and `dart/moq_ffi` bindings regenerate automatically, but a new method needs a hand-written wrapper too, like `py/moq-rs` or `dart/moq`), `doc/lib/{py,swift,kt,go,dart,c}` |
| `rs/moq-net` wire/API | `js/net`, `doc/concept`, `drafts/draft-lcurley-moq-lite.md` (if the wire spec changes) |
| `rs/hang` catalog/container | `js/hang`, `doc/concept`, `drafts/draft-lcurley-moq-hang.md` (if the format spec changes) |
| `rs/moq-token` | `js/token` |
| `rs/moq-stats` wire (track names, frame shapes) | `doc/bin/relay/config.md` (stats section) |
| `rs/moq-relay` config/behavior | `doc/bin/relay/` |
| `rs/moq-cli` | `doc/bin/cli.md` |
| `rs/moq-token-cli` | `doc/bin/relay/auth.md`, `doc/lib/rs/moq-token.md`, `doc/lib/rs/index.md` |
| `rs/moq-gst` | `doc/bin/gstreamer.md` |
| `rs/libmoq` C ABI (`moq.h`) | `cpp/obs/src`, `doc/bin/obs.md` |
| `js/{watch,publish}` UI/API | `demo/web` if it consumes the API |
| a kramdown-rfc construct new to `drafts/` | `doc/.vitepress/drafts.ts`, which translates the drafts into `/draft/` site pages |

Any wire-format change updates its matching IETF draft in the same PR, including framing, message fields, enum values, and version negotiation. Use the feature-specific draft for extensions and validate with `just drafts check`. See `drafts/AGENTS.md`.

For wire, `moq-ffi`, or gateway changes, also run `just test interop --all` for cross-language interop; plain `interop` is Rust-only.

When a CLI interface changes, search the whole repo for the binary name and update every example invocation, including docs and demo recipes. Check examples against `--help`.
113 changes: 0 additions & 113 deletions CLAUDE.md

This file was deleted.

4 changes: 2 additions & 2 deletions PROMPTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ Mocking up an API makes a lot of sense but again, it should be flexible enough t

# Context

This includes editing any `CLAUDE.md`, `AGENTS.md`, `CONTRIBUTING.md`, etc.
This includes editing any `AGENTS.md`, `CONTRIBUTING.md`, etc.

These files need to be light because they're loaded into every prompt.
More specific context (ex. per language or project) should exist in optional files/folders.

These base prompts are meant to fix regular agent mistakes.
If there is a history of bad practices, or sub-optimal behavior, update `CLAUDE.md` to steer away from them.
If there is a history of bad practices, or sub-optimal behavior, update `AGENTS.md` to steer away from them.
If you think a slight tweak to the base prompt would help, propose it.

Focus on best practices and conventions.
Expand Down
12 changes: 4 additions & 8 deletions cpp/obs/justfile
Original file line number Diff line number Diff line change
Expand Up @@ -200,21 +200,17 @@ _includes:

(cd ../.. && cargo check --locked --quiet -p libmoq)

# Ask cargo where its build script ran rather than reconstructing the path.
# CARGO_TARGET_DIR, a `--target` triple and a custom profile each move the
# generated header, and guessing wrong doesn't fail: it type-checks against
# whatever stale copy the default directory still holds. Replays the check
# above from cache, so it costs a process rather than a compile.
# rs/libmoq/build.rs writes the header into its OUT_DIR, so ask cargo where
# that is. Replays the check above from cache, so it costs a process rather
# than a compile.
out_dir=$(cd ../.. && cargo check --locked -p libmoq --message-format=json |
jq -r 'select(.reason == "build-script-executed") | select(.package_id | tostring | test("libmoq")) | .out_dir' |
tail -1)
if [ -z "$out_dir" ]; then
echo "cargo reported no build script output for libmoq" >&2
exit 1
fi
# <target>/<profile>/build/libmoq-<hash>/out, and the header sits beside the
# profile directory. rs/libmoq/build.rs derives it from OUT_DIR the same way.
moq_include="$(dirname "$(dirname "$(dirname "$(dirname "$out_dir")")")")/include"
moq_include="$out_dir/include"
if [ ! -f "$moq_include/moq.h" ]; then
echo "$moq_include/moq.h missing after 'cargo check --locked -p libmoq'" >&2
exit 1
Expand Down
Loading
Loading