Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .claude/agents/linux-media-expert.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ You are the Linux media-capture and environment specialist. You own the seams wh
- **Exactly one consumer per `/dev/videoN`.** V4L2 returns EBUSY at the kernel level if two processes open the same node. The loop serializes rig work; never launch a second capture against a device already in use.
- **v4l2loopback needs `exclusive_caps=0`** (caps=1 breaks ffmpeg→loopback writes) and does not tolerate `poll()` before `VIDIOC_STREAMON` — a strict-conformance driver that has exposed real MMAP-path bugs the permissive vivid driver hides.
- **A FAILED cross-device DMA-BUF import probe still perturbs NVIDIA's OPAQUE_FD allocation accounting.** A `vkAllocateMemory` chained with an import-FD info is NOT side-effect-free on NVIDIA even when it returns cleanly; per-handle-type kernel accounting carries forward. Gate such probes by vendor where the engine already does.
- **Helper-process Vulkan is import-side only** (FD import + bind + map + layout transitions + timeline wait/signal) — allocation, modifier choice, and kernel construction all live in the parent. The RHI boundary (`.claude/rules/rhi.md`) and the polyglot rule (`.claude/rules/polyglot.md`) apply to any capture code you touch.
- **Helper-process Vulkan is import-side only** (FD import + bind + map + layout transitions + timeline wait/signal) — allocation, modifier choice, and kernel construction all live in the parent. The RHI boundary (`.claude/rules/rhi.md`) applies to any capture code you touch.
- **Camera / display processor code goes through `GpuContext`, never raw Vulkan.** DMA-BUF import and modifier handling that crosses into Vulkan belongs behind the RHI.

## What to re-derive from code (never cache here)
Expand Down
2 changes: 1 addition & 1 deletion .claude/agents/polyglot-ipc-expert.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ You are the helper-process / IPC specialist. You own the wire between the parent

## Method — how you work
- **Python is the sole focus runtime** (`docs/plan/ARCHITECTURE.md` §Language SDKs & parity). TypeScript authoring is paused, not rejected; a future SDK follows the same importable-library model. Do not design a second-runtime abstraction into a surface that has one runtime today — and when the plan entry is OPEN, stop and escalate rather than assuming either way.
- **The escalate-op recipe is: edit the JTD schema → regenerate → rebuild both halves → paired tests.** A schema edit is followed by `cargo xtask generate-schemas` and a rebuild of the Rust parent and the Python wheel so the wire shapes stay identical. The op isn't done until a parent-side Rust test and a helper-side Python test both exercise it.
- **The escalate-op recipe is: edit the Rust wire types → mirror the helper's dict construction → extend the round-trip vectors → paired tests.** There is no codegen and no schema file. The types in `runtime/streamlib-engine/src/core/compiler/compiler_ops/subprocess_escalate_wire_types/` are hand-written serde structs and the helper builds the same documents as plain Python dicts, so serde's encoding *is* the agreement between the two sides — field names, variant spellings and optional-field omission are not free to change. `escalate_wire_encoding_tests.rs` holds the vectors. The op isn't done until a parent-side Rust test and a helper-side Python test both exercise it.
- **Serve a new capability as its own escalate op, never as an emulated callback scope.** The parent bridge answers per-op round trips; a design that ships a scope object into the helper and calls back is the shape to reject.
- **On a test that hangs with no output, suspect PUBSUB-without-init first.** PUBSUB silently no-ops when uninitialized — subscribe buffers, publish drops — so a subscribe/publish/join test blocks forever with no panic and no error. Initialize it (or run inside a real runtime), use a timed channel receive instead of a bare join, and allow the subscriber setup time before publishing.

Expand Down
22 changes: 0 additions & 22 deletions .claude/rules/polyglot.md

This file was deleted.

