# AGENTS.md — Screencast (Linux) Agent Workflow This document governs how Zed agents work in the `screen_cast` project. It is mandatory reading before any non-trivial implementation task. ## Agent memory Before starting work in a new agent conversation: - read this `AGENTS.md`; - read the `agent-memory/SKILL.md` skill; - read `.agents/MEMORY.md` for the current project handoff; - read `docs/PHASES.md` to understand the current phase and milestones; - read any domain-specific `RUNBOOK.md` relevant to the task (e.g. `docs/RUNBOOK.md` or `docs/multimedia/RUNBOOK.md`). Update `.agents/MEMORY.md` when the task produces significant state, blockers, or decisions. Update the relevant `RUNBOOK.md` when the task reveals reusable operational observations. Update `docs/PHASES.md` when a phase is completed or its plan changes. ## Skills Skills are task-specific instructions and must be read before planning work. Before producing a plan, identify all skills applicable to the task and read their `SKILL.md` files. Skills are self-contained directories under `.agents/skills/`. When a skill is selected, read its `SKILL.md` and consult any relevant documentation under that skill's `references/` directory. Skills are task-specific guidance, not a replacement for the mandatory project workflow in this file. The agent must follow `AGENTS.md` even when no skill applies. ### Skill selection - C++ project, Meson build, dependencies, or toolchain issues: `cpp-meson-build/SKILL.md` - Linux screen/audio capture, PipeWire, xdg-desktop-portal, FFmpeg, VAAPI, or codec work: `linux-multimedia-capture/SKILL.md` - RTP/UDP networking, transport, signaling, NAT traversal, or encryption: `rtp-networking/SKILL.md` - Overall screencast application architecture, sender/receiver modes, protocol negotiation, or integration decisions: `screencast-app/SKILL.md` Multiple skills may apply. Read all applicable ones. For example, implementing sender-side capture + encode will normally require: 1. `cpp-meson-build/SKILL.md` 2. `linux-multimedia-capture/SKILL.md` 3. `screencast-app/SKILL.md` A networking change will normally require: 1. `cpp-meson-build/SKILL.md` 2. `rtp-networking/SKILL.md` 3. `screencast-app/SKILL.md` Do not assume that a skill is applicable merely because its subject is mentioned incidentally. Use the task's actual scope to determine applicability. ## Mandatory development workflow All non-trivial implementation tasks follow this workflow: ### 1. Understand Before changing anything: - read `AGENTS.md`; - read all applicable skills; - inspect the existing implementation and directory structure; - search the project for related symbols, build rules, and tests; - identify system dependencies (pkg-config names, headers, runtime packages); - identify dependencies and integration points. Do not modify files during this phase. ### Plan against the phase roadmap - `docs/PHASES.md` defines the project milestones and the current active phase. - **Do not start implementation that belongs to a later phase** unless the user explicitly asks for it or the current phase is already complete and validated. - When planning work, identify which phase(s) the task touches and include that in the implementation plan. - Update `docs/PHASES.md` when a phase is finished, blocked, or its scope changes; update `.agents/MEMORY.md` at the same time. ### 2. Plan Produce a concise implementation plan containing: - understanding of the requirement; - relevant existing project functionality; - files/components likely to change; - proposed implementation; - build/dependency implications; - tests to add or modify; - multimedia/networking/security considerations; - potential risks or unresolved questions. ### 3. Wait for approval **STOP after presenting the plan.** Do not create, modify, delete, or rename files until the user explicitly approves the plan. Questions and clarification are allowed during this phase. ### 4. Implement After approval: - implement the approved plan; - prefer existing project modules and standard library functionality; - keep the change as small and focused as practical; - do not introduce unrelated refactoring; - follow the C++ and project conventions described in this file and in skills. If implementation reveals that the approved plan is materially wrong or incomplete, stop and explain the discrepancy rather than silently expanding scope. ### 5. Validate Run appropriate tests and checks. At minimum: - the project must still configure with Meson (`meson setup build`); - the project must still compile (`ninja -C build`); - unit/integration tests pass (`meson test -C build --print-errorlogs`); - static analysis or formatting checks configured in the project; - manual smoke test of the affected component where automated tests are insufficient. For multimedia or networking changes, validate runtime behavior on an actual Linux desktop session (Wayland or X11) when feasible. ### 6. Review Before considering the task complete, review the resulting changes for: - correctness; - integration with existing modules; - reuse of existing functionality; - maintainability (small headers, clear ownership, RAII); - security (buffer handling, bounds checks, no secrets committed); - thread safety and async I/O correctness; - regression risk; - build/dependency impact. ## Verify before assuming Never invent or assume the existence of an API. Before using a: - system library or package; - header file or symbol; - class, function, or macro; - build option or pkg-config name; - external protocol or service; verify that it exists in the current environment, project dependencies, or a reliable source (distribution package index, upstream API docs, local header). Do not infer existence from naming conventions, training knowledge, or similarly named components. If existence cannot be verified, stop and report the uncertainty. In particular, never add a dependency merely because it would be a plausible package name. ## Prefer framework and standard functionality Before implementing custom functionality, search the project and the C++ standard library for an existing mechanism. Prefer, in order: 1. existing project functionality that already satisfies the requirement; 2. C++ standard library facilities (`std::`, ``, ``, etc.); 3. widely adopted third-party libraries already used by the project; 4. a small project-specific implementation only when the above are insufficient. Do not duplicate functionality merely because implementing it locally appears simpler. When choosing a custom implementation over an existing mechanism, explain the reason in the plan. ## Git - Keep commits focused and logically coherent. - Prefer one component or one phase per commit where practical. - Do not mix unrelated changes. - Review the staged diff before committing. - Never commit secrets, credentials, local configuration, or generated build artifacts. - Do not create a commit unless the user explicitly asks for one or the task explicitly requires it. - When committing, write concise, descriptive messages in imperative mood. ## Coding conventions ### Language baseline - C++20 is mandatory. The project must compile with `-std=c++20` and all source must use C++20 idioms. - Prefer standard library facilities over hand-written alternatives. - No C-style constructs when a modern C++ equivalent exists. ### Modern C++ guidelines - **Ownership**: use `std::unique_ptr` and `std::shared_ptr`; never use raw `new`/`delete` or raw owning pointers. - **Optional values**: use `std::optional` instead of sentinel values or out-parameters. - **Fallible operations**: use `std::expected` or `std::error_code` for recoverable errors. Avoid exceptions for control flow. - **References and views**: use `std::span` for non-owning contiguous data and `std::string_view` for read-only strings. - **Compile-time computation**: prefer `constexpr`, `consteval`, and `std::integral_constant` where applicable. - **Type safety**: use `enum class`, `std::variant`, and `std::optional` instead of bare integers or bool flags. - **Concurrency**: prefer `std::jthread`, `std::stop_token`, and standard synchronization primitives. Avoid manual thread lifecycle management. - **Containers**: use `std::vector`, `std::array`, `std::deque`, and standard containers; avoid C arrays and raw buffers. - **Formatting and time**: use `` / `std::format` and `` instead of `printf`, `sprintf`, or manual time math. - **Algorithms**: prefer `std::ranges` algorithms over hand-rolled loops where clarity improves. - **Lambdas and callable abstractions**: use `std::function` sparingly; prefer function pointers, templates, or `auto` parameters for simple callbacks. - **Concepts and constraints**: use `requires` clauses or `std::concepts` to express interface contracts where beneficial. ### Style - Use `namespace sc` for all project code. - Prefer `snake_case` for functions and variables, `PascalCase` for types, `SCREAMING_SNAKE_CASE` for constants. - Keep headers minimal and free of unnecessary includes; forward-declare where possible. - Format code with the configured formatter (`clang-format` if available). ### Error handling - Use explicit error handling. Prefer `std::expected`, `std::optional`, or `std::error_code` over exceptions for recoverable errors. - Use RAII for resource cleanup; do not leave resources unreleased on error paths. - Avoid `assert` for user-facing error conditions; use real error returns or logging.