Skip to content

Commit 101a013

Browse files
committed
📝 Add mandatory field-notes system and Feb 12 session gotchas
1 parent 7f37e2b commit 101a013

4 files changed

Lines changed: 361 additions & 2 deletions

File tree

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Ruff Field Notes — Hashmap loop fusion, JIT sealing fix, and v0.9.0 release prep
2+
3+
**Date:** 2026-02-12
4+
**Session:** 14:52 local
5+
**Branch/Commit:** main / 7f37e2b
6+
**Scope:** Implemented hashmap-oriented bytecode/compiler/VM optimizations, fixed JIT sealing regressions causing test failures, and completed release preparation for v0.9.0. Validated with full build/test and cross-language benchmarks.
7+
8+
---
9+
10+
## What I Changed
11+
- Added fused hashmap loop opcodes in `src/bytecode.rs` for common integer map accumulation/fill patterns.
12+
- Added compiler pattern lowering for canonical while-loop hashmap patterns in `src/compiler.rs`.
13+
- Implemented fused opcode execution paths and VM-level tests in `src/vm.rs`.
14+
- Fixed Cranelift block sealing regressions in `src/jit.rs` to eliminate panics in JIT tests.
15+
- Updated release/docs metadata in `CHANGELOG.md`, `ROADMAP.md`, `README.md`, and `Cargo.toml` for v0.9.0.
16+
- Ran `cargo build`, `cargo test`, and full cross-language benchmarks via `benchmarks/cross-language/run_benchmarks.sh`.
17+
- Created release commit and tag, then pushed `main` and `v0.9.0` to remote.
18+
19+
## Gotchas (Read This Next Time)
20+
- **Gotcha:** Cranelift block sealing must happen in strict control-flow order.
21+
- **Symptom:** JIT tests panic with Cranelift assertions around already-sealed or improperly sealed blocks.
22+
- **Root cause:** Some paths sealed blocks early or attempted duplicate sealing when loop/header flow had multiple edges.
23+
- **Fix:** Centralized and corrected sealing logic in `src/jit.rs` so blocks are sealed exactly once at the right stage.
24+
- **Prevention:** Treat block sealing as a control-flow invariant; when touching JIT branching/loops, re-run targeted JIT tests before full suite.
25+
26+
- **Gotcha:** Hashmap loop fusion only applies to specific canonical shapes.
27+
- **Symptom:** Expected fusion does not occur for semantically equivalent loops with reordered or extra statements.
28+
- **Root cause:** Compiler optimization is pattern-based, not a full general-purpose loop optimizer.
29+
- **Fix:** Keep matcher strict and optimize known hot patterns first.
30+
- **Prevention:** Add new fusion patterns intentionally with tests; do not assume all equivalent loops are currently optimized.
31+
32+
- **Gotcha:** Benchmark conclusions can drift if non-comparable workloads are mixed.
33+
- **Symptom:** Performance claims vary run-to-run when benchmark mix or warmup conditions change.
34+
- **Root cause:** Startup overhead and workload differences dominate tiny tasks.
35+
- **Fix:** Use the cross-language benchmark harness consistently and compare the same scripts across Ruff/Python/Go.
36+
- **Prevention:** Keep benchmark table generation tied to one command and one benchmark set per report.
37+
38+
## Things I Learned
39+
- JIT correctness invariants (SSA/block sealing) are as release-critical as throughput gains; performance changes must be paired with stability sweeps.
40+
- In this codebase, high-confidence optimization work means: targeted tests first, full suite second, cross-language benchmark last.
41+
- Release readiness should include metadata synchronization (`Cargo.toml`, changelog, roadmap, README), not just green tests.
42+
- Canonical-pattern fusion delivers meaningful wins quickly without requiring broad IR redesign.
43+
44+
## Debug Notes (Only if applicable)
45+
- **Failing test / error:** Cranelift JIT panics related to block sealing invariants (already-sealed / incorrect sealing order).
46+
- **Repro steps:** Run `cargo test` after JIT/optimizer edits; failures appear in JIT-focused tests.
47+
- **Breakpoints / logs used:** Focused on JIT control-flow/sealing paths in `src/jit.rs`; iterated with targeted runs then full suite.
48+
- **Final diagnosis:** Block sealing was performed at inconsistent points for some control-flow shapes; corrected ordering removed panics.
49+
50+
## Follow-ups / TODO (For Future Agents)
51+
- [ ] Add focused regression tests that isolate problematic sealing shapes (nested loops/branches) at JIT translation boundaries.
52+
- [ ] Expand hashmap fusion matcher coverage incrementally with benchmark-backed additions.
53+
- [ ] Automate release checklist into a single script (build + tests + benchmark + metadata checks).
54+
55+
## Links / References
56+
- Files touched:
57+
- `src/bytecode.rs`
58+
- `src/compiler.rs`
59+
- `src/vm.rs`
60+
- `src/jit.rs`
61+
- `CHANGELOG.md`
62+
- `ROADMAP.md`
63+
- `README.md`
64+
- `Cargo.toml`
65+
- Related docs:
66+
- `README.md`
67+
- `ROADMAP.md`
68+
- `CHANGELOG.md`
69+
- `notes/FIELD_NOTES_SYSTEM.md`
70+
- `notes/GOTCHAS.md`

