diff --git a/.agents/skills/bmad-build/SKILL.md b/.agents/skills/bmad-build/SKILL.md new file mode 100644 index 000000000..df893a9ad --- /dev/null +++ b/.agents/skills/bmad-build/SKILL.md @@ -0,0 +1,8 @@ +--- +name: bmad-build +description: "Implement a bounded repository change with the shared BMAD build workflow and local gates." +--- + +Read and follow `~/.codex/skills/bmad-build/SKILL.md` with this repository as the project root. +This entrypoint intentionally uses the shared personal workflow directly; do not run the legacy +BMAD renderer or adjacent workflow snapshots. Preserve this repository's authority and local gates. diff --git a/.agents/skills/bmad-checkpoint-preview/SKILL.md b/.agents/skills/bmad-checkpoint-preview/SKILL.md new file mode 100644 index 000000000..8d13941ea --- /dev/null +++ b/.agents/skills/bmad-checkpoint-preview/SKILL.md @@ -0,0 +1,8 @@ +--- +name: bmad-checkpoint-preview +description: "Guide human review of a change with orientation, concern walkthrough, risk details, and observation." +--- + +Read and follow `~/.codex/skills/bmad-checkpoint-preview/SKILL.md` with this repository as the project root. +This entrypoint intentionally uses the shared personal workflow directly; do not run the legacy +BMAD renderer or adjacent workflow snapshots. Preserve this repository's authority and local gates. diff --git a/.agents/skills/bmad-qa/SKILL.md b/.agents/skills/bmad-qa/SKILL.md new file mode 100644 index 000000000..d0366344b --- /dev/null +++ b/.agents/skills/bmad-qa/SKILL.md @@ -0,0 +1,8 @@ +--- +name: bmad-qa +description: "Review changes with the shared BMAD QA process and local domain gates; fix only when requested." +--- + +Read and follow `~/.codex/skills/bmad-qa/SKILL.md` with this repository as the project root. +This entrypoint intentionally uses the shared personal workflow directly; do not run the legacy +BMAD renderer or adjacent workflow snapshots. Preserve this repository's authority and local gates. diff --git a/.agents/skills/conformance/SKILL.md b/.agents/skills/conformance/SKILL.md index 7301f4672..e5ba6eeea 100644 --- a/.agents/skills/conformance/SKILL.md +++ b/.agents/skills/conformance/SKILL.md @@ -29,13 +29,10 @@ each runtime passes the same language-agnostic scenarios. ## Code-intelligence routing -For each indexed runtime implementation, call `codegraph_explore` before raw source Read/`rg` to locate the -scenario harness and trace the protocol symbols it exercises, their callers/dependents, adjacent tests, -public boundaries, and blast radius. Treat returned source as already read and query again only for uncovered -paths. Read spec/conformance jsonl, TLA+, configs, git diff, untracked files, and stale/unindexed files -directly. If an index is absent or disabled, use direct inspection and never initialize it autonomously. -Codegraph locates behavioral paths; the shared scenario, property tests, compiler, and runtime gates decide -conformance. +Use a current Codegraph index when it helps trace the affected symbols; use direct file reads or +`rg` for simpler lookups, unavailable tools, or stale/unindexed files. Reuse source already read. +Do not initialize an index merely to satisfy this workflow. Validate through the affected executable +checks and required gates; an index is context, not correctness evidence. ## Phase 1 — scenario integrity diff --git a/.agents/skills/dashboard/SKILL.md b/.agents/skills/dashboard/SKILL.md index fc8fd6240..89b622785 100644 --- a/.agents/skills/dashboard/SKILL.md +++ b/.agents/skills/dashboard/SKILL.md @@ -9,12 +9,10 @@ You are executing **dashboard** for the clean-slate GraphReFly redesign. ## Code-intelligence routing -Running or interpreting the dashboard needs no source survey. When debugging or changing indexed generator -implementation, call `codegraph_explore` before raw source Read/`rg` for the named generator symbol, its -callers/dependents, tests, generated-output boundary, and blast radius. Treat returned source as already read. -Read jsonl authority, README/schema text, generated HTML, configs, git diff, untracked files, and stale or -unindexed files directly. If no live index exists, use direct inspection and never initialize one -autonomously. The generator and consistency gate remain the correctness evidence. +Use a current Codegraph index when it helps trace the affected symbols; use direct file reads or +`rg` for simpler lookups, unavailable tools, or stale/unindexed files. Reuse source already read. +Do not initialize an index merely to satisfy this workflow. Validate through the affected executable +checks and required gates; an index is context, not correctness evidence. ## What this skill does diff --git a/.agents/skills/design-review/SKILL.md b/.agents/skills/design-review/SKILL.md index be791dc08..71865074b 100644 --- a/.agents/skills/design-review/SKILL.md +++ b/.agents/skills/design-review/SKILL.md @@ -1,6 +1,6 @@ --- name: design-review -description: "Validate the design of a new primitive or API surface against the 5-question lens (Q5–Q9 from the per-unit review format). Use BEFORE coding (or right after a sketch lands) when adding a new public API / pattern factory / domain primitive. Triggers: 'design review', 'review the design', 'is this the right shape', 'before I implement'. Different from /qa — that finds bugs in landed code; this validates abstraction + long-term shape + reactive composability + alternatives." +description: "Review a proposed public API, primitive, or architectural change against project constraints and resolve material design choices." --- You are executing the **design-review** workflow for the **clean-slate GraphReFly** redesign. diff --git a/.agents/skills/dev-dispatch/SKILL.md b/.agents/skills/dev-dispatch/SKILL.md index 461de2e85..689a1067e 100644 --- a/.agents/skills/dev-dispatch/SKILL.md +++ b/.agents/skills/dev-dispatch/SKILL.md @@ -1,6 +1,6 @@ --- name: dev-dispatch -description: "Implement feature/fix with planning and self-test. Use when user says 'dispatch', 'dev-dispatch', or provides a task with implementation context. Supports --light flag for bug fixes and small changes. Run /qa afterward for code review and final checks." +description: "Implement the requested feature or fix within project authority and verify affected behavior." --- You are executing the **dev-dispatch** workflow for the **clean-slate GraphReFly** redesign. @@ -14,46 +14,30 @@ This repo is **`@graphrefly/ts`** — the self-contained TypeScript implementati The user's task/context is: $ARGUMENTS ### Mode detection -If `$ARGUMENTS` contains `--light`, this is **light mode**. Otherwise **full mode**. Differences are noted inline per phase. +Use a focused workflow for routine fixes and a fuller plan for substantial changes. `--light` remains +supported. Neither mode requires another approval for work already authorized by the user; pause +for unresolved semantic/architectural decisions or an action outside the approved scope. -### Repository ownership practice +### Shared build and preview -Apply the global `repository-ownership-practice` skill unless `$ARGUMENTS` explicitly contains -`--delivery-only`. - -- Before broad context loading, pause for the user's OWN card and best-effort PREDICT card. -- Map one concrete input-to-output path before proposing implementation. Limit the implementation map to five - files and eight symbols; targeted authority records do not count toward that cap, but load only records that - govern the slice. -- Preserve the user's first debugging pass: hypotheses and cheapest discriminators before a generated fix. -- Freeze one Given/When/Then behavior and its stopping boundary before code. -- Finish with diff, behavior, and trace evidence plus the user's TEACH-BACK checkpoint and next-day five - questions. -- Do not begin another slice in the same turn after the teach-back checkpoint. Waiting for the user leaves any - Goal active; it is not a blocker. - -`--delivery-only` skips waiting for the user's cards and teach-back, not the narrow map, frozen contract, -three-layer verification, or ownership handoff. Label such work `delivered, not yet ownership-verified`. +Use `~/.codex/skills/bmad-build/SKILL.md` inside the selected implementation slice, retaining this +workflow's authority, sequencer and gates. Use `~/.codex/skills/bmad-checkpoint-preview/SKILL.md` for +human review: build-handoff mode during ordinary delivery; interactive mode for explicit checkpoint +or `--practice` requests. No prediction or teach-back is required. ### Workflow floor (non-negotiable) -- **decision-first and owner-first**: any architectural lock needs an origin-qualified `D#` in its unique owner ledger from `~/src/graphrefly/authority/ledgers.jsonl` BEFORE code (`/design-review` → user approval → append). Cross-project/protocol locks stay in root; TypeScript-only product or implementation locks live in `graphrefly-ts:decisions/decisions.jsonl`. Decisions locked ≠ implementation approved — wait for an explicit "implement". +- **decision-first and owner-first**: any architectural lock needs an origin-qualified `D#` in its unique owner ledger from `~/src/graphrefly/authority/ledgers.jsonl` BEFORE code (`/design-review` → user approval → append). Cross-project/protocol locks stay in root; TypeScript-only product or implementation locks live in `graphrefly-ts:decisions/decisions.jsonl`. A design lock alone is not implementation approval; the current implementation request can supply that approval. - **spec-first** (F-NO-IMPL-DEFINED): any wave-protocol behavior change amends `spec/rules.jsonl` + `formal/*.tla` + `spec/conformance.jsonl` FIRST (`/spec-amend`), THEN code. Operators/sugar/inspection are per-language (D6/D24) — NOT spec, skip spec-amend. -- **no autonomous decisions**: surface spec↔code conflicts; don't silently pick. File-by-file review for multi-file rewrites. -- **verify premise**: design tables lag code — inspect the named symbols + check landed markers (`plan/phases.jsonl` status/notes) before designing new surface; a stale premise is a HALT. +- **no autonomous decisions**: surface spec↔code conflicts; don't silently pick. Review affected boundaries for multi-file rewrites. +- **verify premise**: design tables lag code — inspect the named symbols + check landed markers (`plan/phases.jsonl` status/notes) before designing new surface; correct stale premises from current evidence; ask only if the correction changes scope or a locked decision. - **consistency gate**: after touching any `~/src/graphrefly` jsonl, run `node ~/src/graphrefly/dashboard/build.mjs --check` (non-zero on broken links / orphans). ### Code-intelligence routing -- For implementation source in a repository with a live `.codegraph` index, call `codegraph_explore` - before raw Read/`rg`. Query the named symbols or flow endpoints and request exact source, call paths, - dependents, relevant tests, export/build boundaries, and blast radius. -- Treat returned source as already read; do not re-read or grep it merely to verify Codegraph. Use another - targeted query only for uncovered symbols or paths. -- Read `AGENTS.md`, `CLAUDE.md`, skills, authority jsonl, docs, configs, generated artifacts, git diff, - untracked files, and unindexed files directly. If the index is absent/disabled or reports stale files, - follow its fallback guidance and never initialize an index autonomously. -- After edits, verify correctness with git diff, compiler/typecheck, tests, lint, build, and package/export - gates. Codegraph informs scope and blast radius; it is not a correctness gate. +Use a current Codegraph index when it helps trace the affected symbols; use direct file reads or +`rg` for simpler lookups, unavailable tools, or stale/unindexed files. Reuse source already read. +Do not initialize an index merely to satisfy this workflow. Validate through the affected executable +checks and required gates; an index is context, not correctness evidence. --- @@ -63,7 +47,8 @@ Load context and plan in a bounded pass. Read authority indexes first, then only seams governing the frozen slice. Parallelize independent targeted reads; do not load the whole design history merely because it is available. -Read in parallel (clean-slate authority): +Context index: read only the governing records and relevant implementation/tests below, reusing +material already loaded. Protocol/formal context is needed only when the changed behavior depends on it: - `~/src/graphrefly/AGENTS.md` — the single-source authority index (read FIRST). - `~/src/graphrefly/spec/rules.jsonl` — the protocol 宪法 (R-* rules); deep-read the rules your change touches. - `~/src/graphrefly/authority/ledgers.jsonl` + the resolved owner ledger — the federated decision authority (or invoke `/decision-guard` to recall the governing origin-qualified D#/values/floor). @@ -81,9 +66,9 @@ Read in parallel (clean-slate authority): While planning, validate proposed changes against the clean-slate floor (cite the rule/D#): - **Sacred (L0.7):** topology declarative/serializable/inspectable · wave protocol is a public spec · wave protocol impl is **sync** · all fn go through the dispatcher. - **8 verbs, closed (D4):** `node`/`graph`/`batch`/`state` + `producer`/`derived`/`effect`/`mount`. **Operators are `node` sugar (D6), not verbs** — per-language, never in parity (D24); real factory names show in `describe`. Adding a verb is a constitutional change. -- **Messages** `[[Type, Data?], ...]`; one array to `ctx.down`/`ctx.up` = one wave (R-msg-format). 10-type closed set, no user-defined types (R-msg-closed-set). +- **Messages** `[[Type, Data?], ...]`; one array to `ctx.down`/`ctx.up` = one wave (R-msg-format). The closed message set is defined by R-msg-closed-set; do not duplicate its count here. - **DIRTY before DATA/RESOLVED** in the same wave (R-dirty-before-data); two-phase glitch-free diamond (R-two-phase); a diamond/fan-in node recomputes exactly once after all changed deps settle (R-diamond). batch defers tier-≥3, not DIRTY. -- **`ctx.up` is control-tier only** (DIRTY/PAUSE/RESUME/INVALIDATE/TEARDOWN); DATA/RESOLVED/COMPLETE/ERROR are down-only (R-ctx-up, D8). A handle is pure data, no methods (D7). +- **`ctx.up`**: read the current control/demand boundary in R-ctx-up before changing its behavior. A handle is pure data, no methods (D7). - **No polling** (R-no-polling); **no imperative triggers** (R-no-imperative — reactive `ctx.up`/signals, not emitters/callbacks/timers+set; remove imperative paths when no caller depends); **no raw async** in the sync core (R-no-raw-async / F-SYNC-CORE — async lives only in sources / the pool / the wire bridge). - **All fn through the dispatcher** (R-dispatch-all / F-DISPATCH-ALL — no inline-fn bypass). `dispatcher.invoke` is sync void (R-sync-core). - **Data moves via messages** (R-data-not-peek — never peek a dep's `.cache` to seed compute; `.cache` is a read-only accessor for external consumers). SENTINEL = absence-of-DATA (R-sentinel); the canonical never-emitted detector is `ctx.prevData[i] === undefined`. @@ -95,56 +80,24 @@ While planning, validate proposed changes against the clean-slate floor (cite th **Targeting a sibling (py/rust):** if the task targets `@graphrefly/py` (`~/src/graphrefly-py`) or `@graphrefly/rust` (`~/src/graphrefly-rs`), read that package's local layout + its conformance arm status in `spec/conformance.jsonl`. The cross-language contract is **behavioral conformance (D24)**, not symbol parity. PY public APIs are synchronous (return `Node[T]`/`Graph`/value, no `async def`); async lives at the source/pool boundary only (F-SYNC-CORE). -Do NOT start implementing yet. --- -## Phase 2: Architecture Discussion - -### Full mode — HALT - -**HALT and report before implementing.** Present: - -1. **Architecture assumptions** — how this fits the substrate (`node`/`dispatcher`/`ctx`/`protocol`/`batch`) vs graph-layer (`graph/`) split. -2. **New patterns** — any not yet in `packages/ts/src/`. -3. **Options considered** — alternatives with pros/cons. -4. **Recommendation** — preferred approach + why. - -Prioritize (in order): -1. **Correctness** — matches `~/src/graphrefly/spec/rules.jsonl` + the floor. -2. **Completeness** — edge cases (errors, COMPLETE, reconnect/reactivate, diamonds, SENTINEL gate, PAUSE lockset). -3. **Consistency** — matches patterns already in `packages/ts/src/`. -4. **Simplicity** — minimal solution. - -No backward compatibility (pre-1.0). +## Phase 2: Resolve material decisions -**Escalation routing** (don't silently pick — no-autonomous-decisions): -- Architectural lock → `/design-review` → user approval → append a `D#` to `decisions.jsonl`. -- Wave-protocol behavior change → `/spec-amend` (spec-first: rules + TLA+ + conformance, THEN code). -- Cross-runtime concern → `/conformance` (behavioral scenario, not structural diff). -- Deferred/open question with no answer yet → append to `~/src/graphrefly/plan/backlog.jsonl` (B# + trigger); a recurring anti-pattern → `plan/antipatterns.jsonl` (+ a `feedback_*` memory if generalizable). - -**Wait for user approval before proceeding.** - -### Light mode — Skip unless escalation needed - -Proceed directly to Phase 3 **unless** Phase 1 reveals any of these: -- A change to **wave-protocol behavior** (tiers, wave semantics, diamond/equals/SENTINEL, batch, push-on-subscribe, ctx.up/down contract) → spec-first, escalate. -- A new architectural lock with no governing `D#`. -- Multiple viable approaches with non-obvious trade-offs. - -If any apply: HALT and present findings as in full mode. - ---- +Proceed with authorized implementation when existing decisions govern the behavior. Explain material +assumptions and tradeoffs briefly. Ask only when an unresolved choice changes product semantics, +public contract, architecture, or authorization. Preserve spec-first amendments and owner-ledger +approval for new locks; a locked design alone does not authorize implementation when the user deferred it. ## Phase 3: Implementation & Self-Test -After user approves (full mode) or after Phase 1 (light mode, no escalation): +Once implementation is authorized and material decisions are resolved: 1. Implement the changes. - Treat `~/src/graphrefly/spec/rules.jsonl` as non-negotiable for behavior; if code drifts from a rule, align to the rule — or surface the conflict, don't silently pick. - Cite the governing R-id / D# in test expectations. -2. Create tests (per `guide/guide.jsonl` G-test — unit / property / conformance layering): +2. Add meaningful behavior tests where needed (per `guide/guide.jsonl` G-test — unit / property / conformance layering): - Put tests in the most specific existing file under `packages/ts/src/__tests__/`. - Use `graph.observe()` for live message assertions; assert at the node + message level otherwise. A behavioral-protocol change ALSO needs a `spec/conformance.jsonl` scenario (`/conformance`) before its rule flips `draft → active`. 3. Run checks: @@ -155,5 +108,5 @@ After user approves (full mode) or after Phase 1 (light mode, no escalation): If implementation leaves an **open architectural decision** (deferred behavior, parity caveat, "needs spec" item), append it to `~/src/graphrefly/plan/backlog.jsonl` (B# + trigger) — NOT a docs file. If it **lands or advances a CSP-* phase**, update that phase's `status`/`note` in `~/src/graphrefly/plan/phases.jsonl`, flip any conformance-backed `draft` rule to `active` once its scenario is green per arm, then run the consistency gate. -When done, briefly list files changed and new exports added. Run the ownership handoff before suggesting `/qa`. -In practice mode, wait for the user's teach-back before starting another implementation slice. +When done, briefly list files changed and new exports added. Apply the shared BMAD QA process with local gates, then provide the checkpoint preview trail. +Wait for review navigation only when interactive checkpoint mode was explicitly requested. diff --git a/.agents/skills/qa/SKILL.md b/.agents/skills/qa/SKILL.md index ee77b4fe3..08fa4c521 100644 --- a/.agents/skills/qa/SKILL.md +++ b/.agents/skills/qa/SKILL.md @@ -1,8 +1,14 @@ --- name: qa -description: "Adversarial code review, apply fixes, final checks (test/lint/build), and doc updates. Run after /dev-dispatch or any manual implementation. Use when user says 'qa', 'review', or 'code review'. Supports --skip-docs to skip documentation phase." +description: "Review project changes and verify affected behavior or required phase gates. Apply fixes only within an implementation or QA-and-fix request." --- +Read `~/.codex/skills/bmad-build/references/qa.md` for the shared review lenses, five-way triage and +repair loop. Integrate the domain checks below into that one review; retain this repository's canonical +completion verdict. Review-only remains read-only, including documentation and authority records. +Finish with `~/.codex/skills/bmad-checkpoint-preview/SKILL.md` in build-handoff mode unless interactive +review was requested. + You are executing the **qa** workflow for the **clean-slate GraphReFly** redesign. This repo is **`@graphrefly/ts`** — the self-contained TypeScript implementation (D32); clean-slate code lives in **`packages/ts/src/`**. Siblings (each self-contained, cross-language = wire bridge, never in-process): `@graphrefly/rust` (`~/src/graphrefly-rs`), `@graphrefly/py` (`~/src/graphrefly-py`). The language-neutral authority (spec / decisions / plan / conformance / formal) lives in **`~/src/graphrefly`** (branch `clean-slate`) as jsonl — when this skill and that repo disagree, that repo wins (AGENTS.md). @@ -33,42 +39,21 @@ Read the diff, untracked/stale files, authority jsonl, docs, configs, and genera the index is absent/disabled or reports stale files, follow its fallback guidance and never initialize it autonomously. Codegraph does not replace diff review, compiler/typecheck, tests, lint, build, or export gates. -Also load the clean-slate context the review must NOT contradict: +Read the governing entries from the following index when relevant to the changed behavior: - `~/src/graphrefly/spec/rules.jsonl` — the protocol 宪法 (R-* rules); the behavior authority. Cite R-ids in findings. - `~/src/graphrefly/authority/ledgers.jsonl` + the resolved owner ledger — the governing origin-qualified D# (or `/decision-guard`); the F-* floor + durable values. - `~/src/graphrefly/plan/backlog.jsonl` + `plan/antipatterns.jsonl` — **already-acknowledged deferred concerns (B#) and known anti-patterns. DO NOT raise a finding that matches an existing deferred B# or antipattern** — those are accepted. DO raise a finding that *contradicts* a deferred entry's stated scope. - `~/src/graphrefly/spec/conformance.jsonl` — the C-* scenarios the change must keep green (+ their `runtimes` status). - `~/src/graphrefly/formal/*.tla` — when the change implements a formally-modeled rule, cross-check the impl against the TLC-verified model. -### 1b. Launch parallel review subagents - -Launch as parallel Agent calls. Each receives the diff + the context from $ARGUMENTS (what was implemented and why). Tell each to do a STATIC review (no servers, no test runs) and return ONLY a findings list. - -**Subagent 1: Blind Hunter** — pure code review, no project context: -> You are a Blind Hunter code reviewer. Review this diff for: logic errors, off-by-one, race/re-entrancy hazards, resource leaks (unclosed subscriptions, unbounded registries), stale-closure / index-desync bugs, missing error handling, dead/unreachable code, sparse-array holes, security issues. For Python, also check thread/free-threaded safety. Be adversarial — assume bugs exist; trace the suspicious paths concretely. If a suspicious path is actually correct, say so in one line rather than raising noise. Output each finding as: **title** | **severity** (critical/major/minor) | **location** (file:line) | **detail** (trigger + consequence + suggested fix). - -**Subagent 2: Edge Case Hunter** — clean-slate spec-aware: -> You are an Edge Case Hunter reviewing a change against the GraphReFly clean-slate SPEC. The authority is the root spec plus the federated owner ledgers indexed by `~/src/graphrefly/authority/ledgers.jsonl` (branch clean-slate) — NOT any docs/*.md or packages/pure-ts (retired port-model; ignore). Read the relevant `spec/rules.jsonl` R-* rules + uniquely resolved origin-qualified D# for the area under review, and the matching `spec/conformance.jsonl` C-* + `formal/*.tla` model if the change implements a spec-locked behavior. -> -> Check protocol/wave invariants against the rules: message tuples `[[Type,Data?]]`, one array = one wave (R-msg-format); DIRTY-before-DATA in the same wave (R-dirty-before-data); two-phase glitch-free diamond, recompute-once (R-two-phase/R-diamond); ctx.up control-tier-only (R-ctx-up); SENTINEL = absence-of-DATA, never-emitted detector `prevData===undefined` (R-sentinel); equals DATA→RESOLVED only on a single-DATA wave (R-equals); first-run gate (R-first-run-gate); INVALIDATE idempotent + lifecycle-continue (R-invalidate-idempotent); terminal-is-forever / resubscribable reset (R-terminal); ROM/RAM cache (R-rom-ram); PAUSE lockset + modes (R-pause-lockset/R-pause-modes); reentrancy reject (R-reentrancy/D37). -> -> Flag floor violations: imperative side-channel triggers (R-no-imperative — emitters/callbacks/timers+set instead of ctx.up/message flow); polling/busy-wait (R-no-polling); bare async in the sync core (R-no-raw-async / F-SYNC-CORE — async only in sources / pool / wire bridge); inline-fn bypassing the dispatcher (R-dispatch-all / F-DISPATCH-ALL); peeking a dep `.cache` to seed compute (R-data-not-peek); hardcoded `type === "DATA"` instead of messageTier (R-tier); protocol internals (DIRTY/RESOLVED/bitmask) leaking into value-level sugar (R-primary-api-clean / DR-1); counters/inspection on the thin node (R-node-thin); a new verb (D4 closed set) or a 10th tier (D9) introduced casually; graph-level shared mutable state accessed implicitly instead of an explicit node+dep (D22/D23); cross-graph in-process coupling instead of a wire bridge (D22/D32). -> -> If the change implements a formally-modeled rule, identify any place the impl DIVERGES from the `formal/*.tla` model (cite the invariant). Surface real-but-unmodeled cross-axis interactions (e.g. X×batch, X×pause) and say whether each is a genuine gap or acceptably-deferred. DROP any finding that matches an already-acknowledged `plan/backlog.jsonl` B# or `plan/antipatterns.jsonl` entry. Output each finding as: **title** | **severity** | **location** (file:line or R-id) | **detail** (the rule/D# it relates to + what the impl does + divergence/gap/ok). - -Scale the reviewer count to the change: 2 is the default; for a large or high-risk substrate change add a third reviewer on a specific axis (e.g. concurrency/pool, or a perspective-diverse second spec reviewer). - -### 1c. Triage findings -Classify each: **patch** (fixable, caused by this change — include the fix) · **defer** (pre-existing or out-of-scope — note it) · **reject** (false positive / noise — drop silently). Cross-check every finding against `plan/backlog.jsonl` + `plan/antipatterns.jsonl`; a match to an accepted deferral → **reject** silently. - -Fix priority (most→least): 1) **spec alignment** (`spec/rules.jsonl` / the F-* floor — a rule wins over current impl) · 2) **semantic correctness** (protocol + node contract) · 3) **completeness** (edge cases) · 4) **consistency** (patterns already in `packages/ts/src/`) · 5) **level of effort**. (Frozen `packages/pure-ts/**` + `~/src/callbag-recharge` are read-only precedent only — the clean-slate spec wins on any conflict.) - -### 1d. Present findings (HALT) -Present ALL patch + defer findings (treat equally). For each: the issue + location, the **recommended fix** (pros/cons), whether it affects architecture, and whether it needs a user decision or can be auto-applied. Group: -1. **Needs Decision** — architecture-affecting or ambiguous (route per the floor: architectural lock → `/design-review` → D#; wave-protocol behavior change → `/spec-amend`; an open question with no clear answer → `plan/backlog.jsonl` B#). -2. **Auto-applicable** — clear fixes following existing patterns. +### 1b. Review, triage and repair -**Wait for user decisions on group 1.** Group 2 may be applied on the user's batch approval. Do NOT silently pick on a needs-decision item (no-autonomous-decisions). +Apply the shared BMAD QA reference once, using the original acceptance, governing R-id / D# and this +diff. Use its blind-hunter, edge-case and verification-gap lenses, then classify validated findings as +`intent_gap`, `bad_spec`, `patch`, `defer`, or `reject`. Preserve spec-first and owner-first boundaries: +a `bad_spec` finding never authorizes changing protocol, semantics or a locked design. Collect material +questions for the user; apply clear in-scope fixes when authorized. Trace protocol behavior and lifecycle +against conformance and the formal model where relevant. Reuse the final checks below in that repair loop. --- @@ -78,7 +63,8 @@ Apply the approved fixes. Cite the governing R-id / D# in any new test expectati --- ## Phase 3: Final Checks -Run all checks for the affected package(s) and fix failures (do NOT skip/ignore): +Select checks for the changed surfaces and complete any required phase/release gates. Reuse passing +results for unchanged code and environment; rerun affected checks after fixes. Available commands: **TypeScript (`@graphrefly/ts`):** 1. `pnpm --filter @graphrefly/ts test` (vitest) — all pass. diff --git a/.agents/skills/research/SKILL.md b/.agents/skills/research/SKILL.md index 7f925d0e7..45e08bf18 100644 --- a/.agents/skills/research/SKILL.md +++ b/.agents/skills/research/SKILL.md @@ -1,6 +1,6 @@ --- name: research -description: "Research a topic triggered by curiosity or a post the user saw. Uses web search to analyze latest trends, competitor landscape, user patterns, future demands, and how findings relate to GraphReFly's roadmap and gaps. Triggers: 'research', 'look into', 'what's the landscape for', 'I saw this post about', 'trend check', 'competitor analysis'." +description: "Research a requested GraphReFly topic or competitive question using current sources and relevant project authority." --- You are executing the **research** workflow for **GraphReFly**. @@ -27,7 +27,8 @@ State the extracted topic, trigger, and angle before proceeding. ## Phase 1: Landscape research -Use `mcp__searxng__searxng_web_search` (preferred) or `WebSearch` to gather intel. Run **at least 4-6 searches** covering different angles. Suggested search patterns (adapt to topic): +Use `mcp__searxng__searxng_web_search` (preferred) or `WebSearch` to gather intel. Search the angles needed to answer the request. Stop when the material claims and recommendation +have adequate evidence; expand only for unresolved uncertainty. Suggested search patterns (adapt to topic): 1. **Trend pulse** — `"{topic}" trends 2025 2026` or `"{topic}" state of` 2. **User pain points** — `"{topic}" problems OR frustrations OR "wish it could"` or reddit/HN discussions @@ -36,7 +37,7 @@ Use `mcp__searxng__searxng_web_search` (preferred) or `WebSearch` to gather inte 5. **Developer adoption** — `"{topic}" adoption OR migration OR "switched to"` 6. **Academic/deep** — `"{topic}" research OR paper OR architecture` (if relevant) -For each search, read 2-3 promising results using `mcp__searxng__web_url_read` or `WebFetch` to get substance beyond snippets. +Read the sources needed to substantiate material claims using `mcp__searxng__web_url_read` or `WebFetch` to get substance beyond snippets. --- @@ -62,7 +63,7 @@ actually implement. ## Phase 3: Structured analysis -Produce a report with these sections. Be **honest and specific** — don't flatter GraphReFly where it doesn't deserve it. +Select the sections that answer the request; a narrow question does not require a landscape report. Be **honest and specific** — don't flatter GraphReFly where it doesn't deserve it. ### 3.1 Trend summary @@ -87,7 +88,7 @@ Build a comparison table: |---|---|---|---|---| | {name} | {1-line approach} | {2-3 points} | {2-3 points} | {GitHub stars, npm downloads, community size, or "unknown"} | -Include 3-6 competitors. For each, note the most interesting design decision they made. +Include only competitors relevant to the requested comparison and explain their material differences. ### 3.4 GraphReFly positioning @@ -132,7 +133,7 @@ over Y". Ask before changing canonical records. ### 4.2 Discussion prompts -Surface **2-3 open questions** that the research raised but can't answer alone — things that depend on the user's judgment, taste, or strategic priorities. Frame these as genuine questions to spark discussion, not rhetorical ones. Examples: +Surface unresolved material questions, if any, that the research raised but can't answer alone — things that depend on the user's judgment, taste, or strategic priorities. Frame these as genuine questions to spark discussion, not rhetorical ones. Examples: - "Competitor X chose to do Y — do we think that's the right trade-off for our users, or does our reactive-first approach make Y unnecessary?" - "There's emerging demand for Z, but it would pull us toward {direction}. Is that a direction we want to go?" @@ -150,4 +151,4 @@ The goal is to leave the user with something to react to, not just a wall of inf - **Keep it scannable.** Use tables, bullets, and headers. Avoid walls of prose. - **Don't implement.** This skill produces a research report. It does NOT modify code. It MAY suggest phase or backlog changes, but must ask before editing canonical records. -- **Invite discussion.** End on the open questions, not the recommendations. The user should feel pulled to respond, not just informed. +- Ask a follow-up only when a user decision is needed; otherwise end with the supported recommendation. diff --git a/.agents/skills/spec-amend/SKILL.md b/.agents/skills/spec-amend/SKILL.md index fa367854e..78c47b349 100644 --- a/.agents/skills/spec-amend/SKILL.md +++ b/.agents/skills/spec-amend/SKILL.md @@ -28,14 +28,10 @@ Protocol behavior is **spec-first**. No "implementation defines what happens." O ## Code-intelligence routing -Before estimating or implementing each runtime delta, call `codegraph_explore` in every indexed affected -implementation repo before raw source Read/`rg`. Query the changed rule's protocol symbols and journey -endpoints for exact source, call paths, callers/dependents, existing conformance/property tests, public -boundaries, and blast radius. Treat returned source as already read and query again only for uncovered paths. -Read rules/conformance jsonl, decisions, TLA+, configs, git diff, untracked files, and stale/unindexed files -directly. If an index is absent or disabled, use direct inspection and never initialize it autonomously. -Codegraph scopes the implementation work; the amended spec, TLC, scenarios, compiler, and runtime gates decide -correctness. +Use a current Codegraph index when it helps trace the affected symbols; use direct file reads or +`rg` for simpler lookups, unavailable tools, or stale/unindexed files. Reuse source already read. +Do not initialize an index merely to satisfy this workflow. Validate through the affected executable +checks and required gates; an index is context, not correctness evidence. ## Output diff --git a/.claude/skills/bmad-build/SKILL.md b/.claude/skills/bmad-build/SKILL.md new file mode 100644 index 000000000..df893a9ad --- /dev/null +++ b/.claude/skills/bmad-build/SKILL.md @@ -0,0 +1,8 @@ +--- +name: bmad-build +description: "Implement a bounded repository change with the shared BMAD build workflow and local gates." +--- + +Read and follow `~/.codex/skills/bmad-build/SKILL.md` with this repository as the project root. +This entrypoint intentionally uses the shared personal workflow directly; do not run the legacy +BMAD renderer or adjacent workflow snapshots. Preserve this repository's authority and local gates. diff --git a/.claude/skills/bmad-checkpoint-preview/SKILL.md b/.claude/skills/bmad-checkpoint-preview/SKILL.md new file mode 100644 index 000000000..8d13941ea --- /dev/null +++ b/.claude/skills/bmad-checkpoint-preview/SKILL.md @@ -0,0 +1,8 @@ +--- +name: bmad-checkpoint-preview +description: "Guide human review of a change with orientation, concern walkthrough, risk details, and observation." +--- + +Read and follow `~/.codex/skills/bmad-checkpoint-preview/SKILL.md` with this repository as the project root. +This entrypoint intentionally uses the shared personal workflow directly; do not run the legacy +BMAD renderer or adjacent workflow snapshots. Preserve this repository's authority and local gates. diff --git a/.claude/skills/bmad-qa/SKILL.md b/.claude/skills/bmad-qa/SKILL.md new file mode 100644 index 000000000..d0366344b --- /dev/null +++ b/.claude/skills/bmad-qa/SKILL.md @@ -0,0 +1,8 @@ +--- +name: bmad-qa +description: "Review changes with the shared BMAD QA process and local domain gates; fix only when requested." +--- + +Read and follow `~/.codex/skills/bmad-qa/SKILL.md` with this repository as the project root. +This entrypoint intentionally uses the shared personal workflow directly; do not run the legacy +BMAD renderer or adjacent workflow snapshots. Preserve this repository's authority and local gates. diff --git a/.claude/skills/design-review/SKILL.md b/.claude/skills/design-review/SKILL.md index 5a783b325..ca5f7f54d 100644 --- a/.claude/skills/design-review/SKILL.md +++ b/.claude/skills/design-review/SKILL.md @@ -1,6 +1,6 @@ --- name: design-review -description: "Validate the design of a new primitive or API surface against the 5-question lens (Q5–Q9 from the per-unit review format). Use BEFORE coding (or right after a sketch lands) when adding a new public API / pattern factory / domain primitive. Triggers: 'design review', 'review the design', 'is this the right shape', 'before I implement'. Different from /qa — that finds bugs in landed code; this validates abstraction + long-term shape + reactive composability + alternatives." +description: "Review a proposed public API, primitive, or architectural change against project constraints and resolve material design choices." disable-model-invocation: true argument-hint: "[ | | --diff] [optional context]" --- diff --git a/.claude/skills/dev-dispatch/SKILL.md b/.claude/skills/dev-dispatch/SKILL.md index 4288cccfe..66c5dc6e3 100644 --- a/.claude/skills/dev-dispatch/SKILL.md +++ b/.claude/skills/dev-dispatch/SKILL.md @@ -1,6 +1,6 @@ --- name: dev-dispatch -description: "Implement feature/fix with planning and self-test. Use when user says 'dispatch', 'dev-dispatch', or provides a task with implementation context. Supports --light flag for bug fixes and small changes. Run /qa afterward for code review and final checks." +description: "Implement the requested feature or fix within project authority and verify affected behavior." argument-hint: "[--light] [task description or context]" --- @@ -13,13 +13,15 @@ This repo is **`@graphrefly/ts`** — the self-contained TypeScript implementati The user's task/context is: $ARGUMENTS ### Mode detection -If `$ARGUMENTS` contains `--light`, this is **light mode**. Otherwise **full mode**. Differences are noted inline per phase. +Use a focused workflow for routine fixes and a fuller plan for substantial changes. `--light` remains +supported. Neither mode requires another approval for work already authorized by the user; pause +for unresolved semantic/architectural decisions or an action outside the approved scope. ### Workflow floor (non-negotiable) -- **decision-first**: any architectural lock needs a `D#` in `~/src/graphrefly/decisions/decisions.jsonl` BEFORE code (`/design-review` → user approval → append). Decisions locked ≠ implementation approved — wait for an explicit "implement". +- **decision-first**: any architectural lock needs a `D#` in `~/src/graphrefly/decisions/decisions.jsonl` BEFORE code (`/design-review` → user approval → append). A design lock alone is not implementation approval; the current implementation request can supply that approval. - **spec-first** (F-NO-IMPL-DEFINED): any wave-protocol behavior change amends `spec/rules.jsonl` + `formal/*.tla` + `spec/conformance.jsonl` FIRST (`/spec-amend`), THEN code. Operators/sugar/inspection are per-language (D6/D24) — NOT spec, skip spec-amend. -- **no autonomous decisions**: surface spec↔code conflicts; don't silently pick. File-by-file review for multi-file rewrites. -- **verify premise**: design tables lag code — grep the named symbols + check landed markers (`plan/phases.jsonl` status/notes) before designing new surface; a stale premise is a HALT. +- **no autonomous decisions**: surface spec↔code conflicts; don't silently pick. Review affected boundaries for multi-file rewrites. +- **verify premise**: design tables lag code — grep the named symbols + check landed markers (`plan/phases.jsonl` status/notes) before designing new surface; correct stale premises from current evidence; ask only if the correction changes scope or a locked decision. - **consistency gate**: after touching any `~/src/graphrefly` jsonl, run `node ~/src/graphrefly/dashboard/build.mjs --check` (non-zero on broken links / orphans). --- @@ -28,7 +30,8 @@ If `$ARGUMENTS` contains `--light`, this is **light mode**. Otherwise **full mod Load context and plan in a single pass. **Parallelize all reads.** -Read in parallel (clean-slate authority): +Context index: read only the governing records and relevant implementation/tests below, reusing +material already loaded. Protocol/formal context is needed only when the changed behavior depends on it: - `~/src/graphrefly/CLAUDE.md` — the single-source authority index (read FIRST). - `~/src/graphrefly/spec/rules.jsonl` — the protocol 宪法 (R-* rules); deep-read the rules your change touches. - `~/src/graphrefly/decisions/decisions.jsonl` — the unified D# log (or invoke `/decision-guard` to recall the governing D#/values/floor). @@ -46,9 +49,9 @@ Read in parallel (clean-slate authority): While planning, validate proposed changes against the clean-slate floor (cite the rule/D#): - **Sacred (L0.7):** topology declarative/serializable/inspectable · wave protocol is a public spec · wave protocol impl is **sync** · all fn go through the dispatcher. - **8 verbs, closed (D4):** `node`/`graph`/`batch`/`state` + `producer`/`derived`/`effect`/`mount`. **Operators are `node` sugar (D6), not verbs** — per-language, never in parity (D24); real factory names show in `describe`. Adding a verb is a constitutional change. -- **Messages** `[[Type, Data?], ...]`; one array to `ctx.down`/`ctx.up` = one wave (R-msg-format). 10-type closed set, no user-defined types (R-msg-closed-set). +- **Messages** `[[Type, Data?], ...]`; one array to `ctx.down`/`ctx.up` = one wave (R-msg-format). The closed message set is defined by R-msg-closed-set; do not duplicate its count here. - **DIRTY before DATA/RESOLVED** in the same wave (R-dirty-before-data); two-phase glitch-free diamond (R-two-phase); a diamond/fan-in node recomputes exactly once after all changed deps settle (R-diamond). batch defers tier-≥3, not DIRTY. -- **`ctx.up` is control-tier only** (DIRTY/PAUSE/RESUME/INVALIDATE/TEARDOWN); DATA/RESOLVED/COMPLETE/ERROR are down-only (R-ctx-up, D8). A handle is pure data, no methods (D7). +- **`ctx.up`**: read the current control/demand boundary in R-ctx-up before changing its behavior. A handle is pure data, no methods (D7). - **No polling** (R-no-polling); **no imperative triggers** (R-no-imperative — reactive `ctx.up`/signals, not emitters/callbacks/timers+set; remove imperative paths when no caller depends); **no raw async** in the sync core (R-no-raw-async / F-SYNC-CORE — async lives only in sources / the pool / the wire bridge). - **All fn through the dispatcher** (R-dispatch-all / F-DISPATCH-ALL — no inline-fn bypass). `dispatcher.invoke` is sync void (R-sync-core). - **Data moves via messages** (R-data-not-peek — never peek a dep's `.cache` to seed compute; `.cache` is a read-only accessor for external consumers). SENTINEL = absence-of-DATA (R-sentinel); the canonical never-emitted detector is `ctx.prevData[i] === undefined`. @@ -60,56 +63,24 @@ While planning, validate proposed changes against the clean-slate floor (cite th **Targeting a sibling (py/rust):** if the task targets `@graphrefly/py` (`~/src/graphrefly-py`) or `@graphrefly/rust` (`~/src/graphrefly-rs`), read that package's local layout + its conformance arm status in `spec/conformance.jsonl`. The cross-language contract is **behavioral conformance (D24)**, not symbol parity. PY public APIs are synchronous (return `Node[T]`/`Graph`/value, no `async def`); async lives at the source/pool boundary only (F-SYNC-CORE). -Do NOT start implementing yet. --- -## Phase 2: Architecture Discussion +## Phase 2: Resolve material decisions -### Full mode — HALT - -**HALT and report before implementing.** Present: - -1. **Architecture assumptions** — how this fits the substrate (`node`/`dispatcher`/`ctx`/`protocol`/`batch`) vs graph-layer (`graph/`) split. -2. **New patterns** — any not yet in `packages/ts/src/`. -3. **Options considered** — alternatives with pros/cons. -4. **Recommendation** — preferred approach + why. - -Prioritize (in order): -1. **Correctness** — matches `~/src/graphrefly/spec/rules.jsonl` + the floor. -2. **Completeness** — edge cases (errors, COMPLETE, reconnect/reactivate, diamonds, SENTINEL gate, PAUSE lockset). -3. **Consistency** — matches patterns already in `packages/ts/src/`. -4. **Simplicity** — minimal solution. - -No backward compatibility (pre-1.0). - -**Escalation routing** (don't silently pick — no-autonomous-decisions): -- Architectural lock → `/design-review` → user approval → append a `D#` to `decisions.jsonl`. -- Wave-protocol behavior change → `/spec-amend` (spec-first: rules + TLA+ + conformance, THEN code). -- Cross-runtime concern → `/conformance` (behavioral scenario, not structural diff). -- Deferred/open question with no answer yet → append to `~/src/graphrefly/plan/backlog.jsonl` (B# + trigger); a recurring anti-pattern → `plan/antipatterns.jsonl` (+ a `feedback_*` memory if generalizable). - -**Wait for user approval before proceeding.** - -### Light mode — Skip unless escalation needed - -Proceed directly to Phase 3 **unless** Phase 1 reveals any of these: -- A change to **wave-protocol behavior** (tiers, wave semantics, diamond/equals/SENTINEL, batch, push-on-subscribe, ctx.up/down contract) → spec-first, escalate. -- A new architectural lock with no governing `D#`. -- Multiple viable approaches with non-obvious trade-offs. - -If any apply: HALT and present findings as in full mode. - ---- +Proceed with authorized implementation when existing decisions govern the behavior. Explain material +assumptions and tradeoffs briefly. Ask only when an unresolved choice changes product semantics, +public contract, architecture, or authorization. Preserve spec-first amendments and owner-ledger +approval for new locks; a locked design alone does not authorize implementation when the user deferred it. ## Phase 3: Implementation & Self-Test -After user approves (full mode) or after Phase 1 (light mode, no escalation): +Once implementation is authorized and material decisions are resolved: 1. Implement the changes. - Treat `~/src/graphrefly/spec/rules.jsonl` as non-negotiable for behavior; if code drifts from a rule, align to the rule — or surface the conflict, don't silently pick. - Cite the governing R-id / D# in test expectations. -2. Create tests (per `guide/guide.jsonl` G-test — unit / property / conformance layering): +2. Add meaningful behavior tests where needed (per `guide/guide.jsonl` G-test — unit / property / conformance layering): - Put tests in the most specific existing file under `packages/ts/src/__tests__/`. - Use `graph.observe()` for live message assertions; assert at the node + message level otherwise. A behavioral-protocol change ALSO needs a `spec/conformance.jsonl` scenario (`/conformance`) before its rule flips `draft → active`. 3. Run checks: diff --git a/.claude/skills/qa/SKILL.md b/.claude/skills/qa/SKILL.md index b5c404542..30ae38adf 100644 --- a/.claude/skills/qa/SKILL.md +++ b/.claude/skills/qa/SKILL.md @@ -1,9 +1,15 @@ --- name: qa -description: "Adversarial code review, apply fixes, final checks (test/lint/build), and doc updates. Run after /dev-dispatch or any manual implementation. Use when user says 'qa', 'review', or 'code review'. Supports --skip-docs to skip documentation phase." +description: "Review project changes and verify affected behavior or required phase gates. Apply fixes only within an implementation or QA-and-fix request." argument-hint: "[--skip-docs] [optional context about what was implemented]" --- +Read `~/.codex/skills/bmad-build/references/qa.md` for the shared review lenses, five-way triage and +repair loop. Integrate the domain checks below into that one review; retain this repository's canonical +completion verdict. Review-only remains read-only, including documentation and authority records. +Finish with `~/.codex/skills/bmad-checkpoint-preview/SKILL.md` in build-handoff mode unless interactive +review was requested. + You are executing the **qa** workflow for the **clean-slate GraphReFly** redesign. This repo is **`@graphrefly/ts`** — the self-contained TypeScript implementation (D32); clean-slate code lives in **`packages/ts/src/`**. Siblings (each self-contained, cross-language = wire bridge, never in-process): `@graphrefly/rust` (`~/src/graphrefly-rs`), `@graphrefly/py` (`~/src/graphrefly-py`). The language-neutral authority (spec / decisions / plan / conformance / formal) lives in **`~/src/graphrefly`** (branch `clean-slate`) as jsonl — when this skill and that repo disagree, that repo wins (CLAUDE.md). @@ -26,42 +32,21 @@ Inspect the diff to detect which package(s) are touched: `packages/ts/` (this re Run `git diff` for uncommitted changes; if the chat's work was already committed, diff against the chat's baseline commit (`git log --oneline` to find it, then `git diff ..HEAD`). Include relevant untracked files (read them). Concentrate the review on the **substantive hand-written code** — formally-verified TLA+ (already TLC-checked), generated artifacts, and jsonl data are lower bug-risk than imperative substrate/graph code. -Also load the clean-slate context the review must NOT contradict: +Read the governing entries from the following index when relevant to the changed behavior: - `~/src/graphrefly/spec/rules.jsonl` — the protocol 宪法 (R-* rules); the behavior authority. Cite R-ids in findings. - `~/src/graphrefly/decisions/decisions.jsonl` — the governing D# (or `/decision-guard`); the F-* floor + durable values. - `~/src/graphrefly/plan/backlog.jsonl` + `plan/antipatterns.jsonl` — **already-acknowledged deferred concerns (B#) and known anti-patterns. DO NOT raise a finding that matches an existing deferred B# or antipattern** — those are accepted. DO raise a finding that *contradicts* a deferred entry's stated scope. - `~/src/graphrefly/spec/conformance.jsonl` — the C-* scenarios the change must keep green (+ their `runtimes` status). - `~/src/graphrefly/formal/*.tla` — when the change implements a formally-modeled rule, cross-check the impl against the TLC-verified model. -### 1b. Launch parallel review subagents - -Launch as parallel Agent calls. Each receives the diff + the context from $ARGUMENTS (what was implemented and why). Tell each to do a STATIC review (no servers, no test runs) and return ONLY a findings list. - -**Subagent 1: Blind Hunter** — pure code review, no project context: -> You are a Blind Hunter code reviewer. Review this diff for: logic errors, off-by-one, race/re-entrancy hazards, resource leaks (unclosed subscriptions, unbounded registries), stale-closure / index-desync bugs, missing error handling, dead/unreachable code, sparse-array holes, security issues. For Python, also check thread/free-threaded safety. Be adversarial — assume bugs exist; trace the suspicious paths concretely. If a suspicious path is actually correct, say so in one line rather than raising noise. Output each finding as: **title** | **severity** (critical/major/minor) | **location** (file:line) | **detail** (trigger + consequence + suggested fix). - -**Subagent 2: Edge Case Hunter** — clean-slate spec-aware: -> You are an Edge Case Hunter reviewing a change against the GraphReFly clean-slate SPEC. The authority is `~/src/graphrefly` jsonl (branch clean-slate) — NOT any docs/*.md or packages/pure-ts (retired port-model; ignore). Read the relevant `spec/rules.jsonl` R-* rules + `decisions/decisions.jsonl` D# for the area under review, and the matching `spec/conformance.jsonl` C-* + `formal/*.tla` model if the change implements a spec-locked behavior. -> -> Check protocol/wave invariants against the rules: message tuples `[[Type,Data?]]`, one array = one wave (R-msg-format); DIRTY-before-DATA in the same wave (R-dirty-before-data); two-phase glitch-free diamond, recompute-once (R-two-phase/R-diamond); ctx.up control-tier-only (R-ctx-up); SENTINEL = absence-of-DATA, never-emitted detector `prevData===undefined` (R-sentinel); equals DATA→RESOLVED only on a single-DATA wave (R-equals); first-run gate (R-first-run-gate); INVALIDATE idempotent + lifecycle-continue (R-invalidate-idempotent); terminal-is-forever / resubscribable reset (R-terminal); ROM/RAM cache (R-rom-ram); PAUSE lockset + modes (R-pause-lockset/R-pause-modes); reentrancy reject (R-reentrancy/D37). -> -> Flag floor violations: imperative side-channel triggers (R-no-imperative — emitters/callbacks/timers+set instead of ctx.up/message flow); polling/busy-wait (R-no-polling); bare async in the sync core (R-no-raw-async / F-SYNC-CORE — async only in sources / pool / wire bridge); inline-fn bypassing the dispatcher (R-dispatch-all / F-DISPATCH-ALL); peeking a dep `.cache` to seed compute (R-data-not-peek); hardcoded `type === "DATA"` instead of messageTier (R-tier); protocol internals (DIRTY/RESOLVED/bitmask) leaking into value-level sugar (R-primary-api-clean / DR-1); counters/inspection on the thin node (R-node-thin); a new verb (D4 closed set) or a 10th tier (D9) introduced casually; graph-level shared mutable state accessed implicitly instead of an explicit node+dep (D22/D23); cross-graph in-process coupling instead of a wire bridge (D22/D32). -> -> If the change implements a formally-modeled rule, identify any place the impl DIVERGES from the `formal/*.tla` model (cite the invariant). Surface real-but-unmodeled cross-axis interactions (e.g. X×batch, X×pause) and say whether each is a genuine gap or acceptably-deferred. DROP any finding that matches an already-acknowledged `plan/backlog.jsonl` B# or `plan/antipatterns.jsonl` entry. Output each finding as: **title** | **severity** | **location** (file:line or R-id) | **detail** (the rule/D# it relates to + what the impl does + divergence/gap/ok). - -Scale the reviewer count to the change: 2 is the default; for a large or high-risk substrate change add a third reviewer on a specific axis (e.g. concurrency/pool, or a perspective-diverse second spec reviewer). - -### 1c. Triage findings -Classify each: **patch** (fixable, caused by this change — include the fix) · **defer** (pre-existing or out-of-scope — note it) · **reject** (false positive / noise — drop silently). Cross-check every finding against `plan/backlog.jsonl` + `plan/antipatterns.jsonl`; a match to an accepted deferral → **reject** silently. - -Fix priority (most→least): 1) **spec alignment** (`spec/rules.jsonl` / the F-* floor — a rule wins over current impl) · 2) **semantic correctness** (protocol + node contract) · 3) **completeness** (edge cases) · 4) **consistency** (patterns already in `packages/ts/src/`) · 5) **level of effort**. (Frozen `packages/pure-ts/**` + `~/src/callbag-recharge` are read-only precedent only — the clean-slate spec wins on any conflict.) - -### 1d. Present findings (HALT) -Present ALL patch + defer findings (treat equally). For each: the issue + location, the **recommended fix** (pros/cons), whether it affects architecture, and whether it needs a user decision or can be auto-applied. Group: -1. **Needs Decision** — architecture-affecting or ambiguous (route per the floor: architectural lock → `/design-review` → D#; wave-protocol behavior change → `/spec-amend`; an open question with no clear answer → `plan/backlog.jsonl` B#). -2. **Auto-applicable** — clear fixes following existing patterns. +### 1b. Review, triage and repair -**Wait for user decisions on group 1.** Group 2 may be applied on the user's batch approval. Do NOT silently pick on a needs-decision item (no-autonomous-decisions). +Apply the shared BMAD QA reference once, using the original acceptance, governing R-id / D# and this +diff. Use its blind-hunter, edge-case and verification-gap lenses, then classify validated findings as +`intent_gap`, `bad_spec`, `patch`, `defer`, or `reject`. Preserve spec-first and owner-first boundaries: +a `bad_spec` finding never authorizes changing protocol, semantics or a locked design. Collect material +questions for the user; apply clear in-scope fixes when authorized. Trace protocol behavior and lifecycle +against conformance and the formal model where relevant. Reuse the final checks below in that repair loop. --- @@ -71,7 +56,8 @@ Apply the approved fixes. Cite the governing R-id / D# in any new test expectati --- ## Phase 3: Final Checks -Run all checks for the affected package(s) and fix failures (do NOT skip/ignore): +Select checks for the changed surfaces and complete any required phase/release gates. Reuse passing +results for unchanged code and environment; rerun affected checks after fixes. Available commands: **TypeScript (`@graphrefly/ts`):** 1. `pnpm --filter @graphrefly/ts test` (vitest) — all pass. diff --git a/.claude/skills/research/SKILL.md b/.claude/skills/research/SKILL.md index 2082bbef7..6ad9772ec 100644 --- a/.claude/skills/research/SKILL.md +++ b/.claude/skills/research/SKILL.md @@ -1,6 +1,6 @@ --- name: research -description: "Research a topic triggered by curiosity or a post the user saw. Uses web search to analyze latest trends, competitor landscape, user patterns, future demands, and how findings relate to GraphReFly's roadmap and gaps. Triggers: 'research', 'look into', 'what's the landscape for', 'I saw this post about', 'trend check', 'competitor analysis'." +description: "Research a requested GraphReFly topic or competitive question using current sources and relevant project authority." argument-hint: "" --- @@ -28,7 +28,8 @@ State the extracted topic, trigger, and angle before proceeding. ## Phase 1: Landscape research -Use `mcp__searxng__searxng_web_search` (preferred) or `WebSearch` to gather intel. Run **at least 4-6 searches** covering different angles. Suggested search patterns (adapt to topic): +Use `mcp__searxng__searxng_web_search` (preferred) or `WebSearch` to gather intel. Search the angles needed to answer the request. Stop when the material claims and recommendation +have adequate evidence; expand only for unresolved uncertainty. Suggested search patterns (adapt to topic): 1. **Trend pulse** — `"{topic}" trends 2025 2026` or `"{topic}" state of` 2. **User pain points** — `"{topic}" problems OR frustrations OR "wish it could"` or reddit/HN discussions @@ -37,7 +38,7 @@ Use `mcp__searxng__searxng_web_search` (preferred) or `WebSearch` to gather inte 5. **Developer adoption** — `"{topic}" adoption OR migration OR "switched to"` 6. **Academic/deep** — `"{topic}" research OR paper OR architecture` (if relevant) -For each search, read 2-3 promising results using `mcp__searxng__web_url_read` or `WebFetch` to get substance beyond snippets. +Read the sources needed to substantiate material claims using `mcp__searxng__web_url_read` or `WebFetch` to get substance beyond snippets. --- @@ -55,7 +56,7 @@ Read these files in parallel to ground findings: ## Phase 3: Structured analysis -Produce a report with these sections. Be **honest and specific** — don't flatter GraphReFly where it doesn't deserve it. +Select the sections that answer the request; a narrow question does not require a landscape report. Be **honest and specific** — don't flatter GraphReFly where it doesn't deserve it. ### 3.1 Trend summary @@ -80,7 +81,7 @@ Build a comparison table: |---|---|---|---|---| | {name} | {1-line approach} | {2-3 points} | {2-3 points} | {GitHub stars, npm downloads, community size, or "unknown"} | -Include 3-6 competitors. For each, note the most interesting design decision they made. +Include only competitors relevant to the requested comparison and explain their material differences. ### 3.4 GraphReFly positioning @@ -123,7 +124,7 @@ Recommendations should be actionable — not "think about X" but "add X to imple ### 4.2 Discussion prompts -Surface **2-3 open questions** that the research raised but can't answer alone — things that depend on the user's judgment, taste, or strategic priorities. Frame these as genuine questions to spark discussion, not rhetorical ones. Examples: +Surface unresolved material questions, if any, that the research raised but can't answer alone — things that depend on the user's judgment, taste, or strategic priorities. Frame these as genuine questions to spark discussion, not rhetorical ones. Examples: - "Competitor X chose to do Y — do we think that's the right trade-off for our users, or does our reactive-first approach make Y unnecessary?" - "There's emerging demand for Z, but it would pull us toward {direction}. Is that a direction we want to go?" @@ -140,4 +141,4 @@ The goal is to leave the user with something to react to, not just a wall of inf - **Date-stamp.** Note that this research reflects the landscape as of the current date. - **Keep it scannable.** Use tables, bullets, and headers. Avoid walls of prose. - **Don't implement.** This skill produces a research report. It does NOT modify code. It MAY suggest additions to `docs/optimizations.md` if gaps are identified — ask the user first. -- **Invite discussion.** End on the open questions, not the recommendations. The user should feel pulled to respond, not just informed. +- Ask a follow-up only when a user decision is needed; otherwise end with the supported recommendation. diff --git a/.gemini/skills/dev-dispatch/SKILL.md b/.gemini/skills/dev-dispatch/SKILL.md index 013f99f42..4e4afd1cf 100644 --- a/.gemini/skills/dev-dispatch/SKILL.md +++ b/.gemini/skills/dev-dispatch/SKILL.md @@ -1,160 +1,6 @@ --- name: dev-dispatch -description: "Implement a feature or fix for GraphReFly (TS + PY) with planning, spec alignment, and self-test. Use when user says 'dispatch', 'dev-dispatch', 'implement', or provides a task. ALWAYS halts for approval before implementing. Run /parity afterward for cross-language check." +description: "Route dev-dispatch requests to the current clean-slate workflow." --- -You are executing the **dev-dispatch** workflow for **GraphReFly** (cross-language: TypeScript + Python). Operational docs live in graphrefly-ts (this repo). Implementation may target graphrefly-ts, graphrefly-py (`~/src/graphrefly-py`), or both. - -The user's task/context is: $ARGUMENTS - ---- - -## CRITICAL RULES (read before every phase) - -1. **ALWAYS HALT after Phase 2.** Present your plan. Do NOT implement until the user approves. -2. **The spec is the authority.** `~/src/graphrefly/GRAPHREFLY-SPEC.md` decides behavior. Not your training data. Not the predecessor. The spec. -3. **Follow existing patterns.** Before writing new code, find the closest existing pattern in this repo and follow it. If you can't find one, say so in Phase 2. -4. **No async in public APIs.** TS: No `Promise` in public APIs. PY: No `async def` / `Awaitable` in public APIs. All public functions return `Node`, `Graph`, `void`/`None`, or a plain synchronous value. -5. **No raw time calls.** TS: No `Date.now()`/`performance.now()` — use `monotonicNs()`/`wallClockNs()` from `src/core/clock.ts`. PY: No `datetime.now()`/`time.time()` — use `monotonic_ns()`/`wall_clock_ns()` from `src/graphrefly/core/clock.py`. -6. **All durations and timestamps are nanoseconds.** Backoff strategies return `number` (ns). Use `NS_PER_MS` / `NS_PER_SEC` from `src/extra/backoff.ts` for conversions. Convert to ms only at `setTimeout`/`setInterval` call sites. -7. **Messages use tuple arrays.** TS: Messages are always `[[Type, Data?], ...]`. PY: Messages are always `list[tuple[Type, Any] | tuple[Type]]`. No single-tuple shorthand at API boundaries. -8. **Unknown message types forward.** Do not swallow unrecognized tuples. -9. **Thread safety is mandatory (PY).** All public PY APIs must be safe under concurrent access with per-subgraph RLock. -10. **No imperative polling or internal timers for composition.** Sources like `fromHTTP` must be one-shot reactive. If users need periodic behavior, they compose with `interval()`/`fromTimer()` externally. Only time-domain primitives (`fromTimer`, `interval`, `debounce`, `throttle`, `delay`, `timeout`, `bufferTime`, `windowTime`) and resilience retry/rate-limiting may use raw `setTimeout`/`setInterval`. -11. **No imperative triggers in public APIs.** Use reactive `NodeInput` signals instead of imperative `.trigger()` or `.set()` methods where possible. -12. **Run tests before reporting done.** TS: `pnpm test` must pass. PY: `cd ~/src/graphrefly-py && uv run pytest` must pass. - ---- - -## Phase 1: Context & Planning - -Read these files to understand the task. **Parallelize all reads.** - -**Always read:** -- `~/src/graphrefly/GRAPHREFLY-SPEC.md` — deep-read sections relevant to the task -- `docs/roadmap.md` — find the roadmap item for this task (lives in this repo, graphrefly-ts) -- `docs/test-guidance.md` — testing checklist for the relevant layer (lives in this repo, graphrefly-ts) - -**Read if relevant:** -- `docs/optimizations.md` — if touching protocol, batch, node lifecycle, or parity -- `docs/demo-and-test-strategy.md` — if this is a demo-related or domain-layer task -- Existing source files in the area you'll modify -- Existing tests for the area -- The closest existing pattern (e.g., `src/patterns/orchestration.ts` for domain factories) -- If the feature is PY-targeted, check the TS implementation at `src/` in this repo for reference - -**Optional predecessor reference:** -- `~/src/callbag-recharge` — use for analogous operator behavior, edge cases, test ideas. Map to GraphReFly APIs. The spec wins on conflicts. - -After reading, proceed to Phase 2. Do NOT start implementing. - ---- - -## Phase 2: Architecture Discussion (HALT) - -**STOP and present your plan to the user.** Include: - -### 2a. What you understand the task to be -Restate the task in your own words. If anything is unclear, ask here. - -### 2b. Files you will create or modify -List every file path. For new files, state where they go and why. - -### 2c. The pattern you are following -Name the existing file whose structure you will mirror. Show how your new code maps to it. If no existing pattern fits, explain why and propose a structure. - -Example: "Following `src/patterns/orchestration.ts` — `pipeline()` creates a Graph and adds nodes via `registerStep()`. My `topic()` will do the same: create a Graph, add internal nodes (`state("buffer")`, `derived("messages")`), return a bundle." - -### 2d. Public API you will create -Show exact function signatures with types: -```typescript -function topic(name: string, opts?: TopicOptions): TopicBundle -``` - -### 2e. Internal graph topology (for domain factories) -If building a factory that returns a Graph, draw the internal node topology: -``` -Graph("topic/{name}") -├── state("buffer") — reactiveLog internal -├── derived("messages") — logSlice(buffer, -retention) -└── ... -``` - -### 2f. Tests you will write -List the test file and test names: -``` -src/__tests__/patterns/messaging.test.ts -- "publishes and subscribes" -- "late subscriber starts at current position" -- "retention: oldest messages evict" -- "TEARDOWN cascades to subscribers" -``` - -### 2g. Spec conformance check -For each invariant below, state whether your design complies and how: -- [ ] Messages are `[[Type, Data?], ...]` -- [ ] DIRTY before DATA/RESOLVED in two-phase push -- [ ] Unknown types forward -- [ ] No Promise in return types -- [ ] Diamond resolution: recompute once after all deps settle -- [ ] Error handling: fn throws → `[[ERROR, err]]` downstream - -### 2h. What you are NOT doing -Explicitly state what's out of scope. This prevents scope creep. - -**WAIT for user approval. Do NOT proceed to Phase 3 until approved.** - ---- - -## Phase 3: Implementation - -After user approves: - -1. **Implement the code** following your approved plan from Phase 2 -2. **Create tests** following `docs/test-guidance.md`: - - Put tests in the most specific existing file, or create a new file as stated in Phase 2 - - Use `graph.observe()` for message assertions where applicable - - Assert both behavior AND topology (`describe()` output) -3. **Export the new public API:** - - Add to the appropriate barrel export (`src/patterns/index.ts`, `src/extra/index.ts`, etc.) - - Add to the package root export if user-facing -4. **Run tests:** TS: `pnpm test`. PY: `cd ~/src/graphrefly-py && uv run pytest && uv run mypy src/graphrefly/`. -5. **Fix any failures** - ---- - -## Phase 4: Self-Verification - -Before reporting done, verify: - -- [ ] Tests pass — TS: `pnpm test`. PY: `cd ~/src/graphrefly-py && uv run pytest && uv run mypy src/graphrefly/` -- [ ] Your code follows the pattern you stated in Phase 2c -- [ ] Your public API matches the signatures you stated in Phase 2d -- [ ] Your tests cover the scenarios you listed in Phase 2f -- [ ] No async in public return types — TS: no `Promise`. PY: no `async def` / `Awaitable` -- [ ] No raw time calls — TS: no `Date.now()`/`performance.now()`. PY: no `datetime.now()`/`time.time()` -- [ ] All durations/timestamps use nanoseconds; ms only at setTimeout call sites -- [ ] No internal polling loops — sources are one-shot reactive, compose with interval() for periodic -- [ ] Messages use correct format — TS: `[[Type, Data?], ...]`. PY: `list[tuple[Type, Any] | tuple[Type]]` - -Report: -- Files created/modified -- New public exports -- Test results (pass count) -- Suggest running `/parity` to check Python alignment - ---- - -## GUARDRAILS FOR FLASH-CLASS MODELS - -These rules prevent common drift patterns. Re-read if unsure: - -- **DO NOT add features beyond what was asked.** If the task says "implement `topic()`", implement `topic()`. Do not also implement `topicBridge()` unless asked. -- **DO NOT add docstrings, comments, or type annotations to code you didn't change.** Only comment where logic isn't self-evident. -- **DO NOT add error handling for impossible scenarios.** Trust internal code. Only validate at system boundaries (user input, external APIs). -- **DO NOT create helpers or abstractions for one-time operations.** Three similar lines are better than a premature abstraction. -- **DO NOT add backward-compat shims.** This is pre-1.0. Free to break APIs. -- **DO follow the file layout in the target repo's GEMINI.md/CLAUDE.md.** Core goes in `src/core/`, graph in `src/graph/`, operators in `src/extra/`, domain factories in `src/patterns/`. -- **DO use existing utilities.** Check `src/core/` and `src/extra/` for helpers before writing new ones. -- **DO check the sibling repo.** If implementing in PY, check the TS at `src/` in this repo. If implementing in TS, check PY at `~/src/graphrefly-py/src/graphrefly/`. -- **DO check the predecessor.** `~/src/callbag-recharge` often has the edge cases you'll miss. But reconcile with the spec — it wins. +For implementation, read `../../../AGENTS.md`, then `../../../.agents/skills/dev-dispatch/SKILL.md`. diff --git a/.gemini/skills/parity/SKILL.md b/.gemini/skills/parity/SKILL.md index 8433e4488..51e4dd42e 100644 --- a/.gemini/skills/parity/SKILL.md +++ b/.gemini/skills/parity/SKILL.md @@ -1,179 +1,7 @@ --- name: parity -description: "Cross-language parity check between graphrefly-ts and graphrefly-py. Compares API surface, behavior, tests, and spec conformance. READ-ONLY — reports findings, never applies fixes without explicit approval. Use when user says 'parity', 'cross-lang check', or 'sync repos'." +description: "Route parity requests to the current clean-slate workflow." --- -You are executing the **parity** workflow, comparing **graphrefly-ts** and **graphrefly-py**. All operational docs (roadmap, optimizations, test-guidance) live in graphrefly-ts (this repo). - -User's context: $ARGUMENTS - ---- - -## CRITICAL RULES (read before every phase) - -1. **READ-ONLY until Phase 5.** You are comparing, not fixing. Do NOT edit any file until the user explicitly approves fixes in Phase 5. -2. **Spec is the authority.** `~/src/graphrefly/GRAPHREFLY-SPEC.md` decides what is correct. Not the TS code. Not the Python code. The spec. -3. **Report everything you find.** Do not filter, summarize, or skip "minor" differences. Present all findings and let the user decide. -4. **Stay in scope.** If the user specifies a feature area (e.g. "4.1 orchestration"), only check that area. If they say "full", check all implemented phases. -5. **No architectural decisions.** If you find a gap where neither the spec nor `docs/optimizations.md` has a clear answer, report it as "needs decision" — do NOT pick a resolution yourself. - ---- - -## Phase 1: Scope & Gather - -Determine scope from the user's input: -- If a **feature area** is given (e.g. "4.2 messaging", "guard", "batch"), focus only on that area. -- If `full`, check all phases that are checked off in BOTH roadmaps. - -Read these files (parallelize all reads): - -> **Note:** Operational docs (roadmap, optimizations, cross-language notes) all live in this repo (graphrefly-ts). Do NOT read from `~/src/graphrefly-py/docs/`. - -**From graphrefly-ts (this repo):** -- `docs/roadmap.md` — which phases are complete -- `docs/optimizations.md` — cross-language notes and open decisions -- Source files in the scoped area under `src/` -- Test files in the scoped area under `src/__tests__/` - -**From graphrefly-py:** -- Source files in the scoped area under `~/src/graphrefly-py/src/graphrefly/` -- Test files in the scoped area under `~/src/graphrefly-py/tests/` - -**Spec:** -- `~/src/graphrefly/GRAPHREFLY-SPEC.md` — sections relevant to the scoped area - -After reading, list what you scoped and what files you read. Then proceed to Phase 2. - ---- - -## Phase 2: API Surface Comparison - -For the scoped area, compare the **public API** between TS and Python. Check each of these dimensions: - -| Dimension | What to compare | -|-----------|----------------| -| **Function/method names** | TS `camelCase` vs Python `snake_case` — names should be equivalent after case conversion | -| **Signatures** | Parameters, their types, optionality, defaults | -| **Return types** | Node vs Node[T], Graph vs Graph, void vs None | -| **Options/kwargs** | Same option names (case-converted), same defaults, same validation | -| **Error behavior** | Same error types thrown/raised, same conditions | -| **Exports** | Every public export in TS has a Python counterpart and vice versa | - -Present findings as a table: - -``` -| Aspect | TypeScript | Python | Verdict | -|--------|-----------|--------|---------| -| topic() signature | topic(name, opts?) | topic(name, opts=None) | ALIGNED | -| jobQueue retry default | 3 | 5 | GAP — TS value is spec-correct | -| fromLLM() | exists | missing | GAP — Py behind | -``` - -Use these verdicts: -- **ALIGNED** — equivalent behavior -- **GAP** — unintentional difference (one side wrong or behind) -- **INTENTIONAL** — language-idiomatic difference (e.g. Python `|` operator, `with batch():` context manager) - ---- - -## Phase 3: Behavioral Semantics Check - -For each **GAP** found in Phase 2, dig deeper: - -1. Read the **implementation** on both sides -2. Read the **tests** on both sides -3. Check what the **spec** says (`~/src/graphrefly/GRAPHREFLY-SPEC.md`) -4. Check `docs/optimizations.md` for prior cross-language decisions - -Classify each gap: -- **spec-decided** — spec clearly defines the behavior; one side is wrong. State which side and cite the spec section. -- **convention-decided** — `optimizations.md` already aligned this. State the convention. -- **needs-decision** — neither spec nor conventions cover this. Do NOT guess — flag it. - ---- - -## Phase 4: Test Coverage Comparison - -For the scoped area, compare test coverage: - -1. List test files and test names on both sides -2. Identify scenarios tested in TS but NOT in Python (and vice versa) -3. For each missing test, classify: - - **port** — the test should exist on both sides (same behavior, same edge case) - - **language-specific** — test only makes sense on one side (e.g. Python thread-safety, TS async scheduling) - -Present as a table: - -``` -| Test scenario | TS file:test | Python file:test | Verdict | -|--------------|-------------|-----------------|---------| -| 10 rapid orders no loss | orchestration.test.ts:AC-1 | (missing) | PORT to Python | -| thread-safe batch drain | (N/A) | test_concurrency.py:test_batch | LANGUAGE-SPECIFIC | -``` - ---- - -## Phase 5: Report (HALT) - -Present ALL findings from Phases 2-4, grouped: - -### Group 1: Gaps — one side needs a fix -For each: the gap, which repo needs the fix, what the fix is, effort estimate (S/M/L). - -### Group 2: Test coverage gaps -For each: missing test, which repo, what the test should assert. - -### Group 3: Needs Decision -For each: the gap, both behaviors, why the spec doesn't cover it, your recommended resolution (but the user decides). - -### Group 4: Intentional Divergences (FYI only) -Language-specific differences that are correct on both sides. - -**STOP HERE. Wait for the user to review and approve before proceeding.** - ---- - -## Phase 6: Apply Fixes (only after user approval) - -After the user approves specific fixes: - -1. Apply fixes to the repo the user specifies -2. Run tests: - - **This repo (TS):** `pnpm test` - - **Sibling repo (Python):** `cd ~/src/graphrefly-py && uv run pytest` -3. If any test fails, fix it. If a failure reveals a design question, HALT and ask. -4. Update `docs/optimizations.md` in BOTH repos: - - Remove resolved gaps - - Add any new decisions - ---- - -## Phase 7: Final Verification - -Run all checks and report results: - -**TypeScript:** -```bash -pnpm test && pnpm run lint:fix && pnpm run build -``` - -**Python:** -```bash -cd ~/src/graphrefly-py && uv run pytest && uv run ruff check --fix src/ tests/ && uv run mypy src/ -``` - -Report pass/fail. If anything fails, fix it or HALT if it needs a decision. - ---- - -## REMINDERS FOR FLASH-CLASS MODELS - -These rules are critical. Re-read them if you are unsure at any point: - -- **DO NOT edit files in Phase 1-5.** You are reading and reporting. -- **DO NOT resolve ambiguities yourself.** If the spec doesn't say, report "needs decision." -- **DO NOT skip the table format.** The user needs to scan findings quickly. -- **DO NOT summarize away details.** "A few minor differences" is not acceptable. List every difference. -- **DO** cite spec section numbers (e.g. "GRAPHREFLY-SPEC §1.3.5") when classifying gaps. -- **DO** show actual code snippets from both sides when the difference is subtle. -- **DO** note when a test exists on one side but not the other — test parity is as important as API parity. +For behavioral conformance, read `../../../AGENTS.md`, then `../../../.agents/skills/conformance/SKILL.md`. +Structural symbol parity and the old port-model specification are retired. diff --git a/AGENTS.md b/AGENTS.md index bd4065736..801fbb5da 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -11,7 +11,8 @@ self-contained package (substrate + sugar + operators), **no cross-language peer ## Authority — where the truth lives (`~/src/graphrefly`) -Read `~/src/graphrefly/CLAUDE.md` first — it is the single-source index for the design. +For protocol or cross-project work, use `~/src/graphrefly/AGENTS.md` to locate the governing +authority. Read only the records relevant to this task. | Concern | Source of truth | |---|---| @@ -68,12 +69,12 @@ Sibling implementations (each self-contained, cross-language = wire bridge, not Durable values (memory `feedback_*`): no backward compat (pre-1.0) · no imperative triggers · single source of truth · **no autonomous decisions** (surface spec↔code conflicts, don't silently pick) · -no implement without explicit approval · verify premise before greenfield. +implement within the user’s requested scope; retain approval for new semantic or architectural locks · verify premise before greenfield. ## Workflow rules -Before decision or work admission, design review, dispatch, QA, long-running goal progression, -live/provider/spend authorization, retry, or stalled-work recovery, load and follow the personal +When changing authority records or resolving an execution, spend, retry, or stalled-work +authorization boundary, load and follow the personal `$project-governance` skill at `~/.codex/skills/project-governance/SKILL.md`. It governs cross-project record and permission classification, while this repo and `~/src/graphrefly` retain their existing authorities. The concrete GraphReFly family mapping is proposed as @@ -119,3 +120,13 @@ Project-local skills under `.agents/skills/`: New TypeScript-local decisions must satisfy ~/src/graphrefly/authority/README.md. The root-origin-history ledger is relocation-only. + +## Shared build and human review + +Use the personal `~/.codex/skills/bmad-build/SKILL.md` inside the work selected by this repository's +dispatch/Goal workflow. Use `~/.codex/skills/bmad-build/references/qa.md` for machine-review lenses, +finding triage and repairs, together with this repository's own QA checks and completion gates. +Use `~/.codex/skills/bmad-checkpoint-preview/SKILL.md` for the human review trail; it replaces the old +repository-ownership-practice checks. Ordinary delivery uses build-handoff mode; explicit checkpoint +or `--practice` requests use interactive review. The shared skills own only this personal workflow; +project authority, semantic approvals, execution permissions and work records remain locally governed. diff --git a/CLAUDE.md b/CLAUDE.md index 7a9701b5a..8659b9f12 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,107 +1,3 @@ -# graphrefly-ts — agent context (TypeScript implementation) +# Agent instructions -**GraphReFly** — reactive universal reduction layer (high fan-in/out → information reduction → push; -not LLM-limited, D1). This repo is the **TypeScript implementation** (`@graphrefly/ts`): a -self-contained package (substrate + sugar + operators), **no cross-language peer-deps** (D32). - -> **This file points, it does not host.** The language-neutral authority — protocol spec, -> cross-project decisions, design sessions, conformance, formal model — lives in `~/src/graphrefly` (branch -> `clean-slate`). When anything here disagrees with that repo, **that repo wins.** Do not -> duplicate its content back into this file. - -## Authority — where the truth lives (`~/src/graphrefly`) - -Read `~/src/graphrefly/CLAUDE.md` first — it is the single-source index for the design. - -| Concern | Source of truth | -|---|---| -| **Decision locator / global resolver** | `~/src/graphrefly/authority/ledgers.jsonl` + `authority/federation.mjs` | -| **Root language-neutral / cross-project decisions** | `~/src/graphrefly/decisions/decisions.jsonl` | -| **TypeScript package-local decisions** | `decisions/decisions.jsonl` (`graphrefly-ts:`) | -| **Relocated root-origin TypeScript history** | `decisions/root-origin-history.jsonl` (`graphrefly:`, locator-owned; never for new records) | -| **Design narrative** — full L0–L6 locks, F-* constraints, flags, spec-amendment list | `~/src/graphrefly/sessions/active/SESSION-clean-slate-redesign.md` (DS-1) | -| **Protocol rules (宪法)** | `~/src/graphrefly/spec/rules.jsonl` (changed via `/spec-amend`) | -| **Conformance scenarios (parity)** | `~/src/graphrefly/spec/conformance.jsonl` (driven via `/conformance`) | -| **Formal model** | `~/src/graphrefly/formal/*.tla` (+ MC configs) | -| **Cross-project program / backlog / anti-patterns** | `~/src/graphrefly/plan/{phases,backlog,antipatterns}.jsonl` | -| **TypeScript implementation sequencer** | `plan/work.jsonl` (`graphrefly-ts:`; registered by root `authority/work-ledgers.jsonl`) | -| **Guides (composition / docs / test / contribute)** | `~/src/graphrefly/guide/guide.jsonl` | -| **Rendered view** (progress / structure / gaps / search) | `~/src/graphrefly/dashboard/` (`node dashboard/build.mjs`) | - -## Local documentation boundary (`docs/docs.jsonl`) - -This repo's package-local docs policy lives in `docs/docs.jsonl`. - -- `~/src/graphrefly` owns the shared `graphrefly.dev` public website shell, shared public - documentation architecture, blog, guide records, protocol/rules views, and dashboard/control views - (D563). -- `~/src/graphrefly-ts` owns only TypeScript package docs: `@graphrefly/ts` install and release - notes, package README material, JSDoc on exported TS APIs, generated TS API reference artifacts, - examples, demos, and package-local docs automation. -- `website/` is legacy/migration material plus the current TS API-doc generator host until that - generator moves. Do not treat it as canonical ownership of the public site. - -Sibling implementations (each self-contained, cross-language = wire bridge, not in-process): -`@graphrefly/rust` (`~/src/graphrefly-rs`), `@graphrefly/py` (`~/src/graphrefly-py`). - -## Clean-slate floor (cite, never violate — full text in DS-1 / `rules.jsonl`) - -- **Sacred (L0.7):** topology declarative/serializable/inspectable · wave protocol is a public spec · - wave protocol impl is **sync** · all fn go through the dispatcher. -- **8 verbs, closed set (D4):** `node` `graph` `batch` `state` + `producer` `derived` `effect` `mount`. - Operators are `node` sugar, not verbs — per-language, never in parity (D6). -- **`ctx.up` / `ctx.down(msgs)` (D8):** one `msgs` array = one wave; may mix tiers. `ctx.up` is - **control/demand only** (DIRTY/PAUSE/RESUME/PULL/INVALIDATE/TEARDOWN); - START/DATA/RESOLVED/COMPLETE/ERROR are not up-going (R-ctx-up). Handle = pure data - `(pool_id, handle_id)`, no methods (D7). -- **7-tier const table + 11-message closed set (D9/D34/D269, R-tier/R-msg-closed-set):** adding a tier - or message type is a constitutional change. -- **graph = single-thread concurrency domain (D22):** causal influence may cross graphs through - delayed-consistency wire bridges; parallelism via pool callback or multi-graph + wire bridge; - rewire intra-graph only. -- **parity = behavioral conformance (D24):** structural `Impl` + cross-track-ledger retired. -- **config dissolved (D26):** clock is graph-local (no global singleton); `messageTier` is a - compile-time const table; `onMessage`/`onSubscribe` are substrate-fixed, not user-replaceable (D19). -- **Forced (F-*):** F-SYNC-CORE (async lives only in pools / wire-bridge) · F-DISPATCH-ALL (no - inline-fn bypass) · F-NO-IMPL-DEFINED (spec-locked or explicitly undefined) · F-NO-WEDGE-CUT · - F-NO-LLM-ONLY · F-GRAPH-FIRST-API · F-PERF. - -Durable values (memory `feedback_*`): no backward compat (pre-1.0) · no imperative triggers · -single source of truth · **no autonomous decisions** (surface spec↔code conflicts, don't silently pick) · -no implement without explicit approval · verify premise before greenfield. - -## Workflow rules - -- **spec-first** (F-NO-IMPL-DEFINED): any protocol behavior change → amend `~/src/graphrefly` - `spec/rules.jsonl` + `formal/*.tla` + `spec/conformance.jsonl` **before** code (`/spec-amend`). -- **decision-first + owner-first**: `/design-review` → approval → append to the unique owner ledger. - Protocol, cross-runtime and cross-project locks stay in `graphrefly`; TypeScript-only package or - implementation locks go to `graphrefly-ts:decisions/decisions.jsonl`. Never copy the body between ledgers. -- **consistency gate**: `node ~/src/graphrefly/dashboard/build.mjs --check` (non-zero on broken - links / orphans) after touching any spec/decision/plan jsonl. - Run `npm --prefix ~/src/graphrefly run authority:check:workspace` after any owner-ledger change. - -## Commands - -```bash -pnpm test # full TS test suite -pnpm run lint # biome + layer/typecheck gates -pnpm run lint:fix # biome check --write -pnpm run build # build the package -pnpm bench # vitest bench (informational, not a CI gate — L5-Q1) -``` - -## Skills (clean-slate) - -Project-local skills under `.agents/skills/`: - -- **decision-guard** — recall locked D#/values/floor before any decision question. -- **spec-amend** — spec-first protocol amendment (rules + TLA+ + conformance, then code). -- **conformance** — drive behavioral conformance scenarios green per runtime. -- **dashboard** — build / check the `~/src/graphrefly` docs dashboard + consistency gate. -- **dev-dispatch** — plan, align with spec, implement, self-test. -- **qa** — adversarial review, fixes, test + lint + build, doc touch-ups. -- **design-review** — Q5–Q9 design lens before coding new primitives. - -New TypeScript-local decisions must satisfy ~/src/graphrefly/authority/README.md. The -root-origin-history ledger is relocation-only. +Read [AGENTS.md](./AGENTS.md) for this repository’s canonical instructions. diff --git a/GEMINI.md b/GEMINI.md index efed01f16..9eb127ceb 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -1,73 +1,4 @@ -# graphrefly — unified agent context +# Agent instructions -**GraphReFly** — reactive graph protocol for human + LLM co-operation. This repo (`graphrefly-ts`) is the **single source of truth** for operational docs, skills, roadmap, and optimization records across both the TypeScript and Python implementations. - -## Canonical references (read these) - -| Doc | Role | -|-----|------| -| `~/src/graphrefly/GRAPHREFLY-SPEC.md` | **Behavior spec** — messages, `node`, `Graph`, invariants | -| `docs/roadmap.md` | Phased implementation checklist (covers both TS and PY) | -| `docs/optimizations.md` | Cross-language notes, open design decisions | -| `docs/test-guidance.md` | How to write and organize tests (both TS and PY) | -| `docs/demo-and-test-strategy.md` | Demo plans, acceptance criteria, test layers | - -## Repos - -| Repo | Path | Role | -|------|------|------| -| **graphrefly-ts** | this repo | TypeScript implementation + **all operational docs** | -| **graphrefly-py** | `~/src/graphrefly-py` | Python implementation (must stay in parity) | -| **graphrefly** (spec) | `~/src/graphrefly` | `GRAPHREFLY-SPEC.md`, `COMPOSITION-GUIDE.md` | -| **callbag-recharge** | `~/src/callbag-recharge` | TS predecessor (patterns/tests, NOT spec authority) | -| **callbag-recharge-py** | `~/src/callbag-recharge-py` | PY predecessor (concurrency patterns) | - -## Layout - -**TypeScript (`graphrefly-ts`):** -- `src/core/` — message protocol, `node` primitive, batch, sugar constructors (Phase 0) -- `src/graph/` — `Graph` container, describe/observe, snapshot (Phase 1+) -- `src/extra/` — operators and sources (Phase 2+) -- `src/patterns/` — domain layer factories (Phase 4+) - -**Python (`graphrefly-py`):** -- `src/graphrefly/core/` — message protocol, `node` primitive, batch, sugar constructors -- `src/graphrefly/graph/` — `Graph` container, describe/observe, snapshot -- `src/graphrefly/extra/` — operators and sources -- `src/graphrefly/patterns/` — domain layer factories -- `src/graphrefly/compat/` — async runners: asyncio, trio - -## Commands - -**TypeScript:** -```bash -pnpm test # vitest run -pnpm run lint # biome check -pnpm run lint:fix # biome check --write -pnpm run build # tsup -``` - -**Python:** -```bash -uv run pytest # tests -uv run ruff check src/ tests/ # lint -uv run ruff check --fix src/ tests/ # lint fix -uv run mypy src/ # type check -``` - -## Key invariants - -- Messages are always `[[Type, Data?], ...]` (TS) / `list[tuple[Type, Any] | tuple[Type]]` (PY) — no single-message shorthand. -- DIRTY before DATA/RESOLVED in two-phase push; batch defers DATA, not DIRTY. -- Unknown message types forward — do not swallow. -- TS: No `Promise` in public API return types. PY: No `async def` / `Awaitable`. -- TS: Use `src/core/clock.ts`. PY: Use `src/graphrefly/core/clock.py`. (`monotonicNs()`/`monotonic_ns()` for event order, `wallClockNs()`/`wall_clock_ns()` for attribution). -- PY: Thread safety mandatory. Per-subgraph `RLock`. -- `~/src/graphrefly/GRAPHREFLY-SPEC.md` is the behavior authority, not the TS or Python code. - -## Agent skills - -Project-local skills live under `.gemini/skills/`: - -- **dev-dispatch** — implement feature/fix with planning, spec alignment, and self-test. Always halts for approval before implementing. Works on both TS and PY. -- **parity** — cross-language parity check (TS vs PY, read-only until approved) +Read [AGENTS.md](./AGENTS.md) for current clean-slate authority, constraints, and commands. +Use the project workflows in `.agents/skills/`; legacy structural parity is retired.