@kodrunhq/opencode-autopilot 1.4.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/assets/commands/brainstorm.md +7 -0
  2. package/assets/commands/stocktake.md +7 -0
  3. package/assets/commands/tdd.md +7 -0
  4. package/assets/commands/update-docs.md +7 -0
  5. package/assets/commands/write-plan.md +7 -0
  6. package/assets/skills/brainstorming/SKILL.md +295 -0
  7. package/assets/skills/code-review/SKILL.md +241 -0
  8. package/assets/skills/e2e-testing/SKILL.md +266 -0
  9. package/assets/skills/git-worktrees/SKILL.md +296 -0
  10. package/assets/skills/go-patterns/SKILL.md +240 -0
  11. package/assets/skills/plan-executing/SKILL.md +258 -0
  12. package/assets/skills/plan-writing/SKILL.md +278 -0
  13. package/assets/skills/python-patterns/SKILL.md +255 -0
  14. package/assets/skills/rust-patterns/SKILL.md +293 -0
  15. package/assets/skills/strategic-compaction/SKILL.md +217 -0
  16. package/assets/skills/systematic-debugging/SKILL.md +299 -0
  17. package/assets/skills/tdd-workflow/SKILL.md +311 -0
  18. package/assets/skills/typescript-patterns/SKILL.md +278 -0
  19. package/assets/skills/verification/SKILL.md +240 -0
  20. package/bin/configure-tui.ts +1 -1
  21. package/package.json +1 -1
  22. package/src/config.ts +76 -14
  23. package/src/index.ts +43 -2
  24. package/src/memory/capture.ts +205 -0
  25. package/src/memory/constants.ts +26 -0
  26. package/src/memory/database.ts +103 -0
  27. package/src/memory/decay.ts +94 -0
  28. package/src/memory/index.ts +24 -0
  29. package/src/memory/injector.ts +85 -0
  30. package/src/memory/project-key.ts +5 -0
  31. package/src/memory/repository.ts +217 -0
  32. package/src/memory/retrieval.ts +260 -0
  33. package/src/memory/schemas.ts +34 -0
  34. package/src/memory/types.ts +12 -0
  35. package/src/orchestrator/skill-injection.ts +38 -0
  36. package/src/review/sanitize.ts +1 -1
  37. package/src/skills/adaptive-injector.ts +122 -0
  38. package/src/skills/dependency-resolver.ts +88 -0
  39. package/src/skills/linter.ts +113 -0
  40. package/src/skills/loader.ts +88 -0
  41. package/src/templates/skill-template.ts +4 -0
  42. package/src/tools/configure.ts +1 -1
  43. package/src/tools/create-skill.ts +12 -0
  44. package/src/tools/memory-status.ts +164 -0
  45. package/src/tools/stocktake.ts +170 -0
  46. package/src/tools/update-docs.ts +116 -0
