Local invocations answer ACP permission prompts automatically. The
handler picked the "allow" option for every request, ignoring whether the
turn was read-only, so a read-only discussion participant (for example
Hermes running with command approval prompts) had edit, delete, move,
command execution and mode-switch requests approved.
Read-only turns now approve only side-effect-free tool kinds (read,
search, fetch, think) and refuse everything else, including requests
without a recognised kind. Writable turns and the explicit Human Gate
mode are unchanged.
Checks: new local-workspace-permission-policy tests (read-only refusal
matrix, writable approval). Full desktop suite: 1537 pass.
The natural discussion prompt told the owner "another reviewer is
optional", told every Agent it "may finish with nextKinds: []", and showed
a receipt example with empty nextKinds and deliverables. Proposals were
told to "engage with peers" although they run independently; sequential
discussions advertised routing that the code ignores; and the response
scope pointed at an "authoritative" label that natural prompts never
show. Agents therefore rarely requested each other and discussions
collapsed into one owner turn.
- Proposals: say peers answer independently and will be discussed next
round. Discussion turns: respond to peers' specific points, dispute
with reasons, build on their work; end every turn with the receipt.
- Owner: before completing, make sure the relevant peers reviewed the
actual deliverables, otherwise request them with a concrete question.
- Peers: answer the points raised; blocked or needs-human goes to the
owner, who decides.
- Routing: list every peer whose input is needed and ask them a concrete
question; the receipt example names a real peer and shows the completed
form with deliverables.
- Sequential discussions no longer advertise routing and instead say the
next participant runs after this invocation ends.
- The response scope refers to "the current user task stated above".
Checks: local-workspace natural discussion, natural writer, delivery,
transcript, context-pack and harness suites (152 pass). Full desktop
suite: 1532 pass.
Automatic group discussions (the production auto path) ended as
"partial" for reasons that had nothing to do with the task:
- any receipt whose nextKinds named an absent or paused Agent stopped the
whole discussion with "no valid task completion decision";
- a peer's blocked or needs-human status ended the run on the spot,
although only the delivery owner judges the task;
- an owner who failed, was paused, or handed off to an absent Agent ended
the run silently;
- one missing owner receipt stopped the run without asking again;
- strict receipt and taskDecision grammar failed the Agent's whole turn
for "Done", an @handle, a single string instead of a list, a trailing
comma or code fence, an extra key, or a long summary, and the failed
Agent was then excluded from the discussion.
Now absent recipients are dropped with a notice and valid requests still
run; a peer blocker is forwarded to the owner, who decides; the next
active selected Agent takes over ownership with a notice; an ignored
handoff keeps the current owner; an owner without a readable decision is
asked once more and the run stops only after two undecided owner turns;
completing without stopped participants explains why the run is partial.
Discussion receipts are normalised (status synonyms, @handles, case,
lists, smart quotes, trailing commas, closing fences, extra keys, missing
summary) before the strict parser runs, and an unreadable decision is
treated as no decision instead of failing the turn. Phased-V4 receipts
keep their strict contract. New zh/en notices explain each case.
Checks: natural discussion, natural writer, receipt, task-decision and
human-gate recovery suites (99 pass on this tree, including a new fenced
loose-receipt test and updated tests for the new routing, blocker and
handoff behaviour); npm --prefix frontend test (330). Full desktop suite
with the following prompt commit: 1532 pass.
The test used a 100 ms initialize timeout for both turns. Under a loaded
full-suite run the healthy second fake-Agent process also needed more than
100 ms to start, so it fell back too. Only the first process hangs; the
second turn now uses the default timeout.
Checks: the lifecycle test passes three runs in a row.
No message carried a turn order. The timeline rebuilt one from round,
phase, the Agent's current position in the group and the save time, and
those disagreed:
- live bubbles had numeric startedAt, which Date.parse turns into NaN, so
every running Agent was pinned under the user message and the list
reshuffled each time a reply was saved;
- manual concurrent mode wrote failure notices before the barrier
committed successful replies, so failures always rendered first;
- round-less notices sorted after every round, the 'discussion' phase
had no rank, and editing the group reordered history;
- natural proposals were saved in completion order and peers read the
transcript in that order, unlike what the user saw.
Now every group topic message gets a per-topic turnSeq. Batch
dispatchers (manual concurrent replies, natural proposal and discussion
batches) reserve numbers in slot order before dispatching; other turns
reserve at invocation start; failure and stop notices take their turn's
number; other topic messages take the next number when written. The
harness exposes the number on live Agent runs, so a live bubble and the
reply that replaces it share one position. Numbers are derived from saved
messages after a restart (no ledger or journal field changes). The
renderer sorts group topics by turnSeq with one shared rule for the
timeline and the trace panel; older history keeps its saved chronological
order. A failed attempt whose retry was already saved no longer lingers
as a ghost bubble, and peers read turns in dispatch order.
Checks: new local-workspace-turn-order tests (slot order with a failing
middle Agent and reversed completion; numbering continues after restart;
none on direct chats), natural discussion, manual durability and write
scheduling tests (63 pass on this tree); npm --prefix frontend test
(330 pass, including a new conversationOrdering spec and a
production-shaped live round test). Full desktop suite on the combined
tree: 1529 of 1530, the remaining failure being the ACP timing test fixed
in the next commit.
Persistent ACP runtimes (Hermes, Kimi, MiMo, OpenCode) were fragile:
- any turn error, including a user stop or watchdog timeout, destroyed
the process and its native session; Hermes rejects cross-process
resume, so the conversation then fell back to the silent legacy CLI;
- the process identity hashed the whole child environment, so a fresh
login-shell PATH (fnm uses a per-shell directory) restarted the process
and invalidated the stored session;
- initialize had no timeout and ignored stop while holding the
conversation lock, leaving that Agent stuck until the app restarted;
- stderr kept the first megabyte of the process lifetime, so new
failures were classified from stale lines.
Now a stopped or timed-out turn waits up to 3 s for the Agent to answer
the cancelled prompt and keeps the process and session when it does;
volatile shell values (PATH, TERM, TMPDIR, fnm variables, ...) no longer
change the process identity; initialize times out after 60 s (settable
per call) and honours stop without falling back; stderr keeps only the
current turn's last 64 KB. Disposable runtimes still close after every
turn.
Checks: cli-native-acp-lifecycle with three new fake-ACP tests (hanging
initialize releases the lock, a cancelled turn reuses one process and
session, a changed PATH keeps the process), plus the existing lifecycle,
adapter and protocol suites (185 pass). Full desktop suite: 1528 pass.
Group runs gave an Agent three minutes to produce a mapped runtime event,
and only mapped events lifted that deadline. ACP agent_thought_chunk was
mapped to nothing, so Hermes, Kimi, MiMo, OpenCode and OpenClaw were
killed while thinking, and auto mode never retries timeouts. The 3/5
minute inactivity windows also cut off real builds and slow providers.
- Any sign of life (stdout/stderr bytes, ACP traffic) now lifts the
startup deadline. In automatic discussions a separate no-progress cap
(three inactivity windows) still stops CLIs that only emit heartbeats,
so a stalled participant cannot block the round; manual and direct
turns keep running while the process is active.
- Defaults are 10 minutes of inactivity and 20 minutes while a tool runs.
- ACP thinking is reported as a text-free reasoning status event
(running, then completed when the answer starts); the private thought
text never leaves the main process.
Checks: local-workspace-harness (74, including a new slow-starting Agent
test that failed with the old hard deadline, and the existing
heartbeat-only stop test), cli-adapters and cli-adapters-agent-protocols
(event order now includes the reasoning status). Full desktop suite:
1528 pass.
Several codes that end an Agent turn or a whole run had no translation,
so the timeline showed a generic error or the raw code (for example
LOCAL_RUN_PERSIST_FAILED), and users could not tell why a discussion
stopped. The round-limit notice also claimed "no consensus" although
natural discussions have no consensus step.
- Map access-denied, session-invalid, output-limit, send-failed,
refused, permission race, version/capability/protocol mismatch,
task-decision and receipt errors, context overflow, persistence
failures and the circuit breaker to zh/en messages.
- The round-limit notice now says the latest replies are the current
result and how to continue (backend fallback text updated too).
Checks: npm --prefix frontend test (325 pass); updated assertions that
expected the raw code and the old round-limit wording.
eb2234b stopped switching Hermes to its legacy transport for image
attachments to preserve the ACP session, but the ACP runner only sends a
text block, so images reached Hermes as nothing at all (the adapter test
for this failed on bb55fad).
Hermes 0.21.5 advertises promptCapabilities.image during initialize. The
runner now keeps the initialize capabilities, and when an ACP spec
carries imageAttachments it sends them as ACP image content blocks
(png/jpeg/gif/webp, up to 10 MB each) on the same session. An Agent that
does not advertise image prompts fails before prompting, so the existing
setup fallback uses the legacy transport with its --image argument.
Checks: cli-adapters (Hermes invocation spec) and a new
cli-native-acp-lifecycle test with fake Hermes ACP agents covering the
image-capable path and the legacy fallback. The capability response was
verified against the locally installed Hermes 0.21.5 with an
initialize-only handshake (no session or model call).
Commit 9198bf6 made direct chats send only the latest message text and
rely on the native session. After 1c9aabb a rebuilt session received the
continuation text instead, and that text deliberately excludes the
latest user message, so the Agent never saw the request it was answering.
Direct prompts also lost the deliverable contract (.meldwork-output/),
the read-only media warning, staged attachment paths, and regeneration
and recovery instructions, which is why generated files were not
captured and three media tests failed on bb55fad.
- New directPromptFor() leads with the user's own words. A new or rebuilt
native session gets the earlier conversation plus "Current request:";
a resumed session gets the request alone. The full delivery and
language contract is sent once per native session, a one-line reminder
afterwards. Staged inputs, recovery and regeneration instructions are
appended again.
- The shared deliveryContract() is used by group and direct prompts.
- Isolated (task-graph) invocations again neither resume nor persist the
conversation's native session (3ce8ee4 made them resume it, breaking
the "approved prompt only" contract).
- The current task is no longer cut to 6,000 characters, and longer
messages no longer fail every turn with
LOCAL_RUN_REQUIRED_CONTEXT_OVERFLOW: submitted messages are already
capped at 20,000 characters, so the full request is delivered.
Checks: local-workspace-harness (73) and local-workspace-context-packs
(15) pass on this tree, plus the direct, media and custom-label tests in
local-workspace and native-streaming (18), five of which failed on
bb55fad.
The merged branches disagreed on authentication failures: feature/1.0.5
marked every runtime auth failure 'unknown' so readiness never flipped,
while main's 22f811c classified any auth-looking diagnostic as
LOCAL_AGENT_AUTH_REQUIRED. Together with broad regexes (a bare
"forbidden" anywhere, a credential regex matching "login" or "403"),
proxy refusals stopped Agents while real sign-outs left them "ready".
- New pure module runs/failure-signals.cjs classifies CLI text:
explicit sign-in or API-key statements are definitive; line-leading
403/forbidden/unauthorized and permission_error are ambiguous; tool
output that merely mentions 403 is neither. It also recognises rate
limits (with Retry-After hints), network failures, provider 5xx and
context overflow.
- Definitive failures stay LOCAL_AGENT_AUTH_REQUIRED and now mark the
credential 'missing' (the catalog clears it after the retry window or
when native credentials verify). Ambiguous refusals become
LOCAL_AGENT_ACCESS_DENIED, are retried once, and never touch readiness.
- Process failures whose diagnostics show throttling, network loss or a
provider outage are retried in that category. Rate limits honour
Retry-After up to 60 s and wait at least 2 s without a hint.
- A resumed session that no longer fits the model context is classified
as LOCAL_AGENT_SESSION_INVALID so the existing fresh-session retry
rebuilds it; Rust panics and JSON parse errors no longer discard a
healthy session.
- Automatic retries no longer re-run the whole Agent catalog refresh
before each attempt, which flipped busy Agents to unavailable.
Checks: failure-signals (new), failure-policy, cli-process-support,
cli-adapters-agent-protocols, agent-runtime-contract and the auth/retry
tests in local-workspace and local-workspace-auto pass on this tree,
including three readiness tests that failed on bb55fad.
An authentication or compatibility failure in an automatic discussion
called removeAgent, which rewrote and persisted group.agentKinds. One
proxy 403 or expired OAuth refresh made the Agent disappear from every
later turn of that group, and when the last member was removed the group
could no longer load: normalizeLoadedGroup rejects an empty member list,
so the next start silently dropped the group together with all of its
messages.
- The auto runner now pauses a failed Agent only for the current run.
Group membership is never edited; the run-scoped exclusion already
persisted in orchestration activeKinds keeps resume behaviour intact.
- The notice says the Agent is paused for this discussion, with the
failure reason, and stays in the group (system.agentPausedAfterFailure,
zh/en). The removal notice text is kept so history still renders.
- removeAgent refuses to remove a group's last member.
- Loading rebuilds an emptied group's members from the Agents that
replied in it instead of dropping the group and its history.
Checks: node --test local-workspace-state.test.cjs (3 pass, including a
new recovery test) and the membership tests in
local-workspace-auto.test.cjs. Two tests there that also expect a
'missing' credential state stay failing until the next commit (they
already failed on bb55fad).
Commit 6aef211 added temporary icon exports, two large PNG screenshots
and a confirmation.json backup to the repository root. AGENTS.md forbids
placing screenshots and temporary files there and nothing references
them.
Checks: rg found no references to the removed paths.
Bring main's 22f811c (auth classification from errors[], OpenClaw runtime
scope per CLI version, full participant round and cross-review gate for
natural discussions) and eac015d (removal of the managed shared Provider)
into the V1.0.5 branch before the stability work.
Conflict resolution:
- local-workspace-agent-catalog.cjs: keep feature's guard that an
'unknown' runtime credential does not downgrade an authenticated Agent;
drop the provider-credential-unavailable clause removed on main. The
tiered auth policy is reconciled in a follow-up commit.
- README.md / README.zh-CN.md: keep feature's V1.0.5 summary and apply
main's wording that Agents use their own CLI's model provider.
- docs/*: keep feature's untracking of local documentation drafts.
- cli-adapters-discovery.test.cjs: both sides were equivalent.
Checks: npm --prefix frontend test (325 pass). npm --prefix desktop test:
1503/1515 pass. The 12 failures are pre-existing on feature/1.0.5 at
bb55fad (verified by running them on a detached worktree of bb55fad) and
are addressed by the follow-up fixes.
Each Agent CLI now runs only with its own native credentials. The central
path of configuring one provider inside Meldwork for every Agent added
instability without being realistic to maintain, and it depended on
machine-local configuration details.
- Delete the provider store/options modules, the local-agent-provider IPC
handlers and preload API, per-CLI env injection (CODEBUDDY_*/ANTHROPIC_*/
KIMI_* ...), the managed OpenClaw provider runtime, and shared-provider
catalog gating; startup removes the legacy encrypted
meldwork-provider.json.
- OpenClaw always resolves its native runtime now; native credential
passthrough, the isolated gateway/guard runtime, and the
runtime-auth-failure state machine stay unchanged.
- Remove the Provider settings UI, onboarding slide, providerMode display,
~100 i18n keys per language, provider CSS, and update the architecture,
security, and discoverability docs to the native-credentials boundary.
Checks: npm --prefix desktop test (1512 pass), npm --prefix frontend test
(325 pass), frontend build and build:desktop, desktop pack.
- Extract WorkBuddy/Claude/Qwen error-result lists (errors[]) into failure
diagnostics and classify authentication failures as
LOCAL_AGENT_AUTH_REQUIRED instead of a bare LOCAL_AGENT_PROCESS_FAILED,
so the catalog marks the Agent as needing a fresh login and retries stop.
- Scope the isolated OpenClaw runtime directory by session, workspace, and
CLI version, so an upgraded OpenClaw gets a fresh managed scope instead
of failing on legacy workspace state written by an older CLI.
- Natural agent-led discussions now open with a full participant round and
the delivery owner cannot declare completion before peers had a
discussion round; sequential runs get the same cross-review gate
(system.autoCrossReview).
Checks: npm --prefix desktop test (1574 pass), npm --prefix frontend test
(343 pass), frontend build and build:desktop, desktop pack.
Refresh bilingual README and landing copy around evidence-backed review, local boundaries, and V1.0.5 capabilities. Update public download metadata and links.
Keep deletion on the existing IPC attachment cleanup path; remove an unused callback wired to the wrong coordinator and a nonexistent blob-store method. Verified focused conversation deletion test and git diff --check.
Keep direct and multi-round conversations on stable Agent sessions, isolate writable direct chats in the scheduler, and remove orphaned local attachments when deleting a conversation.
Move preferences and shortcuts into a global titlebar 12px from the right edge. Remove hidden duplicate controls and preserve shortcut dismissal. Replace conversation settings gear with sliders.
Verified: frontend tests 343/343, web and desktop builds, Electron position and interaction checks.
Prevent group completion from masking peer blockers, avoid replaying delivered group context, validate Pi protocol capability, and restrict child environments while preserving supported runtime configuration. Update the technical iteration plan and related discoverability documentation.
Recover reused ACP sessions that refuse before producing output so generic workspace recovery can establish a fresh session. Keep Pi processes alive through internal tool turns until agent_end, and extract V4 natural discussion decision methods into a dedicated module without changing the runner API or persisted structures. Verified with focused CLI, natural discussion, workspace recovery, syntax, diff, and full desktop test suites.
Use the Qwen-generated bitmap with rasterized English install guidance, keep Finder root resources hidden by repointing the background into the signed app bundle, and update packaging coverage. Verified with the full desktop suite, focused packaging tests, codesign, and hdiutil.
Use a compact 640x420 branded background and reposition the Finder icons so the installer opens without excess canvas or scrollbars. Keep key content clear when hidden DMG resources are visible.
Checks: node --test test/packaging/package-security.test.cjs; npm run dist; npx electron-builder --mac dmg; hdiutil verify; codesign --verify --deep --strict; git diff --check
Bump desktop/frontend package metadata to 0.1.5 and document CLI detection, OpenClaw migration, generic group routing and recovery improvements with their evidence boundaries.
Validation: frontend 343/343; desktop 1562/1562; deterministic eval 6 cases/18 results; web and desktop builds; pack/dist; DMG, ZIP, checksum and ad-hoc signature integrity; packaged Codex/OpenClaw group, cancellation and restart acceptance. No push, merge or installed-app replacement.
Clarify that completion receipts are stripped transport metadata, preserving user-visible exact output. Include validated dynamic Vertex model region keys in shell collection, cache identity and native Claude environment without changing packaged Electron fuses.
Validation: natural discussion/receipt 56 passed; final readiness/main 91 passed; real Codex and OpenClaw exact-answer runs completed; real Electron shell extraction passed. Full release checks remain pending.
Remove keyword-triggered shared media calls, reply-driven retries and implicit ZGCI fallback from chat orchestration. Preserve native Agent output import and visible responses.
Validation: desktop 1554/1554; five workflow routing regressions; real Electron completed with two Codex calls and zero shared media calls. Document the separate missing completion-receipt sample.
Bind clarification gates to completed task decisions and preserve them across restart. Make repeated gate responses idempotent to prevent invocation replay.
Validation: desktop 1549/1549; real Electron pending restart, input response, completion and duplicate-response checks passed with exactly one continuation call.
Use persisted taskDecision.nextKinds instead of prose mentions so negated and historical references cannot dispatch peers. Normalize identifier case generically, validate active recipients, and retain owner judgment and legacy ledger compatibility.
Validation: desktop suite 1542/1542 with native Claude integration; final protocol and discussion tests 37/37 after aligning the recipient limit to 32. Real Electron Codex/OpenClaw write, readback, completion and history reload passed. Frontend builds and release packaging remain pending.
Bind cached settings to allowed environment values and reload the login shell before serialized Agent refreshes so changed credentials and proxies do not reuse stale settings.
Validation: readiness and main security 87/87; Agent suite 459 passed, 1 optional integration skipped; isolated Electron refresh observed updated synthetic configuration with all 12 Agent entries preserved. Full desktop/build/package checks remain pending for this checkpoint.
Project minimal latest-run outcomes for visible topics through the workspace snapshot. Prefer those outcomes over historical stop messages and Agent call statuses in the topic rail and retained run card, preserving historical errors and private ledger boundaries.
Validate 1536 desktop tests, 343 frontend tests, desktop build, and real Electron reloads of recovered, completed, and blocked histories without additional Agent calls. Keep remaining V1.0.5 work explicit in the development record.
Track acknowledged source messages per native session and resend uncertain or changed input. Sanitize task decision text before hashing public receipts so absolute deliverable paths cannot strand completed group runs. Keep original Agent decisions for recovery.
Validate 1535 desktop tests including real Claude provider routing, 84 focused discussion checks, real Electron Codex/OpenClaw delivery, and recovery of the prior failed run without additional Agent calls. Synchronize the ACP stream test on received events. Record remaining recovery UI and release work.
Forward Agent-scoped cloud configuration and explicit empty overrides. Keep configured Provider credentials isolated and use Claude's native key helper to prevent settings from overriding the selected endpoint or exposing secrets in argv. Treat cloud/API-key status as configuration evidence so refresh does not erase recent auth failures.
Validation: desktop suite 1525/1525 before final credential-evidence classification; final readiness/catalog regressions 53/53; native Claude helper and endpoint tests 3/3; isolated Electron Provider save/refresh/chat passed; git diff --check passed. See progress document for platform and cloud-account limits.
Separate paid problem validation, software contribution, repeat sales, and resilience to upstream changes so service revenue does not imply software demand.
Validation: git diff --check -- docs/product-iteration-plan.md passed; documentation-only change.
Recover long replies from hash-verified, run-bound conclusion artifacts so closing peer requests survive message truncation. Bound shared history with explicit omissions and prevent incomplete excerpts from proving repetition.
Clarify read-only proposal deliverables and require external peer requests to return control to Meldwork. Update the native-session fixture to explicitly continue its requested rounds.
Verified: 1515 desktop tests, focused context and recovery tests, real Electron Codex/OpenClaw write/readback/completion, and git diff --check. Document failed validation samples and remaining release work.