2 changes: 1 addition & 1 deletion .claude/scripts/ship-change-removed-gate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ trap 'rm -f "$hits"' EXIT
# breaks a deadlock: /ship-change gates at step 1 but folds
# ARCHITECTURE.md at step 3, so a change whose own plan text names
# what it removes could never reach the step that retires that text.
# examples/** consumers, lagging by design (CLAUDE.md); moving out-of-repo (#1672).
# examples/** consumers, lagging by design (CLAUDE.md).
# packages/<consumer> the downstream-consumer entries only, same doctrine — see below.
# vendor/** the vendored vulkanalia fork, never ours to edit.
# The path check inherits none of these: a file existing at a named path is residue
Expand Down
2 changes: 1 addition & 1 deletion .claude/scripts/tests/ship-change-removed-gate.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ plant docs/learnings/slpkg-raw-device-rhi-construction.md "A separately-built .f
run_gate
expect_pass "a learning that records driver behaviour is not residue"

# Consumers lag by design (CLAUDE.md) and are moving out-of-repo (#1672).
# Consumers lag by design (CLAUDE.md).
new_repo <<'EOF'
- REMOVED: fictional_modules
EOF
Expand Down
10 changes: 6 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,12 @@ before implementation. Sessions implement the plan; they never make architecture
for this session. Do not file tickets for it.
- File an issue only when something blocks the current milestone. Non-blocking findings go in the
PR description as a note, then we move on. Getting an MVP into users' hands beats completeness.
- These directories are moving to `tatolab/streamlib-packages` (#1672). Reading them is allowed —
they are reference material for parity and completeness checks (how processors are actually
written, which API surfaces real code exercises). Editing stays deny-ruled: they are never bent
to make an engine change pass, and never treated as contract sources.
- They are the pre-pivot tree, **not a model for new code**. Each is written against the
deleted identity grammar, the deleted schema layer, `streamlib.yaml` manifests and the
package-as-distributable shape the wheel replaced — so reading one to learn how a processor
is declared teaches the model we removed. Their *logic* still holds (how a codec was wired to
the RHI, what a capture path must handle); read for that, never for form. Editing stays
deny-ruled.

Captured knowledge lives in `docs/learnings/`; design rationale in `docs/decisions/`. However, these may go stale and should be verified, not viewed as facts. It serves as a cache. Everything else is re-derived
from code at need — do not create summary docs of what code already shows.
Expand Down
32 changes: 6 additions & 26 deletions docs/architecture/adapter-authoring.md
Original file line number Diff line number Diff line change
Expand Up @@ -479,30 +479,12 @@ ambient availability) lives in the *Trade-off* section of
adapter setup is per-runtime and lifetime-controlled, neither of
which a Cargo feature can express.

## Polyglot coverage

If the adapter is supposed to be reachable from Python and Deno
subprocesses (which is the default for any new adapter), follow
[`.claude/rules/polyglot.md`](../../.claude/rules/polyglot.md):

- Cdylibs (`streamlib-python-native`, `streamlib-deno-native`) add
the adapter crate as a runtime dep. The cdylib's dep graph
must still exclude `streamlib` — `cargo tree -p
streamlib-python-native | grep -c "^streamlib v"` should return
`0`. CI enforces this via `cargo xtask check-boundaries` (see
CLAUDE.md → Vulkan RHI Boundary).
- The Python adapter mirror at
`sdk/streamlib-python/python/streamlib/adapters/` carries the
per-adapter context types (`VulkanContext`, `OpenGLContext`, etc.);
the base `SurfaceAdapter` Protocol/interface lives in
`sdk/streamlib-python/python/streamlib/surface_adapter.py`. It mirrors
the trait shape using Python's idiomatic scope binding (`with`).
Escalate-op schemas live
in `packages/escalate/schemas/`.
- Polyglot coverage is **both Python AND Deno together** (per
`polyglot.md`). The only legitimate split is schema-only /
language-specific by construction; document the reason in the
PR if you split.
> A "Polyglot coverage" section was removed here: every artifact it named —
> the `streamlib-python-native` / `streamlib-deno-native` cdylibs, the
> `sdk/streamlib-python/` adapter mirror, `packages/escalate/schemas/`, and the
> Deno half of "both Python AND Deno together" — has been deleted. Adapters are
> statically linked into the wheel, and a helper process imports that same wheel
> rather than a separate cdylib.