@@ -0,0 +1,293 @@
1
+ ---
2
+ name: rust-patterns
3
+ description: Rust patterns covering ownership, error handling with Result/Option, unsafe guidelines, and testing conventions
4
+ stacks:
5
+ - rust
6
+ requires: []
7
+ ---
8
+
9
+ # Rust Patterns
10
+
11
+ Idiomatic Rust patterns for writing safe, efficient, and maintainable code. Covers ownership and borrowing, error handling with `Result` and `Option`, unsafe guidelines, testing conventions, crate organization, and common anti-patterns. Apply these when writing, reviewing, or refactoring Rust code.
12
+
13
+ ## 1. Ownership and Borrowing
14
+
15
+ **DO:** Leverage Rust's ownership system to write safe code without garbage collection.
16
+
17
+ - Prefer borrowing (`&T`, `&mut T`) over taking ownership when the function doesn't need to own the data:
18
+ ```rust
19
+ // DO: Borrow -- caller keeps ownership
20
+ fn process(items: &[Item]) -> Summary { ... }
21
+
22
+ // DON'T: Take ownership unnecessarily
23
+ fn process(items: Vec<Item>) -> Summary { ... }
24
+ ```
25
+ - Prefer `&str` over `String` in function parameters:
26
+ ```rust
27
+ fn greet(name: &str) -> String {
28
+ format!("Hello, {name}!")
29
+ }
30
+ // Accepts both String and &str via deref coercion
31
+ ```
32
+ - Use lifetimes explicitly when the compiler cannot infer them:
33
+ ```rust
34
+ struct Parser<'a> {
35
+ input: &'a str,
36
+ position: usize,
37
+ }
38
+ ```
39
+ - Understand move semantics -- types implementing `Copy` are copied, others are moved:
40
+ ```rust
41
+ let a = String::from("hello");
42
+ let b = a; // a is MOVED to b, a is no longer valid
43
+ // For Copy types (i32, f64, bool): both remain valid
44
+ ```
45
+ - Use `Cow<'_, str>` when a function sometimes needs to allocate and sometimes doesn't:
46
+ ```rust
47
+ fn normalize(input: &str) -> Cow<'_, str> {
48
+ if input.contains(' ') {
49
+ Cow::Owned(input.replace(' ', "_"))
50
+ } else {
51
+ Cow::Borrowed(input)
52
+ }
53
+ }
54
+ ```
55
+
56
+ **DON'T:**
57
+
58
+ - Use `Clone` to silence the borrow checker -- fix the ownership design instead
59
+ - Pass `&String` -- pass `&str` (more general, no extra indirection)
60
+ - Use `'static` lifetime unless the data truly lives for the entire program
61
+ - Fight the borrow checker with `Rc<RefCell<T>>` everywhere -- rethink the data flow
62
+
63
+ ## 2. Error Handling
64
+
65
+ **DO:** Use `Result<T, E>` for recoverable errors and the `?` operator for ergonomic propagation.
66
+
67
+ - Use `Result<T, E>` for all operations that can fail:
68
+ ```rust
69
+ fn parse_config(path: &Path) -> Result<Config, ConfigError> {
70
+ let content = fs::read_to_string(path)?;
71
+ let config: Config = toml::from_str(&content)?;
72
+ Ok(config)
73
+ }
74
+ ```
75
+ - Use `?` for error propagation -- it's Rust's equivalent of Go's `if err != nil`:
76
+ ```rust
77
+ fn process() -> Result<Output, AppError> {
78
+ let input = read_input()?; // propagates on Err
79
+ let parsed = parse(input)?; // propagates on Err
80
+ let result = transform(parsed)?; // propagates on Err
81
+ Ok(result)
82
+ }
83
+ ```
84
+ - Use `thiserror` for custom error types in library code:
85
+ ```rust
86
+ #[derive(Debug, thiserror::Error)]
87
+ enum AppError {
88
+ #[error("config error: {0}")]
89
+ Config(#[from] ConfigError),
90
+ #[error("database error: {0}")]
91
+ Database(#[from] sqlx::Error),
92
+ #[error("not found: {resource}")]
93
+ NotFound { resource: String },
94
+ }
95
+ ```
96
+ - Use `anyhow::Result` in application code (binaries, CLI tools) where you don't need typed errors:
97
+ ```rust
98
+ fn main() -> anyhow::Result<()> {
99
+ let config = load_config().context("failed to load config")?;
100
+ run(config)?;
101
+ Ok(())
102
+ }
103
+ ```
104
+ - Add context to errors with `.context()` or `.with_context()`:
105
+ ```rust
106
+ fs::read_to_string(path)
107
+ .with_context(|| format!("failed to read {}", path.display()))?;
108
+ ```
109
+
110
+ **DON'T:**
111
+
112
+ - Use `panic!` for recoverable errors -- `panic!` is for bugs, not expected failures
113
+ - Use `.unwrap()` in production code -- use `?`, `.unwrap_or_default()`, or explicit match
114
+ - Create error types without `#[derive(Debug)]` -- debug formatting is essential for logging
115
+ - Return `Box<dyn Error>` in library code -- use typed errors for caller inspection
116
+
117
+ ## 3. Option Patterns
118
+
119
+ **DO:** Use `Option<T>` instead of null/sentinel values, and prefer combinators over manual matching.
120
+
121
+ - Use combinators for clean transformations:
122
+ ```rust
123
+ let display_name = user.nickname
124
+ .map(|n| format!("@{n}"))
125
+ .unwrap_or_else(|| user.full_name.clone());
126
+ ```
127
+ - Use `if let` for conditional extraction:
128
+ ```rust
129
+ if let Some(config) = load_optional_config() {
130
+ apply(config);
131
+ }
132
+ ```
133
+ - Use `?` with `Option` in functions returning `Option`:
134
+ ```rust
135
+ fn get_user_email(db: &Database, id: UserId) -> Option<String> {
136
+ let user = db.find_user(id)?; // returns None if not found
137
+ Some(user.email.clone())
138
+ }
139
+ ```
140
+ - Chain operations with `.and_then()` for flat-mapping:
141
+ ```rust
142
+ let port: Option<u16> = env::var("PORT").ok().and_then(|s| s.parse().ok());
143
+ ```
144
+
145
+ **DON'T:**
146
+
147
+ - Use `.unwrap()` outside of tests -- it panics on `None`
148
+ - Use sentinel values (`-1`, `""`, `0`) when `Option` expresses the intent clearly
149
+ - Match when a combinator is more concise -- `option.map(f)` beats `match option { Some(v) => Some(f(v)), None => None }`
150
+ - Use `Option<Option<T>>` -- it's confusing. Use an enum with explicit variants instead
151
+
152
+ ## 4. Unsafe Guidelines
153
+
154
+ **DO:** Minimize unsafe code and encapsulate it behind safe abstractions.
155
+
156
+ - Wrap every `unsafe` block in a safe function with documented invariants:
157
+ ```rust
158
+ /// Returns a reference to the element at `index` without bounds checking.
159
+ ///
160
+ /// # Safety
161
+ /// Caller must ensure `index < self.len()`.
162
+ pub unsafe fn get_unchecked(&self, index: usize) -> &T { ... }
163
+ ```
164
+ - Document every `unsafe` block with a `// SAFETY:` comment explaining the invariant:
165
+ ```rust
166
+ // SAFETY: We checked that index < len on the line above.
167
+ let value = unsafe { slice.get_unchecked(index) };
168
+ ```
169
+ - Keep `unsafe` blocks as small as possible -- one operation per block
170
+ - Prefer safe alternatives in all cases:
171
+ - `Vec<T>` over raw pointers and manual allocation
172
+ - `Arc<Mutex<T>>` over shared mutable raw pointers
173
+ - `std::sync::atomic` over `unsafe` for atomic operations
174
+ - `crossbeam` or channels over `unsafe` for concurrent data structures
175
+
176
+ **DON'T:**
177
+
178
+ - Use `unsafe` for performance without benchmarks proving it's necessary
179
+ - Use `transmute` -- it's almost never the right answer. Use `from_ne_bytes`, `TryFrom`, or safe casts
180
+ - Dereference raw pointers without validating alignment and lifetime
181
+ - Implement `Send` or `Sync` manually unless you deeply understand the invariants
182
+ - Use `unsafe` to bypass the borrow checker -- it means the design is wrong
183
+
184
+ ## 5. Testing
185
+
186
+ **DO:** Write unit tests in the same file and integration tests in `tests/`.
187
+
188
+ - Unit tests in the same file with `#[cfg(test)]`:
189
+ ```rust
190
+ #[cfg(test)]
191
+ mod tests {
192
+ use super::*;
193
+
194
+ #[test]
195
+ fn parse_valid_config() {
196
+ let config = parse_config("key = \"value\"").unwrap();
197
+ assert_eq!(config.key, "value");
198
+ }
199
+
200
+ #[test]
201
+ fn parse_empty_returns_error() {
202
+ assert!(parse_config("").is_err());
203
+ }
204
+ }
205
+ ```
206
+ - Use `#[should_panic]` for expected panics:
207
+ ```rust
208
+ #[test]
209
+ #[should_panic(expected = "index out of bounds")]
210
+ fn panics_on_invalid_index() {
211
+ get_item(&[], 0);
212
+ }
213
+ ```
214
+ - Use `assert_eq!` with descriptive messages:
215
+ ```rust
216
+ assert_eq!(result, expected, "failed for input: {input:?}");
217
+ ```
218
+ - Integration tests in `tests/` directory access only the public API:
219
+ ```
220
+ tests/
221
+ integration_test.rs
222
+ common/
223
+ mod.rs // shared test helpers
224
+ ```
225
+ - Use `proptest` or `quickcheck` for property-based testing:
226
+ ```rust
227
+ proptest! {
228
+ #[test]
229
+ fn roundtrip_serialize(value: MyType) {
230
+ let bytes = serialize(&value);
231
+ let decoded = deserialize(&bytes).unwrap();
232
+ assert_eq!(value, decoded);
233
+ }
234
+ }
235
+ ```
236
+ - Use `#[ignore]` for slow tests with a reason: `#[ignore = "requires database"]`
237
+
238
+ **DON'T:**
239
+
240
+ - Put test utilities in the main `src/` tree -- use `tests/common/` or a `dev-dependencies` crate
241
+ - Use `.unwrap()` in tests without context -- prefer `.expect("reason")` for better panic messages
242
+ - Test private implementation details -- test through the public API
243
+ - Skip `#[cfg(test)]` on the test module -- tests will be compiled into release builds
244
+
245
+ ## 6. Crate Organization
246
+
247
+ **DO:** Organize crates for clarity and minimal compilation units.
248
+
249
+ - Use a workspace for multi-crate projects:
250
+ ```toml
251
+ # Cargo.toml (workspace root)
252
+ [workspace]
253
+ members = ["crates/*"]
254
+ ```
255
+ - Separate library and binary crates:
256
+ ```
257
+ src/
258
+ lib.rs # library logic
259
+ main.rs # thin entry point calling lib
260
+ ```
261
+ - Use `pub(crate)` for internal visibility -- not everything needs to be fully public
262
+ - Group related types in modules:
263
+ ```rust
264
+ // src/lib.rs
265
+ pub mod config;
266
+ pub mod error;
267
+ pub mod client;
268
+ ```
269
+ - Keep `main.rs` thin -- parse args, configure logging, call library functions
270
+
271
+ **DON'T:**
272
+
273
+ - Put everything in `lib.rs` -- split into modules when the file exceeds 400 lines
274
+ - Use `pub` on everything -- default to private, expose only what's needed
275
+ - Create deep module hierarchies -- flat is better than nested
276
+ - Use `mod.rs` files (old style) -- prefer `module_name.rs` (2018 edition style)
277
+
278
+ ## 7. Anti-Pattern Catalog
279
+
280
+ **Anti-Pattern: Unnecessary Clone**
281
+ Calling `.clone()` to satisfy the borrow checker without understanding why it's needed. Cloning hides design problems -- if you need to clone, ask whether the ownership model is correct. Instead: restructure code to use references, or use `Cow<'_, T>` when cloning is sometimes needed.
282
+
283
+ **Anti-Pattern: Unwrap Everywhere**
284
+ Sprinkling `.unwrap()` in production code because "it should never be None/Err". It will be, and it will panic at 3am. Instead: use `?` for propagation, `.unwrap_or_default()` for safe defaults, or `match`/`if let` for explicit handling.
285
+
286
+ **Anti-Pattern: Stringly Typed**
287
+ Using `String` for everything -- status codes, identifiers, categories. Strings have no compile-time validation. Instead: use newtypes (`struct UserId(String)`) and enums (`enum Status { Active, Inactive }`) for domain concepts.
288
+
289
+ **Anti-Pattern: Over-Generic Functions**
290
+ `fn process<T: Debug + Clone + Send + Sync + 'static>(item: T)` when the function only ever processes `Widget`. Generics should be introduced when there are 2+ concrete types that need the same logic. Instead: start concrete, generalize when needed.
291
+
292
+ **Anti-Pattern: Ignoring Clippy**
293
+ Adding `#[allow(clippy::...)]` instead of fixing the lint. Clippy catches real bugs (unnecessary allocations, logic errors, unidiomatic code). Instead: fix the issue. If the lint is genuinely wrong, add a comment explaining why.
@@ -0,0 +1,217 @@
1
+ ---
2
+ name: strategic-compaction
3
+ description: Context window management through strategic summarization -- keep working memory lean without losing critical information
4
+ stacks: []
5
+ requires: []
6
+ ---
7
+
8
+ # Strategic Compaction
9
+
10
+ Context window management through strategic summarization. When your working context grows large, compaction keeps you productive by preserving what matters and discarding what does not. This skill teaches when to compact, what to keep, and how to rebuild context from a summary.
11
+
12
+ ## When to Use
13
+
14
+ - Context window is filling up (more than 60% used)
15
+ - Working on a long task spanning many files
16
+ - Need to switch subtasks without losing prior context
17
+ - Session is slowing down or responses are becoming less detailed
18
+ - You are about to start a new phase of work that does not need the details of the previous phase
19
+ - After completing a major subtask and before starting the next
20
+
21
+ ## The Compaction Process
22
+
23
+ Compaction is a four-step process. Follow each step in order.
24
+
25
+ ### Step 1: Identify What to Keep
26
+
27
+ These items are essential and must survive compaction:
28
+
29
+ - **Current task requirements** -- the active goal and acceptance criteria
30
+ - **Key decisions made so far** -- and the rationale behind each one (the WHY is more important than the WHAT)
31
+ - **File paths and function signatures** -- for files currently being modified or about to be modified
32
+ - **Error messages and test failures** -- if you are actively investigating or debugging
33
+ - **Constraints and invariants** -- rules that must not be violated (security requirements, API contracts, performance budgets)
34
+ - **Dependency relationships** -- what depends on what, what must be done in order
35
+
36
+ ### Step 2: Identify What to Compact
37
+
38
+ These items can be summarized or discarded:
39
+
40
+ - **File contents already read and understood** -- keep only the path plus the key insight (e.g., "src/auth.ts: JWT validation using jose library, exports verifyToken()")
41
+ - **Exploration dead ends** -- reduce to one line: "Tried approach X, did not work because Y"
42
+ - **Verbose tool output** -- keep the conclusion, discard the raw output (e.g., "Tests pass: 47/47" instead of the full test runner output)
43
+ - **Background context not needed for the current subtask** -- prior phase decisions that are not relevant to what you are doing right now
44
+ - **Completed work details** -- reduce to "Task N done: implemented feature X in file Y" with the commit hash
45
+
46
+ ### Step 3: Create a Summary
47
+
48
+ Structure your summary using this template:
49
+
50
+ ```
51
+ ## Working Context Summary
52
+
53
+ **Goal:** [one sentence describing the active objective]
54
+
55
+ **Key Decisions:**
56
+ - [Decision 1]: [rationale]
57
+ - [Decision 2]: [rationale]
58
+
59
+ **Current State:**
60
+ - Done: [what has been completed]
61
+ - In Progress: [what is currently being worked on]
62
+ - Next: [what comes after the current task]
63
+
64
+ **Active Files:**
65
+ - [path]: [what you are doing with this file]
66
+ - [path]: [key insight about this file]
67
+
68
+ **Constraints:**
69
+ - [constraint 1]
70
+ - [constraint 2]
71
+
72
+ **Errors/Blockers:**
73
+ - [any active issues being investigated]
74
+ ```
75
+
76
+ Target 500-1000 tokens for the summary. This is your restore point -- it should contain everything needed to resume work without re-reading files.
77
+
78
+ ### Step 4: Apply Compaction
79
+
80
+ When starting a new session or after context reset:
81
+
82
+ 1. Load the summary first -- this is your map
83
+ 2. Read only the files actively being modified (the "Active Files" list)
84
+ 3. Re-read constraints and interfaces only if you need to verify a specific detail
85
+ 4. Do NOT re-read files that were already summarized unless you need to edit them
86
+
87
+ ## What to NEVER Compact
88
+
89
+ Some information is too dangerous to summarize. Always keep these in full:
90
+
91
+ - **Active error messages being debugged** -- the exact error text matters for diagnosis
92
+ - **Type definitions and interfaces being implemented against** -- approximate types lead to type errors
93
+ - **Test expectations being satisfied** -- the exact assertion values matter
94
+ - **Security constraints and validation rules** -- approximate security is no security
95
+ - **API contracts with external systems** -- exact field names, types, and required headers
96
+ - **Migration scripts in progress** -- partial migration state is dangerous to approximate
97
+
98
+ ## Compaction Strategies by Scenario
99
+
100
+ ### Scenario: Multi-File Refactoring
101
+
102
+ You have read 15 files and identified the refactoring pattern. Compact by keeping:
103
+ - The list of files to modify (paths only)
104
+ - The transformation pattern (e.g., "replace direct DB calls with repository pattern")
105
+ - Files already transformed (path + done status)
106
+ - The next file to transform
107
+
108
+ ### Scenario: Debugging a Complex Issue
109
+
110
+ You have explored multiple hypotheses. Compact by keeping:
111
+ - The symptom (exact error message)
112
+ - Hypotheses tested and their results (one line each)
113
+ - Current hypothesis being investigated
114
+ - Files relevant to the current hypothesis
115
+
116
+ ### Scenario: Implementing a Feature Across Layers
117
+
118
+ You are building a feature that touches API, service, and data layers. Compact by keeping:
119
+ - The feature requirements
120
+ - Interface contracts between layers (function signatures, types)
121
+ - Which layers are done, which are in progress
122
+ - Test status for completed layers
123
+
124
+ ## Anti-Pattern Catalog
125
+
126
+ ### Anti-Pattern: Compacting Too Early
127
+
128
+ **What it looks like:** Summarizing after reading just 2-3 files, before you have a full picture of the problem space.
129
+
130
+ **Why it is harmful:** You do not yet know what is important. Early summaries miss critical context that you discover later.
131
+
132
+ **Instead:** Compact when context is more than 60% full, or when you are transitioning between major subtasks. Not before.
133
+
134
+ ### Anti-Pattern: Losing Key Decisions
135
+
136
+ **What it looks like:** Summarizing away the reasoning behind a decision, keeping only the outcome.
137
+
138
+ **Why it is harmful:** Without the WHY, you (or a future session) may revisit and reverse a well-reasoned decision, wasting time.
139
+
140
+ **Instead:** Always keep decision rationale. "Chose JWT over session cookies because the API is stateless and serves mobile clients" -- not just "Using JWT."
141
+
142
+ ### Anti-Pattern: Over-Compacting
143
+
144
+ **What it looks like:** Reducing context to a single paragraph that says "working on auth feature."
145
+
146
+ **Why it is harmful:** Too little context means you have to re-read everything, defeating the purpose of compaction.
147
+
148
+ **Instead:** Keep file paths, function signatures, decision rationale, and current task state. The summary should be 500-1000 tokens, not 50.
149
+
150
+ ### Anti-Pattern: Never Compacting
151
+
152
+ **What it looks like:** Accumulating context until the window is full and responses degrade.
153
+
154
+ **Why it is harmful:** The last 20% of the context window produces worse results. By the time you notice degradation, you have already lost quality.
155
+
156
+ **Instead:** Proactively compact when you pass 60% usage, or at natural transition points between subtasks.
157
+
158
+ ### Anti-Pattern: Compacting Active Work
159
+
160
+ **What it looks like:** Summarizing files you are still actively editing, losing the detailed state.
161
+
162
+ **Why it is harmful:** You will need to re-read those files immediately, wasting the effort of compaction.
163
+
164
+ **Instead:** Only compact information from COMPLETED subtasks. Keep active work in full detail.
165
+
166
+ ## Failure Modes
167
+
168
+ ### Summary Is Too Vague
169
+
170
+ **Symptom:** After loading the summary, you do not know which file to open or what to do next.
171
+
172
+ **Fix:** Add specific file paths, function names, and the exact next action. A good summary answers: "What file do I open first, and what do I do in it?"
173
+
174
+ ### Lost Critical Context
175
+
176
+ **Symptom:** You make a mistake that contradicts a decision or constraint from the compacted context.
177
+
178
+ **Fix:** The information is on disk -- re-read the relevant files. Then update your summary to include the missing constraint. This is recoverable, not catastrophic.
179
+
180
+ ### Summary Is Too Long
181
+
182
+ **Symptom:** The summary itself is 2000+ tokens and does not fit well as a context primer.
183
+
184
+ **Fix:** Focus on what is needed for the NEXT task, not everything done so far. Completed work can be reduced to one line per task. Only the current and next tasks need detail.
185
+
186
+ ### Rebuilt Context Drifts from Original
187
+
188
+ **Symptom:** After loading a summary and re-reading files, you reach a different understanding than before compaction.
189
+
190
+ **Fix:** Include concrete artifacts in your summary (exact function signatures, test names, error messages) rather than prose descriptions. Concrete details resist drift; abstract descriptions invite reinterpretation.
191
+
192
+ ## Compaction Checklist
193
+
194
+ Use this checklist before and after compaction to ensure quality:
195
+
196
+ ### Before Compacting
197
+
198
+ - [ ] Context is more than 60% full OR you are transitioning between major subtasks
199
+ - [ ] You have completed a logical unit of work (not mid-task)
200
+ - [ ] You are not actively debugging an error (keep full error context)
201
+ - [ ] You have identified the next task clearly
202
+
203
+ ### Writing the Summary
204
+
205
+ - [ ] Goal is stated in one sentence
206
+ - [ ] Every key decision includes its rationale (the WHY)
207
+ - [ ] Active file paths are listed with their purpose
208
+ - [ ] Current state is explicit (done, in progress, next)
209
+ - [ ] Constraints and invariants are preserved verbatim
210
+ - [ ] Summary is between 500 and 1000 tokens
211
+
212
+ ### After Loading a Summary
213
+
214
+ - [ ] You know which file to open first
215
+ - [ ] You know what action to take next
216
+ - [ ] You have not re-read files unnecessarily
217
+ - [ ] If anything is unclear, you re-read the specific source file (not everything)