Commit Β·
bfc60f2
1
Parent(s): 0bce5fd
Fix dict iteration crash in neuro_foundation + harden QB spec workflow
Browse filesneuro_foundation.py: snapshot self.synapses before iteration in step()
and _prune_synapses() β concurrent writes were causing RuntimeError on
dictionary changed size during iteration.
system_prompt.py: Step 1 now explicitly blocks Step 2 (no exceptions);
Step 2 grep template adds --exclude-dir=venv --exclude-dir=.git to
prevent 60s timeout scanning venv/. Both issues observed in QB #126 run.
app.py: defensive list() copies for history/pending_proposals state.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- app.py +2 -2
- neuro_foundation.py +2 -2
- system_prompt.py +12 -4
app.py
CHANGED
|
@@ -341,8 +341,8 @@ def _build_api_messages(history: list, system_prompt: str) -> list:
|
|
| 341 |
# ---------------------------------------------------------------------------
|
| 342 |
|
| 343 |
def agent_loop(message: str, history: list, pending_proposals: list, uploaded_file) -> tuple:
|
| 344 |
-
safe_hist = history or []
|
| 345 |
-
safe_props = pending_proposals or []
|
| 346 |
|
| 347 |
if not message.strip() and uploaded_file is None:
|
| 348 |
return (safe_hist, "", safe_props, _format_gate_choices(safe_props),
|
|
|
|
| 341 |
# ---------------------------------------------------------------------------
|
| 342 |
|
| 343 |
def agent_loop(message: str, history: list, pending_proposals: list, uploaded_file) -> tuple:
|
| 344 |
+
safe_hist = list(history or [])
|
| 345 |
+
safe_props = list(pending_proposals or [])
|
| 346 |
|
| 347 |
if not message.strip() and uploaded_file is None:
|
| 348 |
return (safe_hist, "", safe_props, _format_gate_choices(safe_props),
|
neuro_foundation.py
CHANGED
|
@@ -1893,7 +1893,7 @@ class Graph:
|
|
| 1893 |
if self.config.get("three_factor_enabled", False):
|
| 1894 |
trace_tau = self.config["eligibility_trace_tau"]
|
| 1895 |
trace_decay = math.exp(-1.0 / trace_tau) if trace_tau > 0 else 0.0
|
| 1896 |
-
for syn in self.synapses.values():
|
| 1897 |
if abs(syn.eligibility_trace) > 1e-12:
|
| 1898 |
syn.eligibility_trace *= trace_decay
|
| 1899 |
|
|
@@ -2757,7 +2757,7 @@ class Graph:
|
|
| 2757 |
initial_w = self.config["initial_sprouting_weight"]
|
| 2758 |
|
| 2759 |
to_prune: List[str] = []
|
| 2760 |
-
for sid, syn in self.synapses.items():
|
| 2761 |
age = self.timestep - syn.creation_time
|
| 2762 |
|
| 2763 |
# Weight-based pruning
|
|
|
|
| 1893 |
if self.config.get("three_factor_enabled", False):
|
| 1894 |
trace_tau = self.config["eligibility_trace_tau"]
|
| 1895 |
trace_decay = math.exp(-1.0 / trace_tau) if trace_tau > 0 else 0.0
|
| 1896 |
+
for syn in list(self.synapses.values()):
|
| 1897 |
if abs(syn.eligibility_trace) > 1e-12:
|
| 1898 |
syn.eligibility_trace *= trace_decay
|
| 1899 |
|
|
|
|
| 2757 |
initial_w = self.config["initial_sprouting_weight"]
|
| 2758 |
|
| 2759 |
to_prune: List[str] = []
|
| 2760 |
+
for sid, syn in list(self.synapses.items()):
|
| 2761 |
age = self.timestep - syn.creation_time
|
| 2762 |
|
| 2763 |
# Weight-based pruning
|
system_prompt.py
CHANGED
|
@@ -1,4 +1,10 @@
|
|
| 1 |
# ---- Changelog ----
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
# [2026-04-16] Claude (Sonnet 4.6) β Add WorkBlockSpec generation section
|
| 3 |
# What: _build_spec_generation_section() added; included in build_system_prompt().
|
| 4 |
# Why: Teaching QB to generate its own specs. Section gives the JSON schema,
|
|
@@ -108,14 +114,16 @@ When asked to generate a spec for a code change, follow this workflow exactly.
|
|
| 108 |
Do not skip steps. Do not draft the spec before completing Steps 1 and 2.
|
| 109 |
|
| 110 |
### Step 1 β Verify current code state
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
-
|
| 114 |
-
-
|
|
|
|
| 115 |
- If the problem no longer exists, report that and stop. Do not write a spec for a closed item.
|
| 116 |
|
| 117 |
### Step 2 β Check callers
|
| 118 |
For every function or method being modified, grep the full repo for callers.
|
|
|
|
| 119 |
The scope of a change includes every call site. A spec that fixes the function
|
| 120 |
but leaves callers using the old API is broken. Find them all before drafting.
|
| 121 |
|
|
|
|
| 1 |
# ---- Changelog ----
|
| 2 |
+
# [2026-04-17] Claude (Sonnet 4.6) β Harden spec workflow: Step 1 blocks Step 2, venv exclusion
|
| 3 |
+
# What: Step 1 now explicitly states "do this before Step 2, no exceptions"; added venv/git
|
| 4 |
+
# exclusion pattern to Step 2 grep template. Both from QB #126 test run observation.
|
| 5 |
+
# Why: QB skipped read_file (Step 1) and jumped to grep (Step 2), missing line number drift.
|
| 6 |
+
# grep also timed out scanning venv/ β 60s limit hit on every broad search.
|
| 7 |
+
# How: Reworded Step 1 lead-in; added --exclude-dir=venv --exclude-dir=.git to Step 2 example.
|
| 8 |
# [2026-04-16] Claude (Sonnet 4.6) β Add WorkBlockSpec generation section
|
| 9 |
# What: _build_spec_generation_section() added; included in build_system_prompt().
|
| 10 |
# Why: Teaching QB to generate its own specs. Section gives the JSON schema,
|
|
|
|
| 114 |
Do not skip steps. Do not draft the spec before completing Steps 1 and 2.
|
| 115 |
|
| 116 |
### Step 1 β Verify current code state
|
| 117 |
+
**Do this before Step 2. No exceptions.**
|
| 118 |
+
Use read_file on every target file named in the task description.
|
| 119 |
+
- Read the actual file. Do not assume the punchlist line numbers are correct β they drift as files change.
|
| 120 |
+
- Identify where the described problem actually lives in the current code.
|
| 121 |
+
- Use shell_execute with `grep -c 'pattern' file` to count exact occurrences.
|
| 122 |
- If the problem no longer exists, report that and stop. Do not write a spec for a closed item.
|
| 123 |
|
| 124 |
### Step 2 β Check callers
|
| 125 |
For every function or method being modified, grep the full repo for callers.
|
| 126 |
+
Always exclude venv and generated directories: `grep -r 'pattern' . --include='*.py' --exclude-dir=venv --exclude-dir=.git`
|
| 127 |
The scope of a change includes every call site. A spec that fixes the function
|
| 128 |
but leaves callers using the old API is broken. Find them all before drafting.
|
| 129 |
|