notes/FIELD_NOTES_SYSTEM.md

Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
1+
# Ruff AI Agent Field Notes & Gotchas System
2+
3+
This document defines a **mandatory post-work note-taking system** for AI agents working on the Ruff programming language. The goal is to capture *hands-on, experience-based knowledge* so future agents build faster, avoid mistakes, and develop correct mental models of the codebase.
4+
5+
This is not documentation.
6+
This is **operational memory**.
7+
8+
---
9+
10+
## 🎯 Purpose
11+
12+
After implementing features, fixing bugs, refactoring, or debugging Ruff, the AI agent must distill what it learned into structured Markdown notes.
13+
14+
These notes should capture:
15+
16+
* surprising behavior
17+
* incorrect assumptions
18+
* fragile areas of the code
19+
* ordering constraints
20+
* edge cases
21+
* rules the code implicitly relies on
22+
23+
Future agents should be able to read these notes and *immediately* avoid repeated mistakes.
24+
25+
---
26+
27+
## 📁 Folder Structure
28+
29+
```
30+
./notes/
31+
├── YYYY-MM-DD_HH-mm_short-kebab-summary.md
32+
├── YYYY-MM-DD_HH-mm_another-session.md
33+
├── GOTCHAS.md
34+
└── README.md (optional index)
35+
```
36+
37+
* One notes file per work session
38+
* Notes are append-only (never overwrite or rename old files)
39+
40+
---
41+
42+
## 🧾 Session Notes File Rules
43+
44+
### Filename format (required)
45+
46+
```
47+
YYYY-MM-DD_HH-mm_short-kebab-summary.md
48+
```
49+
50+
Examples:
51+
52+
* `2026-01-25_10-14_parser-gotchas.md`
53+
* `2026-01-25_18-02_vm-scope-fix.md`
54+
55+
If `./notes/` does not exist, create it.
56+
57+
---
58+
59+
## 🧠 When Notes Must Be Written
60+
61+
Create or update a session notes file after:
62+
63+
* adding a feature
64+
* fixing a bug
65+
* debugging a test failure
66+
* changing parser / lexer / AST / evaluator / runtime behavior
67+
* modifying CLI behavior
68+
* discovering surprising or non-obvious behavior
69+
* correcting an incorrect assumption
70+
71+
**One work session = one notes file**
72+
73+
---
74+
75+
## 🧱 Required Session Notes Template
76+
77+
Each session notes file **must use this exact structure**:
78+
79+
```md
80+
# Ruff Field Notes — <short human title>
81+
82+
**Date:** <YYYY-MM-DD>
83+
**Session:** <HH:mm local>
84+
**Branch/Commit:** <branch name> / <commit hash (if known)>
85+
**Scope:** <1–2 sentences describing what you worked on>
86+
87+
---
88+
89+
## What I Changed
90+
- <bullet list of concrete changes>
91+
- <include file paths when helpful>
92+
93+
## Gotchas (Read This Next Time)
94+
- **Gotcha:** <what surprised you>
95+
- **Symptom:** <what you observed>
96+
- **Root cause:** <why it happened>
97+
- **Fix:** <what resolved it>
98+
- **Prevention:** <how to avoid it next time>
99+
100+
(repeat for each gotcha)
101+
102+
## Things I Learned
103+
- <mental model updates>
104+
- <rules of thumb>
105+
- <implicit invariants or ordering constraints>
106+
107+
## Debug Notes (Only if applicable)
108+
- **Failing test / error:** <exact error output>
109+
- **Repro steps:** <how to reproduce>
110+
- **Breakpoints / logs used:** <where you looked>
111+
- **Final diagnosis:** <what it actually was>
112+
113+
## Follow-ups / TODO (For Future Agents)
114+
- [ ] <specific next step>
115+
- [ ] <tech debt introduced or deferred>
116+
117+
## Links / References
118+
- Files touched:
119+
- `<path>`
120+
- `<path>`
121+
- Related docs:
122+
- `README.md`
123+
- `ROADMAP.md`
124+
- <other docs>
125+
```
126+
127+
---
128+
129+
## ✍️ Writing Style Rules (Critical)
130+
131+
* Write like you are leaving a note to your **future self** with partial context
132+
* Be concrete, not theoretical
133+
* Include file paths, function names, enums, structs, and commands
134+
* If something *will surprise someone*, call it out explicitly
135+
* If something relies on an ordering constraint, write it as a **rule**
136+
* If unsure what to write, write *less*, but make it *specific*
137+
138+
### 🚨 Mandatory Capture Rule: "Justified Behavior"
139+
140+
If the agent has to **justify** why something is OK, expected, intentional, or safe, it **must be documented**.
141+
142+
This includes moments where the agent says or implies:
143+
144+
* "This warning is expected"
145+
* "This is intentional"
146+
* "This is safe because…"
147+
* "We can ignore this"
148+
* "It only happens in X, not Y"
149+
* "This is a known limitation"
150+
* "We’ll clean this up later"
151+
152+
These statements compress non-obvious reasoning and **will not be obvious from the code alone**.
153+
154+
When this happens, add an entry under **Gotchas** or **Things I Learned**.
155+
156+
### Example (Required Documentation Pattern)
157+
158+
```md
159+
- **Gotcha:** Compiler warning about `Spread` being unused as an `Expr`
160+
- **Symptom:** Warning emitted during compile about `Spread` enum variant
161+
- **Root cause:** `Spread` is intentionally NOT a standalone `Expr`
162+
- **Fix:** None — this is expected behavior
163+
- **Prevention:** Do not refactor `Spread` into `Expr` without redesigning
164+
array/dict element handling. `Spread` is only valid within
165+
`ArrayElement` and `DictElement`.
166+
```
167+
168+
### Optional (High Value): Assumptions I Almost Made
169+
170+
If applicable, add:
171+
172+
```md
173+
## Assumptions I Almost Made
174+
- I initially assumed `Spread` should be an `Expr`, but that breaks
175+
contextual evaluation rules
176+
```
177+
178+
🚫 Avoid:
179+
180+
* generic explanations
181+
* textbook definitions
182+
* restating obvious code behavior
183+
184+
---
185+
186+
## 🧠 Curated GOTCHAS.md (Deduplicated)
187+
188+
In addition to session notes, maintain a **curated, long-lived gotchas file**:
189+
190+
```
191+
./notes/GOTCHAS.md
192+
```
193+
194+
### Purpose
195+
196+
* High-signal summary of the most important pitfalls in Ruff
197+
* Deduplicated across sessions
198+
* Clean, readable, and short
199+
* Suitable for onboarding new agents
200+
201+
Session notes are raw.
202+
`GOTCHAS.md` is refined.
203+
204+
---
205+
206+
## 📘 GOTCHAS.md Structure
207+
208+
```md
209+
# Ruff — Known Gotchas & Sharp Edges
210+
211+
This document contains the most important non-obvious pitfalls in the Ruff codebase.
212+
213+
If you are new to the project, read this first.
214+
215+
---
216+
217+
## Parser & Syntax
218+
219+
### Expression precedence is NOT inferred
220+
- **Problem:** <what breaks>
221+
- **Rule:** <explicit rule the parser expects>
222+
- **Why:** <design rationale>
223+
224+
## Runtime / Evaluator
225+
226+
### Variable scope is resolved at <stage>
227+
- **Problem:** <symptom>
228+
- **Rule:** <how scope resolution actually works>
229+
- **Implication:** <what not to assume>
230+
231+
## CLI & Tooling
232+
233+
### Tests must be run with <specific command>
234+
- **Problem:** <failure mode>
235+
- **Rule:** <correct workflow>
236+
237+
---
238+
239+
## Mental Model Summary
240+
241+
- Ruff favors <design philosophy>
242+
- The parser assumes <key assumption>
243+
- The runtime guarantees <invariant>
244+
- Do NOT assume <common incorrect assumption>
245+
```
246+
247+
### Rules for Updating GOTCHAS.md
248+
249+
* Only add **confirmed, repeated, or high-impact** issues
250+
* Merge duplicates instead of appending
251+
* Prefer rules over stories
252+
* Reference session notes where the discovery came from
253+
254+
Example:
255+
256+
```md
257+
(Discovered during: 2026-01-25_10-14_parser-gotchas.md)
258+
```
259+
260+
---
261+
262+
## 📑 Optional: notes/README.md Index
263+
264+
If the notes folder grows large, maintain an index:
265+
266+
```md
267+
# Ruff Field Notes Index
268+
269+
- 2026-01-25_10-14_parser-gotchas.md — Parser edge cases & failure modes
270+
- 2026-01-25_18-02_vm-scope-fix.md — Runtime scoping corrections
271+
```
272+
273+
Only add entries for **high-signal sessions**.
274+
275+
---
276+
277+
## ✅ Definition of Done (Recommended)
278+
279+
A task is **not complete** unless:
280+
281+
* code compiles
282+
* tests pass
283+
* **session notes are written**
284+
* GOTCHAS.md is updated *if applicable*
285+
286+
This system turns AI experience into durable project knowledge.