## Cross-process producer composition

Expand Down Expand Up @@ -883,7 +865,5 @@ Read these, in this order, when authoring:
`VulkanComputeKernel`, the dispatch primitive any adapter that
needs compute reaches through (via escalate IPC from
subprocess).
- [`.claude/rules/polyglot.md`](../../.claude/rules/polyglot.md)
— polyglot rules including the import-side carve-out.
- [`.claude/rules/rhi.md`](../../.claude/rules/rhi.md)
— the RHI + import-side carve-out rule adapter work rides.
6 changes: 3 additions & 3 deletions docs/architecture/adapter-runtime-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ the FD is already an artifact; what the subprocess does with it
is bounded:

1. `VkImportMemoryFdInfoKHR` (the import-side carve-out from
`.claude/rules/polyglot.md`)
`.claude/rules/rhi.md`)
2. `vkBindImageMemory` / `vkBindBufferMemory`
3. Layout transitions + sync wait/signal on imported handles
4. Render or compute against the imported handle
Expand Down Expand Up @@ -484,8 +484,8 @@ property is load-bearing.
subprocess obtains a usable RHI surface beyond the import-side
carve-out (the integration-shape view of how the carve-out
works alongside this doc's adapter-runtime-shape view)
- `.claude/rules/polyglot.md` — the polyglot rule, including
the import-side carve-out
- `.claude/rules/rhi.md` — the RHI boundary, including the
import-side carve-out
- `docs/architecture/adapter-authoring.md` — the adapter
implementation contract
- `docs/learnings/nvidia-egl-dmabuf-render-target.md` —
Expand Down
2 changes: 0 additions & 2 deletions docs/architecture/subprocess-rhi-parity.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,6 @@ Revisit when:
`VulkanGraphicsKernel`.
- [ray-tracing-kernel.md](ray-tracing-kernel.md) — host's
`VulkanRayTracingKernel`.
- [`.claude/rules/polyglot.md`](../../.claude/rules/polyglot.md)
— the polyglot rule the carve-out lives under.
- [`.claude/rules/rhi.md`](../../.claude/rules/rhi.md) —
the RHI + import-side carve-out rule.
- [`docs/learnings/`](../learnings/) — bug evidence motivating one host
Expand Down
9 changes: 4 additions & 5 deletions docs/plan/OPERATING-MODEL.md
Original file line number Diff line number Diff line change
Expand Up @@ -293,15 +293,14 @@ PR — never accreted mid-session because something annoyed an agent once.
1. **Commit the pivot** — today's uncommitted rule/CLAUDE.md/settings edits + this
document, one operating-model PR. (`docs/plan/` is currently untracked; nothing
enforces a plan that isn't in git.)
2. **Land #1672** — consumers out; kills the build coupling.
3. **Wave 1 skills** — `grilling`, `batch-grilling`, `glossary`, `/align`, `/plan`:
2. **Wave 1 skills** — `grilling`, `batch-grilling`, `glossary`, `/align`, `/plan`:
just enough to run the plan session.
4. **The plan session** — `/align` on §Product first (the MVP sentence), then module
3. **The plan session** — `/align` on §Product first (the MVP sentence), then module
system, processor model, SDK parity, in that order. Everything after this is execution.
5. **Wave 2 skills** — `/reconcile-tracker` first (clean today's misaligned milestones
4. **Wave 2 skills** — `/reconcile-tracker` first (clean today's misaligned milestones
and tickets against the fresh plan), then `/propose-change`, `/derive-tickets`,
`/implement`, `review-pr` consolidation: the first real change flows through them.
6. **Wave 3** — `/ship-change`, `/pivot`, `/hygiene` (whose first full run seeds the
5. **Wave 3** — `/ship-change`, `/pivot`, `/hygiene` (whose first full run seeds the
kill-list), then the docs-consolidation
change (retiring `docs/architecture/`) as the first big change run through the new
system — the system migrates the old docs, proving itself on its own bootstrap.
Expand Down
Loading