From 92c38680a1ef7d012a95daba795c4041c44aa2cd Mon Sep 17 00:00:00 2001 From: Rahim Date: Tue, 20 Jan 2026 14:52:09 +1100 Subject: [PATCH 1/3] docs(rfc): add RFC structure and migrate design docs --- .claude/plans/README.md | 68 ++++++++++++++ .claude/plans/store/bindings.md | 41 ++++----- .claude/plans/store/queue-simplification.md | 30 ++----- .claude/plans/store/reactive.md | 63 +++---------- .claude/skills/git/references/scope.md | 4 +- CLAUDE.md | 13 +++ CONTRIBUTING.md | 17 +++- README.md | 4 +- commitlint.config.js | 48 +++++----- docs/ARCHITECTURE.md | 58 ------------ rfcs/README.md | 88 +++++++++++++++++++ .../plans => rfcs}/player-api/architecture.md | 0 .../plans => rfcs}/player-api/decisions.md | 0 .../plans => rfcs}/player-api/examples.md | 0 {.claude/plans => rfcs}/player-api/index.md | 4 + {.claude/plans => rfcs}/slice-availability.md | 4 + {.claude/plans => rfcs}/store/queue-design.md | 4 + 17 files changed, 258 insertions(+), 188 deletions(-) create mode 100644 .claude/plans/README.md delete mode 100644 docs/ARCHITECTURE.md create mode 100644 rfcs/README.md rename {.claude/plans => rfcs}/player-api/architecture.md (100%) rename {.claude/plans => rfcs}/player-api/decisions.md (100%) rename {.claude/plans => rfcs}/player-api/examples.md (100%) rename {.claude/plans => rfcs}/player-api/index.md (99%) rename {.claude/plans => rfcs}/slice-availability.md (99%) rename {.claude/plans => rfcs}/store/queue-design.md (99%) diff --git a/.claude/plans/README.md b/.claude/plans/README.md new file mode 100644 index 00000000..909ed744 --- /dev/null +++ b/.claude/plans/README.md @@ -0,0 +1,68 @@ +# Implementation Plans + +Working notes and implementation details for AI agents and developers. + +## Purpose + +This directory contains: + +- Step-by-step implementation plans +- Working notes during development +- AI-agent context for executing RFCs +- Completed work logs with key decisions + +## What Belongs Here + +- Implementation details and code snippets +- Debugging notes and discoveries +- Task breakdowns for complex features +- Post-implementation summaries + +## What Doesn't Belong Here + +Design proposals and architectural decisions belong in `/rfcs`. This directory is for **how** to implement, not **what** or **why**. + +## Compaction Rule + +Before merging a PR, compact completed plans: + +1. Remove verbose implementation details +2. Point to PR and commits for specifics +3. Keep key decisions and important notes +4. Update status to COMPLETED + +Example compacted plan: + +```markdown +# Feature Name + +**Status:** COMPLETED +**PR:** [#123](https://github.com/videojs/v10/pull/123) + +## Summary + +Brief description of what was implemented. + +## Key Decisions + +- Decision 1: Rationale +- Decision 2: Rationale + +## Notes + +Any gotchas or important context for future reference. +``` + +## Relationship to RFCs + +Plans may link to their parent RFC: + +```markdown +# Implementing Feature X + +**RFC:** [/rfcs/feature-x.md](/rfcs/feature-x.md) + +## Tasks + +... +``` diff --git a/.claude/plans/store/bindings.md b/.claude/plans/store/bindings.md index 1bca06bc..d11ab290 100644 --- a/.claude/plans/store/bindings.md +++ b/.claude/plans/store/bindings.md @@ -1,38 +1,29 @@ # Store React/DOM Bindings -> **STATUS: COMPLETED** — Superseded by `proxies.md` for API changes. +**Status:** COMPLETED (Superseded by reactive.md) ## Summary -Implemented React and Lit bindings for `@videojs/store`: +Implemented React and Lit bindings for `@videojs/store`: `createStore()` factory returning Provider + hooks/controllers. -- `createStore()` factory returning Provider + hooks/controllers -- Skins define store configs, export Provider + Skin + extendConfig -- Base hooks/controllers for testing and advanced use +## Key PRs -## Completed Work - -| Phase | PR | Description | -| ----- | ----------------------------------------------- | ------------------------------------------------------------- | -| 0 | [#283](https://github.com/videojs/v10/pull/283) | `uniqBy`, `composeCallbacks`, `extendConfig` utilities | -| 0.5 | [#287](https://github.com/videojs/v10/pull/287) | Queue task refactor (unified tasks map, status discriminator) | -| 1 | [#288](https://github.com/videojs/v10/pull/288) | React bindings (createStore, Provider, hooks) | -| 2 | [#289](https://github.com/videojs/v10/pull/289) | Lit bindings (controllers, mixins, context) | -| 3 | [#292](https://github.com/videojs/v10/pull/292) | DOM media slices (playback, time, buffer, volume, source) | -| 4 | [#290](https://github.com/videojs/v10/pull/290) | Mutation hooks/controllers | -| 5 | [#291](https://github.com/videojs/v10/pull/291) | Optimistic hooks/controllers | -| 6 | [#298](https://github.com/videojs/v10/pull/298) | Frosted skin (React + HTML) | +| Phase | PR | Description | +| ----- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------ | +| 0 | [#283](https://github.com/videojs/v10/pull/283) | `uniqBy`, `composeCallbacks`, `extendConfig` utilities | +| 0.5 | [#287](https://github.com/videojs/v10/pull/287) | Queue task refactor | +| 1 | [#288](https://github.com/videojs/v10/pull/288) | React bindings | +| 2 | [#289](https://github.com/videojs/v10/pull/289) | Lit bindings | +| 3 | [#292](https://github.com/videojs/v10/pull/292) | DOM media slices | +| 4-5 | [#290](https://github.com/videojs/v10/pull/290), [#291](https://github.com/videojs/v10/pull/291) | Mutation/Optimistic hooks | +| 6 | [#298](https://github.com/videojs/v10/pull/298) | Frosted skin | ## Key Decisions -- Hook naming: `useStore`, `useSelector`, `useRequest`, `useTasks`, `useMutation`, `useOptimistic` -- Controller naming: `SelectorController`, `RequestController`, `TasksController`, etc. -- Mutation/Optimistic: Discriminated union types with `status` field -- Lit mixins: `StoreMixin` (combined), `StoreProviderMixin`, `StoreAttachMixin` -- Provider resolution: Isolated by default; `inherit` prop for parent context - Package structure: `store/react` and `store/lit` +- Provider resolution: Isolated by default; `inherit` prop for parent context +- Lit mixins: `StoreMixin` (combined), `StoreProviderMixin`, `StoreAttachMixin` -## Superseded By +## Notes -The selector-based APIs (`useSelector`, `SelectorController`, `store.subscribe()`) are being -replaced by proxy-based reactivity. See **`proxies.md`** for the migration plan. +Selector-based APIs were later replaced by proxy-based reactivity. See `reactive.md`. diff --git a/.claude/plans/store/queue-simplification.md b/.claude/plans/store/queue-simplification.md index 2ece7a08..f35d79bd 100644 --- a/.claude/plans/store/queue-simplification.md +++ b/.claude/plans/store/queue-simplification.md @@ -1,42 +1,26 @@ # Queue Simplification -> **STATUS: COMPLETED** +**Status:** COMPLETED ## Summary -Simplified Queue from ~524 LOC to ~405 LOC. Removed convenience features only used in tests/docs, kept what's essential for async media operations. +Simplified Queue from ~524 LOC to ~405 LOC. Removed convenience features only used in tests/docs, kept essentials for async media operations. ## Why Queue Exists -All writes are async requests — this is the architecture. Queue handles: +All writes are async requests. Queue handles: - Supersession (rapid clicks → only last executes) - AbortController propagation - Task lifecycle tracking (pending/success/error) - Error surfacing for UI -## Features Removed +## Removed -- `cancel()` method (use `abort()`) -- `flush()` method (no configurable scheduling) -- `queued` getter (internal detail) -- `TaskScheduler` type, `QueueConfig` interface -- `delay()`, `microtask` exports -- `schedule` param on `QueueTask` +- `cancel()`, `flush()`, `queued` getter +- `TaskScheduler`, `QueueConfig`, `schedule` param +- `delay()`, `microtask`, DOM schedulers (`raf()`, `idle()`) - `onDispatch`, `onSettled` hooks -- DOM schedulers (`raf()`, `idle()`) - -## Files Changed - -| File | Change | -| ------------------------- | ------------------------------------ | -| `core/queue.ts` | Main simplification | -| `core/task.ts` | NEW: Extracted task types and guards | -| `core/index.ts` | Added task.ts export | -| `core/request.ts` | Removed schedule field | -| `core/store.ts` | Removed schedule from enqueue | -| `dom/` | DELETED entire directory | -| Various controllers/hooks | Updated imports | ## Final API diff --git a/.claude/plans/store/reactive.md b/.claude/plans/store/reactive.md index 19464436..519ceeb2 100644 --- a/.claude/plans/store/reactive.md +++ b/.claude/plans/store/reactive.md @@ -1,9 +1,19 @@ # Reactive State -**Status:** COMPLETE +**Status:** COMPLETED **PR:** [#311](https://github.com/videojs/v10/pull/311) -Replaced class-based `State` with proxy-based reactive primitives. Inspired by [Valtio](https://github.com/pmndrs/valtio). +## Summary + +Replaced class-based `State` with proxy-based reactive primitives inspired by Valtio. + +## Key Decisions + +| Decision | Rationale | +| ----------------------------- | ---------------------------------------------------- | +| Auto-batch to microtask | Coalesce rapid mutations, export `flush()` for tests | +| React: `useSyncExternalStore` | Version counter for change detection | +| Lit: `SnapshotController` | `host.requestUpdate()` + optional callback | ## API @@ -11,53 +21,8 @@ Replaced class-based `State` with proxy-based reactive primitives. Inspired by [ import { batch, flush, reactive, snapshot, subscribe, subscribeKeys, track } from '@videojs/store'; ``` -| Export | Purpose | -| -------------------------------- | ---------------------------------------------- | -| `reactive(initial)` | Create reactive state with parent bubbling | -| `isReactive(value)` | Check if value is reactive | -| `subscribe(state, fn)` | Subscribe to all changes | -| `subscribeKeys(state, keys, fn)` | Subscribe to specific key changes | -| `batch(fn)` | Group mutations, flush after | -| `flush()` | Force pending notifications (for tests) | -| `snapshot(state)` | Return frozen shallow copy | -| `track(state)` | Track property access for fine-grained updates | - -## Key Behaviors - -- **Auto-batching** — Notifications deferred to microtask -- **Nested tracking** — Auto-wraps nested objects, changes bubble to parents -- **Synchronous reads** — Mutations apply immediately, only notifications are deferred - -## Decisions - -| Question | Decision | -| ------------- | -------------------------------------------------------------------- | -| Batching | Auto-batch to microtask. Export `flush()` for tests. | -| React pattern | `useSyncExternalStore` with version counter for change detection | -| Lit pattern | `SnapshotController` with `host.requestUpdate()` + optional callback | - ## Breaking Changes -**Removed:** +Removed: `useMutation`, `useOptimistic`, `useSelector`, `MutationController`, `OptimisticController`, `SelectorController` -- React: `useMutation`, `useOptimistic`, `useSelector` -- Lit: `MutationController`, `OptimisticController`, `SelectorController` - -**Migration:** - -| Before | After | -| ----------------------------------- | ------------------------------------- | -| `useSelector(store, s => s.volume)` | `useSnapshot(store.state).volume` | -| `useMutation(store, 'play')` | `useSnapshot(store.queue.tasks).play` | -| `SelectorController` | `SnapshotController` | -| `store.subscribe(fn)` | `subscribe(store.state, fn)` | - -## Testing - -Use `flush()` for synchronous assertions: - -```ts -state.volume = 0.5; -flush(); -expect(listener).toHaveBeenCalledOnce(); -``` +Migration: Use `useSnapshot(store.state)` and `subscribe(store.state, fn)` instead. diff --git a/.claude/skills/git/references/scope.md b/.claude/skills/git/references/scope.md index a46d6fca..31bcba15 100644 --- a/.claude/skills/git/references/scope.md +++ b/.claude/skills/git/references/scope.md @@ -13,8 +13,8 @@ Infer commit scope from changed file paths. | `packages/react/` | `react` | | `packages/react-native/` | `react-native` | | `packages/icons/` | `icons` | -| `packages/skins/` | `skins` | | `site/` | `site` | +| `rfcs/` | `rfc` | | `.claude/` | `claude` | | `.github/workflows/` | `ci` | | `.github/` | `cd` | @@ -34,7 +34,7 @@ From `commitlint.config.js`: ``` cd, ci, claude, core, docs, html, icons, packages, -plan, react-native, react, root, site, skins, store, +plan, react-native, react, rfc, root, site, store, test, utils ``` diff --git a/CLAUDE.md b/CLAUDE.md index 236bd983..1e23e691 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -475,6 +475,19 @@ get size(): number { ... } add(cleanup: CleanupFn): void { ... } ``` +## Design Documents + +| Location | Purpose | +| ---------------- | ----------------------------------------------------------------- | +| `rfcs/` | Design proposals, API decisions, architecture — public discussion | +| `.claude/plans/` | Implementation notes, AI-agent context, working drafts | + +**RFCs** focus on **what** and **why**. Write an RFC for major API changes, architectural decisions, or patterns used across packages. + +**Implementation plans** focus on **how**. Use `.claude/plans/` for step-by-step implementation details, debugging notes, and AI-agent context. + +Before merging, compact completed plans: keep key decisions and important notes, point to PRs/commits for details. See `.claude/plans/README.md`. + ## Rule Placement CLAUDE.md contains repo-wide conventions. Domain-specific patterns live in skills: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8e201a0e..5f9ad8c6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -79,10 +79,7 @@ pnpm dev This will run the entire workspace in developer mode, meaning all applications (examples and website) will also be started on their respective ports. ```sh -# Run a specific app -pnpm dev:html -pnpm dev:react -pnpm dev:next +# Run the documentation site pnpm dev:site ``` @@ -175,6 +172,18 @@ When your changes introduce new patterns: - **Code conventions** → Update `CLAUDE.md` Code Rules section - **Domain patterns** → Update relevant skill in `.claude/skills/` +## RFCs (Design Documents) + +For significant architectural decisions and API designs, we use RFCs (Request for Comments). See [`rfcs/README.md`](./rfcs/README.md) for the full process. + +**When to write an RFC:** + +- Introducing a new public API surface +- Making architectural changes affecting multiple packages +- Proposing patterns used throughout the codebase + +**Skip the RFC for:** Bug fixes, small contained features, implementation details. + ## Creating a Pull Request By submitting a pull request, you agree that your contribution is provided under the diff --git a/README.md b/README.md index 0875a02b..16b54bf5 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Modern, modular, and composable media player framework for Web and React. Thanks for checking out the project! It's in its early stages and currently a mix of prototyping and early structure pointing in the direction we want to go with Video.js v10 (so be kind 🙏). -- Read our [early architecture goals][architecture]. +- Read our [design documents][rfcs]. - Read the [v10 discussion topic][v10-discussion]. - Watch [Heff's recent presentation][heff-presentation]. @@ -58,7 +58,7 @@ Please see our [contributing guide](./CONTRIBUTING.md) for getting setup locally Please note that this project is released with a [Contributor Code of Conduct][coc]. By participating in this project you agree to abide by its terms. -[architecture]: ./docs/ARCHITECTURE.md +[rfcs]: ./rfcs [v10-discussion]: https://github.com/videojs/video.js/discussions/9035 [heff-presentation]: https://players.brightcove.net/3737230800001/eyILA5XG7K_default/index.html?videoId=6379311036112 [coc]: https://github.com/videojs/video.js/blob/main/CODE_OF_CONDUCT.md diff --git a/commitlint.config.js b/commitlint.config.js index 320f5dcb..e7634e85 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -9,30 +9,28 @@ export default { }, ], rules: { - 'scope-enum': [2, 'always', [ - 'cd', - 'ci', - 'claude', - 'core', - 'docs', - 'demo', - 'example', - 'examples', - 'example/html', - 'example/react', - 'example/next', - 'html', - 'icons', - 'packages', - 'plan', - 'react-native', - 'react', - 'root', - 'site', - 'skins', - 'store', - 'test', - 'utils', - ]], + 'scope-enum': [ + 2, + 'always', + [ + 'cd', + 'ci', + 'claude', + 'core', + 'docs', + 'html', + 'icons', + 'packages', + 'plan', + 'react-native', + 'react', + 'rfc', + 'root', + 'site', + 'store', + 'test', + 'utils', + ], + ], }, }; diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md deleted file mode 100644 index e3ff3d48..00000000 --- a/docs/ARCHITECTURE.md +++ /dev/null @@ -1,58 +0,0 @@ -# Video.js 10 Architecture - -**Status:** Technical Preview (initial working showcase for Demuxed) - -- Current codebase is an early push by the team to have a working showcase for Demuxed. -- Architecture and patterns will evolve as we refine and plan the long‑term structure. - -## Early Goals - -- Establish a common, TanStack‑based core for consistent state management across supported platforms and frameworks. -- Ensure composition and compound patterns are first‑class. -- Adopt TypeScript throughout for safety and DX. -- Design for modularity, tree‑shaking, and performance. -- Fully support SSR / hydration. -- Create a compiler to handle transformation and output across multiple JS and CSS frameworks. - -## Core Principles - -- **Common Core:** TanStack state-driven architecture; DOM lives in a separate package; maps to web, React, and React Native. -- **Composition-first:** Compound component and functional patterns. E.g., React has `render(attrs, state)` prop to allow full control of element type or animations. -- **TypeScript everywhere.** -- **Modular & tree-shakeable.** -- **Performance-focused:** Minimal bundle size and payload, smooth 60+ FPS target. -- **SSR + hydration safe/optimized.** - -## Accessibility - -- Non-negotiable. -- Core owns ARIA roles, labels, navigation, and focus. -- Captions, keyboard navigation/shortcuts, and focus management. -- Meets WCAG 2.2 / CVAA standards out‑of‑box. - -## State & Reactivity - -- State hooks and components support **controlled/uncontrolled** mode (`value` / `onChange`). -- State-driven architecture powers Web, React, and React‑Native. -- Maintain 16 ms frame budget. -- Offload heavy style computations to CSS. -- Minimal playback engine per user case. -- Stream + lazy caption parsing for large files. -- SSR: preload rendition segments in document head, ship parsed manifest, minimal composed-playback engine for faster TTF (time‑to‑first‑frame). - -## Styling - -- **Style‑agnostic core:** No CSS shipped in Core or Primitives. -- **Style‑ready hooks:** Stable `data-*` attrs and CSS vars for easy theming. -- Default skins in separate exports (optional entry points). -- Primitives avoid Shadow DOM; themed skins may opt in. -- DOM trees stay one level deep per component part (Root, Thumb, Track, etc.). -- No internal JS animations. -- Components toggle data attributes (`data-open`, `data-starting-style`, etc.) for CSS or Motion libraries to hook into. - -## Cross‑Browser Compatibility - -- Ensure consistent behavior across major browsers. -- Abstract differences in media APIs (fullscreen, PiP, captions, streaming). -- Normalize vendor‑specific features through adapters and polyfills. -- Maintain uniform rendering, controls, and accessibility regardless of platform. diff --git a/rfcs/README.md b/rfcs/README.md new file mode 100644 index 00000000..7d047812 --- /dev/null +++ b/rfcs/README.md @@ -0,0 +1,88 @@ +# RFCs + +Request for Comments (RFC) documents for Video.js 10 architecture and API design decisions. + +## What Belongs Here + +RFCs document significant design decisions that benefit from review and discussion: + +- Major API changes or new APIs +- Architectural decisions +- Design patterns used across packages +- Breaking changes with migration paths + +## When to Write an RFC + +Write an RFC when: + +- Introducing a new public API surface +- Making architectural changes that affect multiple packages +- Proposing patterns that will be used throughout the codebase +- Changes need input from multiple contributors + +Skip the RFC for: + +- Bug fixes +- Small features contained to one package +- Implementation details that don't affect public APIs +- Documentation updates + +## File Format + +RFCs use a YAML frontmatter header for status tracking: + +```markdown +--- +status: draft +--- + +# Title + +Content... +``` + +When implemented, add implementation details: + +```markdown +--- +status: implemented +implemented-in: v10.0.0-alpha.5 +implementation-plan: .claude/plans/example.md +--- +``` + +## Status Lifecycle + +| Status | Meaning | +| ------------- | ---------------------------------- | +| `draft` | Under discussion, not yet accepted | +| `accepted` | Approved for implementation | +| `implemented` | Code shipped | +| `superseded` | Replaced by another RFC | + +## Directory Structure + +``` +rfcs/ +├── README.md # This file +├── feature-name.md # Single-file RFC +└── feature-name/ # Multi-file RFC + ├── index.md # Overview and quick start + ├── decisions.md # Design decisions and rationale + └── examples.md # Usage examples +``` + +## Relationship to Implementation Plans + +RFCs focus on **what** and **why** — the design, rationale, and public API. + +Implementation details live in `.claude/plans/` — step-by-step plans, code snippets, and AI-agent context for executing the RFC. + +An RFC may link to its implementation plan: + +```markdown +--- +status: implemented +implementation-plan: .claude/plans/feature-name.md +--- +``` diff --git a/.claude/plans/player-api/architecture.md b/rfcs/player-api/architecture.md similarity index 100% rename from .claude/plans/player-api/architecture.md rename to rfcs/player-api/architecture.md diff --git a/.claude/plans/player-api/decisions.md b/rfcs/player-api/decisions.md similarity index 100% rename from .claude/plans/player-api/decisions.md rename to rfcs/player-api/decisions.md diff --git a/.claude/plans/player-api/examples.md b/rfcs/player-api/examples.md similarity index 100% rename from .claude/plans/player-api/examples.md rename to rfcs/player-api/examples.md diff --git a/.claude/plans/player-api/index.md b/rfcs/player-api/index.md similarity index 99% rename from .claude/plans/player-api/index.md rename to rfcs/player-api/index.md index 1b67dcd6..271e16e9 100644 --- a/.claude/plans/player-api/index.md +++ b/rfcs/player-api/index.md @@ -1,3 +1,7 @@ +--- +status: draft +--- + # Player API Design Unified API for Media and Container concerns. Two stores internally, one API for users. diff --git a/.claude/plans/slice-availability.md b/rfcs/slice-availability.md similarity index 99% rename from .claude/plans/slice-availability.md rename to rfcs/slice-availability.md index 8cd39b37..e8ad5210 100644 --- a/.claude/plans/slice-availability.md +++ b/rfcs/slice-availability.md @@ -1,3 +1,7 @@ +--- +status: draft +--- + # Slice Availability Design ## The Problem diff --git a/.claude/plans/store/queue-design.md b/rfcs/store/queue-design.md similarity index 99% rename from .claude/plans/store/queue-design.md rename to rfcs/store/queue-design.md index 2175825e..bbb9a83a 100644 --- a/.claude/plans/store/queue-design.md +++ b/rfcs/store/queue-design.md @@ -1,3 +1,7 @@ +--- +status: implemented +--- + # Store Queue Design ## Overview From d09fa956896d1fc293a72d4bfddaf366d7732236 Mon Sep 17 00:00:00 2001 From: Rahim Date: Tue, 20 Jan 2026 15:04:46 +1100 Subject: [PATCH 2/3] docs(rfc): add RFC PR workflow conventions --- .claude/skills/git/references/pr.md | 4 +++- rfcs/README.md | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/.claude/skills/git/references/pr.md b/.claude/skills/git/references/pr.md index f8c0166d..8b9b0635 100644 --- a/.claude/skills/git/references/pr.md +++ b/.claude/skills/git/references/pr.md @@ -14,9 +14,11 @@ type(scope): lowercase description | Prefix | Use for | | ------------ | ------------------------------------ | -| `RFC:` | Request for comments / proposals | +| `[RFC]` | Request for comments / proposals | | `Discovery:` | Exploration / research / prototyping | +**Note:** RFC PRs use `[RFC] Title` format while open. When merged, the squash commit uses `docs(rfc): title`. + ## PR Body Template ```markdown diff --git a/rfcs/README.md b/rfcs/README.md index 7d047812..c9585e62 100644 --- a/rfcs/README.md +++ b/rfcs/README.md @@ -72,6 +72,29 @@ rfcs/ └── examples.md # Usage examples ``` +## Contributing an RFC + +### Branch and PR Workflow + +1. **Create branch**: `rfc/feature-name` +2. **PR title while open**: `[RFC] Feature Name` +3. **Squash commit when merged**: `docs(rfc): feature name` + +### Example + +```bash +git checkout -b rfc/slice-accessor-design +# ... write RFC ... +git push -u origin rfc/slice-accessor-design +gh pr create --title "[RFC] Slice Accessor Design" +``` + +When the RFC is accepted and merged, the squash commit becomes: + +``` +docs(rfc): slice accessor design +``` + ## Relationship to Implementation Plans RFCs focus on **what** and **why** — the design, rationale, and public API. From e9776aeeebd016387ece2ae67cc27737025884c0 Mon Sep 17 00:00:00 2001 From: Rahim Date: Tue, 20 Jan 2026 16:09:37 +1100 Subject: [PATCH 3/3] chore: move slice-availability back to plans --- {rfcs => .claude/plans}/slice-availability.md | 4 ---- 1 file changed, 4 deletions(-) rename {rfcs => .claude/plans}/slice-availability.md (99%) diff --git a/rfcs/slice-availability.md b/.claude/plans/slice-availability.md similarity index 99% rename from rfcs/slice-availability.md rename to .claude/plans/slice-availability.md index e8ad5210..8cd39b37 100644 --- a/rfcs/slice-availability.md +++ b/.claude/plans/slice-availability.md @@ -1,7 +1,3 @@ ---- -status: draft ---- - # Slice Availability Design ## The Problem