notes/GOTCHAS.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,8 @@ If you are new to the project, read this first.
752752
### Block sealing order matters for SSA
753753

754754
- **Problem:** Panics with "unsealed block" or "block not filled" errors
755-
- **Rule:** Use two-pass translation - create all blocks first, then translate instructions, seal after adding terminator
755+
- **Rule:** Use two-pass translation - create all blocks first, then translate instructions, and seal blocks only after predecessor edges are finalized and terminators are emitted.
756+
- **Rule (critical):** Each block must be sealed exactly once. Early sealing or duplicate sealing on alternate control-flow paths can trigger Cranelift assertions (including already-sealed failures).
756757
- **Why:** Cranelift requires all predecessors of a block known before sealing (SSA form)
757758
- **Pattern:**
758759
```rust
@@ -767,7 +768,7 @@ If you are new to the project, read this first.
767768
```
768769
- **Implication:** Cannot seal blocks until all jumps to them are generated
769770

770-
(Discovered during: 2026-01-27_14-51_jit-phase-3-completion.md)
771+
(Discovered during: 2026-01-27_14-51_jit-phase-3-completion.md, reinforced in: 2026-02-12_14-52_hashmap-fusion-jit-sealing-release.md)
771772

772773
### Hash-based variable resolution has collision risk
773774

