Friction log
Where nodwyn-stable got in the way while building nodwyn (ADR 15). One line
per observation, newest first. Reviewed at every promotion; the top items
become side-work in the next phase.
Format: date · session · what happened · what it cost · idea
- 2026-10-12 · promotion ·
make acceptstopped atstaticcheck ./...on this Mac after Go moved to 1.27.2: the latest release, v0.8.1, reads unified export data up to version 4 and Go 1.27.2 writes 5, so the lint failed before a test ran and every promotion with it · resolved:staticcheckis atoolin go.mod run bymake lint(go tool staticcheck), pinned withgolang.org/x/toolsv0.51.0, which reads version 5; the installed analyzer no longer decides, and CI installs none (ADR 33, amended) - 2026-10-03 · chat on the worktree task (
20261003T063228Z-73791682) · a provider's 429 ended a turn with two of five plan steps marked; after "continue" the plan panel said "none recorded for this ask", the model read again and wrote the plan again, marking steps 1 and 2 a second time; later the reading reminder asked for a plan it had, and it wrote it a third time with "[done]" in the steps' text · minutes of repeated work and a plan panel that showed nothing marked · resolved: a turn that did not finish leaves its plan, with its marks, to the next message (ADR 35, amended); a turn with a plan is told to go on with it (ADR 32, amended) - 2026-10-02 · chat on the jev-key UI task, read back from its log · nothing in the log says the machine slept: a suspend eight seconds after a
shell-execcall shows as 2 h 11 min between the call and its result ints, while the result'sms(monotonic) says 20.7 s · a review took a suspend for a two-hour approval wait · record a note when the host notices a jump between wall and monotonic time - 2026-10-02 · chat on the jev-key UI task · with "allow all" off and no judge set up,
node --checkasked like any other command;.nodwyn/allow.tomllists only Go and git commands · a confirm for a read-only syntax check · decide whether syntax and lint checks belong in the list (plan.md, smaller gaps) - 2026-10-02 · chat on the jev-key UI task · Go tests and
node --checkpassed in every round while the Credentials tab went blank on a click (a localdetailshadowed the module'sdetail()); the page's browser check ran only in the fourth turn; replies called the work done on a syntax check; proposal questions left unanswered were settled silently into a dead end; a function and a field went in unused · four review rounds for one panel · resolved: the working rules check code where it runs and report what ran (ADR 32, amended); a repository's AGENTS.md joins the system prompt, and nodwyn's says how each change here is validated (ADR 36) - 2026-10-02 · console · Home offered three ways to start a task (chat, run, unattended run) plus who answers a run's requests, and the default, a chat, asked about every write and every command and stopped at soft limits (50 calls, 20 minutes, 25 actions) a long request reaches · a choice to make before every request, and confirm fatigue in the one most used · resolved: ADR 35: every console task is a chat; writes in the folder go ahead with their previous content kept, the judge answers a command before the person is asked, soft limits are off unless set;
nodwyn runstays for scripts and benchmarks - 2026-10-02 · runs and a chat on one UI task · the denylist refused
credentials.js/credentials.go, so the model worked throughbash(approved for the whole session) andgit-statushid its edits from the evidence loop; "propose first" was overridden by "No file has changed yet"; the model re-derived its design at every request since its thinking is not sent back; the explorer's findings never reached the worker; nodwyn's tests failed under nodwyn (TMPDIR in the protected data dir, no SSH agent for signing); the token budget counted cached tokens in full and paused for hours · three attempts, no usable change · resolved: code is exempt from the name globs and git-status names every file (ADR 28); a reviewed turn may end unchanged (reviewed?);plan-write; the findings are handed over (ADR 32); tests run in their own home; cached tokens count a tenth (ADR 18) - 2026-10-02 · supervised run · every turn of a run drafted a new plan for the whole task, exploring the repository again, in a context that did not show what earlier turns did, and step marks counted against that turn's plan only, while the run prompt asked for "one unfinished plan step" · the plan reset each turn, planning was paid for again each turn, and an unattended run's progress was measured against a moving target · resolved: the plan is the run's; a later turn carries it with the steps marked so far (
gate.plancarried, recipe v13) and plans again only once every step is marked - 2026-09-30 · stable install ·
make buildhas no webview tag, so a stable installed the promote way answered the desktop launcher (nodwyn-stable app, no terminal) with the browser fallback instead of a window · the app looked as if it had not started · resolved: promote buildsmake build-webview(a pkg-config shim maps webkit2gtk-4.0 to 4.1) and refuses an installed binary without-tags=webview; without WebKitGTK it installs the browser build and says so - 2026-09-27 · SWE-bench harness · output was never capped: window.output_reserve only sized the context, and Qwen thinking bursts reached 17k tokens (0.2% of replies over 8k), enough to overflow a context sized to the window · a prompt at high water plus a long reply could be cut by the server · resolved: output_reserve (16k by default) caps every reply (num_predict / max_completion_tokens, recipe v8); a cut reply is noted, and ask-model asks again, briefer, at most twice
- 2026-09-27 · SWE-bench harness · a run whose strategy redefined agent-turn got no plan once the gate moved into Scheme, so its first write was refused; and the planner was offered every tool, so a tool-call answer counted as no plan · every custom strategy broke under
nodwyn run· resolved: the host runsnodwyn-turn(then namedturn), which plans first in a run whatever agent-turn is; the planner is asked with no tools (model-turnoptions, recipe v7) - 2026-09-27 · SWE-bench harness · a turn that ended on a folded reviewer's reply was recorded as limited, not completed · run statuses misreported · resolved: completion is judged by the reply the conversation still shows (5f4cdd9)
- 2026-09-27 · SWE-bench harness · the planner once answered with thinking only, and a run requires a nonempty plan, so the task ended before any work · one benchmark task in about 85 lost outright · resolved: an empty draft is asked for again up to twice, noted in the log; an empty revision keeps the best plan
- 2026-09-27 · SWE-bench tuning · writes to /tmp were refused, so the model put throwaway scripts in the repository or wrote them through the shell · stray files in the patch, and turns spent working around the pin · resolved: each session has a scratch directory outside the repository, writable without prompts and TMPDIR for commands (ADR 28)
- 2026-09-26 · SWE-bench harness · L1 took any three dot-joined words of 8+ characters for a JWT, so Django test labels such as
model_fields.test_jsonfield.TestQueryingwere secrets: shell-exec denied the test runs, and a judge request quoting one was refused as an unbound secret, which ended the turn · two of fifteen Jev-verify tasks lost outright, and denied test commands in two other variants · resolved: a JWT must start with an encoded JSON header and payload (eyJ….ey…) - 2026-09-26 · SWE-bench harness · the model sent whole command lines as shell-exec's cmd ("python3 -m pip", "cd /testbed && git log"), and exec answered only "not found" · about 4% of shell calls failed and cost the model a turn to recover · resolved: such a failure now says how to split cmd and args, and names sh -c for pipes
- 2026-09-26 · SWE-bench harness · the manual said
nodwyn run start, but only status/stop/resume were subcommands, so the documented command failed with a usage error · a harness wired from the manual could not start runs · resolved:nodwyn run startis accepted as the explicit form ofnodwyn run - 2026-09-26 · SWE-bench harness · Qwen occasionally wrote tool-call markup the server's parser rejected, even in the planner's tool-less request, and one failed request ended the whole turn · whole benchmark tasks lost to one bad sample · resolved: a failed model request is retried twice with backoff, each failure logged as a note
- 2026-09-26 · Jev setup ·
:eval (credential-register "jev-key"), the documented way to add the judge's key, hung with nothing on screen: plain chat drained events only after Eval returned, so the masked prompt was never shown · the judge could not be set up from plain chat · resolved: :eval renders events and answers prompts while it runs - 2026-09-26 · SWE-bench harness · model requests ignored HTTPS_PROXY, so a sandbox whose only egress is an allowlist proxy reached the judge but not the model · nodwyn could not run in the harness at all · resolved: both model clients use http.ProxyFromEnvironment
- 2026-09-26 · routing · a strategy could only ask the one control model, and any model it asked got the whole conversation · routing an implementation to the right model, or escalating to a stronger one, was impossible as user code · resolved: configured models asked by name, and
narrow-context/widen(ADR 27); the routing behaviour is a userland test - 2026-09-26 · loop policy · a plan cycle written as user code could not reach a keyed judge (Scheme had no way to get a stored key's handle) and could not speak to a model that stopped with steps left · judges and step-keeping were only possible as Go features · resolved:
credentialandadd-message; internal/core/userland_test.go keeps the plan cycle as user code - 2026-09-26 · loop policy · changing how a turn goes (plan first, check with the judge, stop a batch at its first failure) meant editing
internal/loopin Go · every experiment with a model or judge was a rebuild and a promotion · resolved: the loop is a Scheme procedure,agent-turn, over three primitives that keep the invariants (ADR 26, docs/scheme.md §9) - 2026-09-26 · benchmarks ·
nodwyn runcould not complete unattended at all: a run's first write raised a confirm that waited for a client, so the budget killed it · supervised runs unusable without a human watching, which is the opposite of their purpose · resolved:run.starttakesauto_approve, exposed asnodwyn run start --yolo; the keychain lives in the daemon so a run has credentials without a passphrase prompt - 2026-09-26 · benchmarks ·
--no-confirmanswers every confirm with no, which is right for CI and useless for a harness that must actually edit and run things; there was no unattended mode at all · SWE-bench and any test rig blocked · resolved:--yoloanswers ordinary confirms yes and leaves every denial and every security confirm alone - 2026-09-26 · authoring · a multi-line instruction or tool description had to be written as one escaped line · prose in a program read badly enough that nobody wrote any · resolved:
"""…"""raw strings with indented-block dedent (docs/scheme.md §1.1) - 2026-09-25 · browser console · the UI was unpleasant to use and to look at: no dark mode at all, ~220px of chrome before any content, prose running the full window width, telemetry as loud as the answer, a 100px card per tool call hiding both arguments and result, four-line sidebar rows repeating the repo path, and the same hint shown twice · every session read worse than the plain front-end · resolved: dark-first operator console — one token set with a real light peer, thin chrome, turn-grouped transcript, one-line tool rows carrying verdict, size and duration, approvals with the buttons above the fine print
- 2026-09-25 · terminal client · every tool call dumped its indented arguments and its whole result into the transcript, so one 13 kB file read buried the conversation · scrolling past tool output to find the answer · resolved: compact one-line tool rows,
:detailstoggles the bodies, session rows keep a reserved meta column - 2026-09-22 · P10 summaries · older context had only irreversible sticky omission markers · external-agent implementation under ADR 16; actual provider requests tested before/after summary revocation and the real v1 fixture preserved · reviewed summaries are now source-bound log entries; revocation rebuilds from source without reviving superseded caches
- 2026-09-22 · P10 replay foundation · historical logs omitted the system prompt, tool schemas and window recipe needed to prove exact reconstruction · external-agent implementation under ADR 16; actual provider requests compared across resume and elision · record the recipe once per runtime and verify request digests before introducing revocable summaries
- 2026-09-22 · P9 parity audit · temporary approval changes were persisted but omitted by the TUI transcript · external-agent implementation under ADR 16; local/RPC scope and process-lifecycle coverage mapped in the TUI guide · render attributed approval requests and complete the line-mode flow acceptance matrix
- 2026-09-22 · persistent binding approval · new destinations required manual TOML editing and session restart · external-agent implementation under ADR 16; local/RPC, concurrent persistence, cancellation and reload checks · prompt-derived exact rows now persist on explicit consent; invalid policy denies and deletion removes authority
- 2026-09-22 · fixed Jev scope · host-only metadata skipped method and position authorization · external-agent implementation under ADR 16; all three primitives tested against mismatched bindings · require POST and header:Authorization:Bearer before transport
- 2026-09-22 · P9 egress confirmations · unbound credential prompts lacked explicit method and position; Jev still omits these fixed facts from guard metadata · implemented with an external agent under ADR 16, with local/RPC canary coverage · show exact available facts and explicit omissions before adding any binding-writing operation
- 2026-09-22 · P9 plan/budget views · implemented with an external agent under ADR 16; local/RPC and terminal checks exercise configured limits, a real checkpoint stop, history isolation and gate-score labels · no claim of nodwyn self-authorship · inspect recorded planning and budget decisions without treating snapshots as live usage
- 2026-09-22 · P9 tool-call presentation · implemented with an external agent under ADR 16; local/RPC and terminal checks cover nested guards, a declined write, history reconstruction, reused IDs and canary redaction · no claim of nodwyn self-authorship · tool results are readable beside their arguments and recorded decisions instead of only a byte count
- 2026-09-22 · P9 tool discovery · implemented with an external agent under ADR 16; local/RPC tests cover initialization tools, schemas, safe rendering and inspection without execution · no claim of nodwyn self-authorship · inspect the model-facing catalog and use familiar plain-mode command aliases without leaving the TUI
- 2026-09-22 · composer promotion · the live model returned READY, but selfcheck replayed a newer unrelated session from the shared store · stable swap correctly stopped · select the ID printed in the selfcheck session banner; regression coverage includes a newer unrelated session
- 2026-09-22 · P9 composer · implemented with an external agent under ADR 16; local/RPC tests and real terminals cover multiline Scheme comments, bracketed paste, resize and separate approval/secret input · no claim of nodwyn self-authorship · pasted newlines no longer collapse, and prompts/reconnects preserve unsent drafts
- 2026-09-22 · P9 inspectors · implemented with an external agent under ADR 16; local/RPC tests cover fixed history snapshots, isolated bindings, prompt priority and denied friction reads · no claim of nodwyn self-authorship · log, replay, loaded policy and friction can be inspected without leaving the TUI or bypassing the guarded read path
- 2026-09-22 · P9 first client · implemented with an external agent under ADR 16; real-socket, local-session, masked-canary, cancellation and PTY checks exercise the new frontend · no claim of nodwyn self-authorship · scrollable approvals and resumable daemon attachment now work in a terminal; inspectors and richer composing remain
- 2026-09-22 · U2 turns/events · implemented with an external agent under ADR 16; fake-model and real-socket tests cover reconnect gaps, waiting prompts, slow clients, abort and close · Busy could become false before final idle delivery, so close now waits for completion · approval replies remain the next slice
- 2026-09-22 · U2 lifecycle · implemented with an external agent under ADR 16; real-socket tests cover disconnected clients, concurrent resume, private permissions, writer locks and process shutdown · no claim of nodwyn self-authorship · daemon sessions can be owned independently of a terminal; turn/event RPC is the next slice
- 2026-09-22 · ADR 18 budgets · implemented with an external agent under ADR 16; focused tests cover nested host effects, custom choices, denial accounting, cancellation, deadlines, redaction and replay · no claim of nodwyn self-authorship · long supervised turns now checkpoint before exhausting hard ceilings
- 2026-09-22 · CI validation · archive cache restore cannot overwrite existing read-only Go module files on the self-hosted runner · warning and redundant archive work despite passing tests · disable Actions archive caching and reuse the runner's normal local Go caches; extract tool archives without restoring build-machine ownership
- 2026-09-22 · ADR 18 progress guard · implemented with an external agent under ADR 16; fake-service tests cover repeated calls, denied retries, error streaks, skipped batch results and fresh turns · no claim of nodwyn self-authorship · stops unproductive turns before consuming the full hard budget
- 2026-09-22 · Gitea CI · configured by an external agent under ADR 16; the self-hosted runner's image differed from the hosted one · the manual-only workflow did not establish a gate · run fresh acceptance checks and all four portable build targets for every push
- 2026-09-22 · U1 resume · implemented with an external agent under ADR 16; tested CLI restart, process kill after a real tool write, legacy redaction, partial-tail recovery and exclusive ownership · no claim of nodwyn self-authorship · conversation survives restart; ephemeral approvals and Scheme state deliberately reset
- 2026-09-22 · readability refactor · implemented with an external agent under ADR 16 after reviewing the spec and roadmap; acceptance and fresh race tests passed · no claim of nodwyn self-authorship · preserve shared credential and integration boundaries while simplifying the code inside them
- 2026-09-22 · P7 · implemented with an external agent under ADR 16, validated with the candidate selfcheck · no claim of nodwyn self-authorship · model output is now buffered because per-token redaction cannot safely recognize split credentials
- 2026-09-22 · P6 · the doc-coverage test caught three undocumented builtins before they could ship · nothing, it failed the build · ADR 7's mechanical rule keeps paying for itself
- 2026-09-22 · P5 review · the Jev client and its fake agreed on a protocol that does not exist; every test passed · a phase that would have failed on first contact with the API · rule for external APIs: fetch the docs and pin the wire shape in the fake's comments before writing the client
- 2026-09-22 · U2 approvals and eval · implemented with an external agent under ADR 16; Unix-socket tests cover peer attribution, explicit scopes, secret containment, cancellation and schema drift · no claim of nodwyn self-authorship · clients can now complete prompted turns and register credentials without blocking their reply connection; turn-wide write trust no longer bypasses security confirmation
- 2026-09-22 (external agent, ADR 16): searching through general shell commands required broad command approvals;
index-grepnow performs bounded ripgrep retrieval with every selected content read passing the existing guard. Tree-sitter symbols remain separate work. - 2026-09-22 (external agent, ADR 16): source outlines previously needed whole-file context or shell tools;
index-symbolsnow returns guarded Tree-sitter definitions for Go, JavaScript and Python without runtime downloads or a native build toolchain. (Removed 2026-09-27 with its vendored grammars.) - 2026-09-22 (external agent, ADR 16): the daemon had no browser view of saved/live work; U3 now has a paired read-only session/transcript desk with guarded transport boundaries. Interactive approvals remain the next slice.
- 2026-09-22 (external agent, ADR 16): testing the guarded browser friction view exposed an evaluation-result redaction gap: Scheme newline escaping could hide a known secret's token boundary. Session evaluation records and plain chat evaluation displays now scan string leaves before quoting, including nested pairs and vectors; evaluation values remain unchanged. Synthetic canary tests cover frontend events, history, persisted output and linked redaction audits.
- 2026-09-21 · P3 session (766 messages) · every request re-prefilled 82–96K tokens (40–48 s) — the window sat at budget and elided the next-oldest live entry each request, and a big result ageing out of the protected tail un-elided earlier ones · ~40 s of prefill per tool call · resolved: sticky elision from the log, high/low-water hysteresis, result caps, task block in the system prompt (ADR 9 amendment)
- 2026-09-21 · daily use · a pasted prompt longer than 1024 characters was silently truncated — the terminal's canonical-mode line limit, not nodwyn's · long task descriptions could not be pasted · resolved: the plain front-end reads prompt lines in raw mode with x/term's editor (bracketed paste, no length limit); pipes still use the scanner
- 2026-09-21 · daily use · a
yper edit, four to fifteen per task, makes the confirm a reflex · every diff skimmed, none read · resolved: standing write approvals by path prefix (writesin allow.toml,aat a write prompt) andt= all writes this turn; the diff is logged and shown dimmed instead of prompted (ADR 17 amendment) - 2026-09-21 · selfhost run 1 · no way to resume a session after a crash or
:q; the log has everything but the window is not rebuilt from it · a crash mid-task loses the conversation ·nodwyn --resume <id>that resolved in U1: reloads the conversation from its log without replaying tool operations - 2026-09-21 · selfhost run 1 · a 27B model told to change one line
rewrote a 400-line file with
fs-writeand mangled an unrelated line, then spent 10shell-execcalls (sed, python3 -c) repairing it · 15 confirms and ~25 minutes for a 9-line change · resolved the same day:fs-edit(exact, unique, old→new with a diff preview). Re-run of the same task: 4 confirms, 10 tool calls, clean diff - 2026-09-21 · selfhost run 1 · the model wrote
/fix.py(absolute path); the repo pin denied it, it then wrote_tmp_fix.pyinside the repo andrm'd it after · two confirms for scaffolding that should not exist · gone withfs-edit; keep an eye on "helper script" patterns - 2026-09-21 · B2 smoke · every
go testthroughshell-execprompted · a prompt per test run makes "y" a reflex · resolved in B3: standing approvals (.nodwyn/allow.toml,aanswers), ADR 17 - 2026-09-21 · B2 smoke · cold prompt eval of a small prefix took 13 s (another client had the slot); warm turns are 0.2–0.5 s · none once warm · nothing to do; ADR 9 holds