Status: resolved 2026-02-22.
When the LLM writes a note containing a codeblock with Python code that uses double-quoted strings, it sometimes encodes the double quotes as \\" (two backslashes + bare quote) instead of the correct \" (single backslash + quote). This produces invalid JSON that previously fell back silently to an old-style text note, causing double-encoding on the next read and breaking note re-use across runs.
After a coding run, the note stored at e.g. projects/JSONHTL-HTML-converter/code had type=text (old-style). Reading it back required a character-walk extraction because json.loads() failed mid-string at every occurrence of a double-quoted Python string literal in the codeblock body.
Symptom in the log: note reads succeeded but the extracted code was truncated. Symptom in use: json.JSONDecodeError with 'Expecting , delimiter' or 'Expecting value' mid-string.
• NoteWrite.value is typed as str in the Pydantic schema, forcing the LLM to double-encode JSONHTL as a JSON string. Codeblock bodies with nested double quotes require triple-encoding, which the LLM sometimes gets wrong.
• notes_client.write_doc() previously had a silent fallback: if json.loads failed it stored the raw string as an old-style text note. This masked the error.
1. _parse_note_value(key, value) added to orchestrator.py. Tries direct parse, then regex repair (re.sub(r'\\\\\\"', r'\\"', value)), then raises ValueError. Never silently downgrades.
2. notes_client.write_doc() changed to raise ValueError on parse failure instead of wrapping in old-style text note.
3. Instruction notes updated: envoy/start and envoy/states/coding now explicitly tell the LLM to prefer single-quoted Python strings in codeblock bodies to avoid the escaping problem.
In codeblock bodies, prefer single-quoted Python strings (escape(href + '.html')) over double-quoted ones (escape(href + ".html")). Single quotes require no escaping in the JSON body and eliminate the problem entirely.
Long-term: consider changing NoteWrite.value from str to a JSON object type in the schema, eliminating the double-encoding requirement entirely. Blocked by OpenAI strict-mode additionalProperties constraint on flexible object schemas.