notes/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@ These notes capture:
2323

2424
## Quick Navigation
2525

26+
- **FIELD_NOTES_SYSTEM.md** - Mandatory workflow and template for post-work field notes
2627
- **GOTCHAS.md** - Start here! Curated list of the most important non-obvious pitfalls
2728
- Session notes below - Raw, chronological records of each work session
2829

2930
---
3031

3132
## Session Notes (Chronological)
3233

34+
- **2026-02-12_14-52_hashmap-fusion-jit-sealing-release.md** — ✅ COMPLETED: Hashmap performance fusion + JIT sealing stability + v0.9.0 release prep. Added fused map opcodes in bytecode/compiler/VM, fixed Cranelift sealing regressions in `src/jit.rs`, validated with full build/tests/benchmarks, and finalized release metadata/tag push.
3335
- **2026-01-27_phase4e-jit-benchmarking.md** — ✅ COMPLETED: Phase 4E JIT Performance Benchmarking & Validation (v0.9.0). Added 7 micro-benchmark tests + infrastructure validation test. Created 5 real-world benchmark programs. Validated all Phase 4 subsystems: type profiling (11.5M obs/sec), guard generation (46µs per guard), cache lookups (27M/sec), specialization (57M decisions/sec). Phase 4 now 100% complete! ~3 hours implementation time. 3 commits, 198 tests passing.
3436
- **2026-01-26_vm-exception-handling.md** — ✅ COMPLETED: VM Exception Handling Implementation (v0.9.0 Phase 1). Implemented full exception handling in bytecode VM with BeginTry/EndTry/Throw/BeginCatch/EndCatch opcodes. Added exception handler stack for proper unwinding. Critical lesson: chunk restoration during call frame unwinding. Comprehensive test suite (9 scenarios). VM/interpreter parity achieved. ~3 hours implementation time.
3537
- **2026-01-26_interpreter-modularization-phase2.md** — ✅ PHASE 2 COMPLETE: Interpreter Modularization. Extracted ControlFlow enum (22 lines) to control_flow.rs and test framework (230 lines) to test_runner.rs. Reduced mod.rs from 14,285 to 14,071 lines (additional -214 lines). Total reduction: -731 lines from original 14,802 (~5%). Documented key decisions: why call_native_function_impl and register_builtins must stay in impl block. Clarified that remaining size is appropriate. Zero warnings, all tests passing.

0 commit comments

Comments
 (0)