> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tai42.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Merge env changes into the stored env and reload the fleet

> Merge env changes into the stored env and reload this worker and the fleet.

A hot-class key is re-read in place. A recycle-class key rolls a worker recycle across the
fleet: the response's ``recycle`` carries the roll's rows (``null`` when the roll had no worker
to visit: every worker's reload confirmed no recycle-class key moved off its bound value, or the
only ones naming one were refused at their epoch build or are the writer whose own restart cannot
follow as its exit), and when the roll converged and this worker needs its own restart, it
recycles itself after replying — on the HTTP edge and on every projected tool door alike
(a post-reply graceful self-exit its supervisor respawns). A write run under a bound the roll's
waits can outlast (a dispatched job's budget, an armed turn budget) hands the roll to the bus
member it acts for, which carries it out after the reply and departs itself last, once the roll
converged, when it needs its own restart: ``roll_deferred`` is then ``true`` and
``roll_deferred_to`` names that member, ``recycle`` ``null`` and ``awaiting_respawn`` empty.
A change that cannot take effect is refused with a 400 before anything is written, naming
the key, under any spelling of its name: a key that locates the worker bus (a bus URL or the
bus namespace), a deployment / boot-identity (X-band) key no editor may set, and a key the
deployment sets (set it in the deployment's environment and restart; removing its stored
copy is allowed).

``secret_keys`` (when not ``None``) replaces the operator's secret marks in the same write;
the marks variable itself is never accepted as an ``env`` key.
An ``mcp`` selection list whose ``!ENV`` marker would resolve so that a tool something still
uses stops being picked is refused with a 409 naming the holders, a 503 with ``code``
``mcp-server-starting`` while the server's start is in progress or ``mcp-server-not-loaded``
while this worker has not loaded the server, or a 502 with the recorded cause when this worker
holds no listing for the server and its last start or bind failed, before anything is written.

Called over MCP, the reload answers on the session that called it and then retires that session with
the generation it ran on: a later call on the same session fails (streamable HTTP answers it 404,
and an SSE session's stream closes), so the client starts a new session to go on.



## OpenAPI

````yaml /openapi.json post /api/config/env
openapi: 3.1.0
info:
  description: >-
    The operator HTTP surface served under /api/*. The platform's core routes.
    Plugin routes are published by each plugin.
  title: tai42-skeleton API
  version: 35.0.0
servers: []
security: []
paths:
  /api/config/env:
    post:
      tags:
        - config
      summary: Merge env changes into the stored env and reload the fleet
      description: >-
        Merge env changes into the stored env and reload this worker and the
        fleet.


        A hot-class key is re-read in place. A recycle-class key rolls a worker
        recycle across the

        fleet: the response's ``recycle`` carries the roll's rows (``null`` when
        the roll had no worker

        to visit: every worker's reload confirmed no recycle-class key moved off
        its bound value, or the

        only ones naming one were refused at their epoch build or are the writer
        whose own restart cannot

        follow as its exit), and when the roll converged and this worker needs
        its own restart, it

        recycles itself after replying — on the HTTP edge and on every projected
        tool door alike

        (a post-reply graceful self-exit its supervisor respawns). A write run
        under a bound the roll's

        waits can outlast (a dispatched job's budget, an armed turn budget)
        hands the roll to the bus

        member it acts for, which carries it out after the reply and departs
        itself last, once the roll

        converged, when it needs its own restart: ``roll_deferred`` is then
        ``true`` and

        ``roll_deferred_to`` names that member, ``recycle`` ``null`` and
        ``awaiting_respawn`` empty.

        A change that cannot take effect is refused with a 400 before anything
        is written, naming

        the key, under any spelling of its name: a key that locates the worker
        bus (a bus URL or the

        bus namespace), a deployment / boot-identity (X-band) key no editor may
        set, and a key the

        deployment sets (set it in the deployment's environment and restart;
        removing its stored

        copy is allowed).


        ``secret_keys`` (when not ``None``) replaces the operator's secret marks
        in the same write;

        the marks variable itself is never accepted as an ``env`` key.

        An ``mcp`` selection list whose ``!ENV`` marker would resolve so that a
        tool something still

        uses stops being picked is refused with a 409 naming the holders, a 503
        with ``code``

        ``mcp-server-starting`` while the server's start is in progress or
        ``mcp-server-not-loaded``

        while this worker has not loaded the server, or a 502 with the recorded
        cause when this worker

        holds no listing for the server and its last start or bind failed,
        before anything is written.


        Called over MCP, the reload answers on the session that called it and
        then retires that session with

        the generation it ran on: a later call on the same session fails
        (streamable HTTP answers it 404,

        and an SSE session's stream closes), so the client starts a new session
        to go on.
      operationId: post_api_config_env
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EnvUpdate'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/ApplyResponse'
                required:
                  - data
                type: object
          description: Success.
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
          description: Malformed request.
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
          description: Missing or invalid api key.
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
          description: Conflict with the current resource state.
        '502':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
          description: Error.
        '503':
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/ReloadingError'
                  - $ref: '#/components/schemas/Error'
          description: >-
            The server is applying a config reload, or a dependency this route
            needs is temporarily unavailable; retry shortly.
          headers:
            Retry-After:
              description: >-
                Seconds to wait before retrying; carried by the reloading
                answer.
              schema:
                type: integer
      security:
        - ApiKeyAuth: []
components:
  schemas:
    EnvUpdate:
      additionalProperties: false
      description: >-
        An env write: changes merged into the stored env, and optionally the
        whole set of secret marks.


        ``env`` maps names to string values (``""`` deletes a name).
        ``secret_keys`` absent or

        ``null`` leaves the stored marks untouched; a list REPLACES them (``[]``
        deletes them).
      properties:
        env:
          additionalProperties:
            type: string
          title: Env
          type: object
        secret_keys:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          default: null
          title: Secret Keys
      required:
        - env
      title: EnvUpdate
      type: object
    ApplyResponse:
      description: >-
        The standard mutation-op response: this worker's local reload result
        merged with the fleet fan-out summary.


        ``env_keys`` is the count of env keys the reload loaded. ``recycle`` is
        the fleet recycle roll

        the change ran — ``null`` when it had no worker to visit: every worker's
        reload confirmed no

        recycle-class key moved off its bound value, or the only ones naming one
        were refused at their epoch

        build or are the writer whose own restart cannot follow as its exit.
        ``awaiting_respawn`` is the

        operation's verdict: the workers still awaiting a respawn after it (name
        + keys) — when the roll

        converged and this worker recycles itself, only the workers whose reload
        was refused at their epoch

        build: the stored config did not build on them and a restart may fail
        the same way, so the roll

        leaves them running and lists them; a worker the roll did not reach
        keeps its keys.

        ``roll_deferred`` is ``true``

        when the roll is not judged in this reply: ``roll_deferred_to`` then
        names the worker that

        carries it out after the reply (``recycle`` is ``null`` and
        ``awaiting_respawn`` empty), and

        is ``null`` otherwise. ``span_release_error`` is ``null`` when the
        config store released its

        exclusive write span after the persist; otherwise the store's error —
        the change landed and

        the reload, broadcast and roll reported here still ran, but the store
        may still hold its write

        span until the writer process exits, so a later write can block or be
        refused until then.
      properties:
        awaiting_respawn:
          items:
            $ref: '#/components/schemas/AwaitingWorker'
          title: Awaiting Respawn
          type: array
        env_keys:
          title: Env Keys
          type: integer
        fanout:
          $ref: '#/components/schemas/FanoutSummary'
        recycle:
          anyOf:
            - $ref: '#/components/schemas/RecycleRoll'
            - type: 'null'
          default: null
        roll_deferred:
          default: false
          title: Roll Deferred
          type: boolean
        roll_deferred_to:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          title: Roll Deferred To
        span_release_error:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          title: Span Release Error
        status:
          title: Status
          type: string
      required:
        - status
        - env_keys
        - fanout
      title: ApplyResponse
      type: object
    Error:
      properties:
        code:
          description: >-
            Stable machine-readable reason a client keys a dedicated error state
            on, present on refusals that opt in (e.g. a 501 not-configured
            refusal). Optional: absent when the error carries only a
            human-readable message.
          type: string
        error:
          type: string
      required:
        - error
      type: object
    ReloadingError:
      properties:
        error:
          const: reloading — the server is applying a config reload; retry shortly
          type: string
        reloading:
          const: true
          type: boolean
      required:
        - error
        - reloading
      type: object
    AwaitingWorker:
      description: >-
        One worker an operation names as still awaiting a respawn.


        Its recycle-class ``keys`` changed in the stored env since its process
        bound them (at boot, or

        when the plugin that declares them was loaded), and nothing in the
        operation respawns it.
      properties:
        keys:
          items:
            type: string
          title: Keys
          type: array
        name:
          title: Name
          type: string
      required:
        - name
        - keys
      title: AwaitingWorker
      type: object
    FanoutSummary:
      description: >-
        The mode-tagged fan-out summary embedded under a mutation response's
        ``fanout`` field.


        ``mode`` selects the shape: ``local-only`` carries only ``note`` (a lone

        worker reached no sibling); ``fleet`` and ``unreachable`` carry the
        per-worker

        broadcast report
        (``op``/``reachable``/``local_only``/``results``/``error``),

        the ``unreachable`` variant having no worker list, only ``error``. The

        mode-variant fields are optional so one model describes every mode
        without

        reshaping any wire payload.
      properties:
        error:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          title: Error
        local_only:
          anyOf:
            - type: boolean
            - type: 'null'
          default: null
          title: Local Only
        mode:
          title: Mode
          type: string
        note:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          title: Note
        op:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          title: Op
        reachable:
          anyOf:
            - type: boolean
            - type: 'null'
          default: null
          title: Reachable
        results:
          anyOf:
            - items:
                $ref: '#/components/schemas/FanoutWorkerResult'
              type: array
            - type: 'null'
          default: null
          title: Results
      required:
        - mode
      title: FanoutSummary
      type: object
    RecycleRoll:
      description: >-
        The report of a fleet recycle roll a reload ran for the workers that
        needed a restart.


        A worker needs a restart when its reload reported a recycle-class key
        moved off the value it

        bound. A worker whose reload was refused at its epoch build (the build
        discarded before its

        swap) is never restarted, even when it reports such a key: the stored
        config did not build on it

        and a restart may fail the same way, so it keeps serving its current
        config; a failed discard is

        no refused build, and leaves the worker's state unknown. A worker other
        than the writer whose

        state was unknown is asked once it is ready and restarted unless its
        reply confirms it clean or

        states a refused build (its line then ``withheld``). The writer is never
        asked at its own roll:

        when its own state is unknown, its restart is left to its post-response
        self-exit, armed only

        when the roll converged and the reply can carry one (then its
        ``self-deferred`` line).

        ``recycle`` the worker lines of the roll

        (the writer's own ``self-deferred`` line when its post-response
        self-exit is armed); ``skipped``

        the workers whose reload confirmed no such key, at the reload or when
        asked once ready, left

        running; ``fresh`` the new ready lives seen since the change began;
        ``recycle_stopped`` is

        ``null`` when the roll ran to its end, otherwise where it stopped and
        why. Names only — never

        env values.
      properties:
        fresh:
          items:
            $ref: '#/components/schemas/FreshLife'
          title: Fresh
          type: array
        recycle:
          items:
            $ref: '#/components/schemas/RecycleEntry'
          title: Recycle
          type: array
        recycle_stopped:
          anyOf:
            - $ref: '#/components/schemas/RecycleStop'
            - type: 'null'
          default: null
        skipped:
          items:
            type: string
          title: Skipped
          type: array
      required:
        - recycle
        - skipped
        - fresh
      title: RecycleRoll
      type: object
    FanoutWorkerResult:
      description: >-
        One worker's verdict within a multi-worker fan-out report.


        ``payload`` carries a query op's per-worker data; ``error`` a failed
        apply's

        message; ``detail`` the publisher's note for a computed
        missing/departed/

        timed-out verdict. ``outcome`` is the worker's terminal outcome as its
        wire

        string.
      properties:
        detail:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          title: Detail
        error:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          title: Error
        name:
          title: Name
          type: string
        outcome:
          title: Outcome
          type: string
        payload:
          anyOf:
            - $ref: '#/components/schemas/JsonValue'
            - type: 'null'
          default: null
      required:
        - name
        - outcome
      title: FanoutWorkerResult
      type: object
    FreshLife:
      description: One newly-ready worker life observed since the pre-apply snapshot.
      properties:
        generation:
          title: Generation
          type: integer
        kind:
          title: Kind
          type: string
        name:
          title: Name
          type: string
      required:
        - name
        - kind
        - generation
      title: FreshLife
      type: object
    RecycleEntry:
      description: >-
        One worker line of a fleet recycle roll.


        ``status`` is ``recycled`` (confirmed on reality), ``timed-out`` or
        ``failed`` (the target the

        roll stopped at), ``self-deferred`` (a restart the roll cannot confirm:
        the writer's own

        post-response self-exit, or a target whose exit is held by its own
        in-flight change and runs

        once that change's reply is answered), or ``withheld``

        (a worker asked once ready whose reload was refused at its epoch build —
        the build discarded

        before its swap — yet reports a recycle-class key: the stored config did
        not build on it and a

        restart may fail the same way, so the roll leaves it running on its
        current config). ``keys``

        are the recycle-class keys that worker's reload reported as moved off
        the value it bound them

        under — the reason it was restarted, or for a ``withheld`` worker the
        keys it still awaits;

        empty for a worker restarted because its state stayed unknown. A worker
        other than the writer

        whose state was unknown is asked once it is ready and restarted unless
        its reply confirms it

        clean or states a refused build (its line then ``withheld``). The writer
        is never asked at its

        own roll: when its own state is unknown, its restart is left to its
        post-response self-exit,

        armed only when the roll converged and the reply can carry one (then its
        ``self-deferred``

        line). ``detail`` names what left that

        worker's state unknown (its reload outcome, no report row, a malformed
        reply, an unreachable

        bus) with what it answered when asked once ready, and why a
        ``timed-out`` / ``failed`` target

        did not converge, joined with ``"; "``; ``null`` when none applies.
      properties:
        detail:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          title: Detail
        generation_before:
          title: Generation Before
          type: integer
        keys:
          items:
            type: string
          title: Keys
          type: array
        kind:
          title: Kind
          type: string
        name:
          title: Name
          type: string
        status:
          title: Status
          type: string
      required:
        - name
        - kind
        - status
        - generation_before
        - keys
      title: RecycleEntry
      type: object
    RecycleStop:
      description: >-
        Where a profile apply's recycle roll stopped and why.


        ``name`` is the target the roll stopped at (its line in ``recycle``
        carries the

        target's own outcome), or ``null`` when the bus could not be read before
        a target was

        reached.
      properties:
        detail:
          title: Detail
          type: string
        kind:
          title: Kind
          type: string
        name:
          anyOf:
            - type: string
            - type: 'null'
          title: Name
      required:
        - kind
        - name
        - detail
      title: RecycleStop
      type: object
    JsonValue: {}
  securitySchemes:
    ApiKeyAuth:
      in: header
      name: x-api-key
      type: apiKey

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.