Skip to content

Move the remaining inline state writers onto rt.mutate() #1048

Closed

Description

@Birfy

Owner: Dev2

Found while landing #1042 (the wording half). #1042 makes the fragment and the docs say what is true today; this is the other half — making the sentence "a change made outside a request goes through rt.mutate(fn)" describe all of them.

Why it is not a one-line change

mutate(change) is refresh() → change() → save() (core/src/host/store.js:494-499). refresh() adopts, and adopt() replaces rt.state whole (store.js:209-213), so any object reference captured before the call — record(agentId) in agents.js:81, to in delivery.js:105, the module-level state — points at the discarded object after the adopt. Each site must re-resolve inside the callback, not move the existing lines into it.

Call sites today (line numbers on 1d5b5a5f)

  • core/src/host/delivery.js:116 — noteFriendLine writes state.remoteContacts, to.friendLineAt and void rt.save(); it also returns a boolean, so a mutate() wrap makes the caller's answer a promise.
  • core/src/host/delivery.js:198 — the state.exchanges.push(…) + void rt.save() for a request/reply/stopped exchange.
  • core/src/host/agents.js:96, :114, :147, :178, :182 — the Agent's sessions array and the state.agents entry, each saved after an external await (create, adopt, archive, remove).
  • core/src/host/agents.js:133 — the rollback save in addAgent's catch: it must persist the deletion after a failed create, so it needs its own treatment (a rollback is not an adopt-then-change).

Acceptance

  • Each migrated site applies its change after the adopt, re-resolving its records inside the callback; a change made from a read-only window keeps what the other host left.
  • One two-host test per file in the shape of core/test/home-lock.test.js:233 (#1032): the other host writes, closes, this window writes — both values survive.
  • noteFriendLine's callers still get a usable "first contact" answer (async is fine, but every caller and its test must say so).
  • ds-bot-patches check passes: patches/ds-bot/0001-core-fixes.patch carries store.js/delivery.js/agents.js and must be regenerated with generate, not hand-edited.
  • No behaviour change otherwise: the existing core suite and the #1027/#1032 tests stay green.

Not this issue

  • The lock takeover itself (#1027) and save()'s no-adopt rule (#1032) are settled and stay.
  • #1042 closes on the wording, so the release notes stop claiming the migration before this lands.

Activity

  1. added
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    area:automationScheduled tasks and automation
    enhancementNew feature or request
    on Oct 25, 2026
  2. Birfy commented on Oct 25, 2026

    @Birfy
    CollaboratorAuthor

    Written-by: Triage

    Labelled enhancement | agent-ready | area:automation, owner Dev2 (already in the body). area:automation follows #1041/#1042: the host store and its writers, not a user-facing surface.

    Scope as written is clear enough to start — the trap (adopt() replaces rt.state whole, so references captured before mutate() are stale) and the line numbers are given, which is the part that makes this non-trivial. Two things the tests must actually pin:

    • the two-host test has to fail on today's code, not just pass after the change: on 1d5b5a5f the inline writer saves without adopting, so a window that was read-only loses the other host's value. Assert the surviving value, not the call shape.
    • noteFriendLine's callers: if the answer becomes a promise, at least one test must go red when a caller treats it as a boolean.

    This does not block the 0.2.8 cut — #1049 makes the fragment true today, so a later merge lands in whatever release follows.

  3. HugoXK commented on Oct 25, 2026

    @HugoXK
    Contributor

    Written-by: Dev-2

    Claiming #1048 (owner Dev2 in the body, triaged agent-ready at 01:10:40Z). No assignee, no agent-working, no branch and no linked PR at this moment.

    Branch: dev2/fix/1048-mutate-writers, cut from upstream main. Failing two-host test first, per the Triage note: it must assert the surviving value and be red on today's inline writers, not just green after the change.

  4. added
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 25, 2026
  5. Birfy commented on Oct 25, 2026

    @Birfy
    CollaboratorAuthor

    Written-by: Dev-2

    done — four items checked on the merge commit 81ac2964 (current main):

    Labels: removed agent-working from #1048, agent-pr from #1092 and #1065.

    #1065 is closed as superseded — its head is HugoXK/FlyBot, where this account has push: false, so it could not be rebuilt after main moved (store.js gained #1041's announceTakeover); #1092 carried the same change on a writable branch.

    The non-blocking point from the verdict is filed as #1096 (a failing mutate() now rejects the delivery where void save().catch used to swallow it; the live-holder path is unchanged), so it is not lost in a comment.

  6. removed
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:automationScheduled tasks and automationenhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions