Skip to content

    News

    1.32.1

    archied — Host packaging: archie-messaging now ships and updates

    • cmd/archie-messaging is included in the distribution zip, and scripts/archie-update-install installs and restarts it.
    • Why this mattered. v1.30.0 moved Telegram, email and webhook out of archied and into archie-messaging, but nothing packaged the new binary. A host install that upgraded across v1.30.0 therefore ran on with no messaging process at all: archied logged that it stopped serving the telegram gateway, nothing replaced it, and Telegram stayed dead — with no error logged anywhere, because nothing was failing. The process simply did not exist.
    • The host component set was enumerated in four places — the zip’s build loop, the zip’s copy list, the installer’s service list, and the installer’s binary list — and archie-messaging was missing from all four. The duplication was the defect: a single test now derives the host-run commands from cmd/ and asserts that all four lists agree with it, so adding or extracting a process fails until it is packaged.
    • deployments/systemd-user-service.md gains the messaging unit. That is load-bearing rather than cosmetic: the updater refuses an update when a service unit is missing and tells the operator to create one from that document, which previously had nothing to offer.

    Upgrade note: a host that reached v1.30.0 without a messaging unit has been running with no Telegram, email or webhook. Updating to this release installs and starts archie-messaging.

    1.32.0

    archied — EDA: playbook action ids, and a dispatch idempotency ledger

    • Action ids (J1). Every action a later action references must now carry an id. Ids are validated at load – unique and stable-identifier-shaped – and a when/args expression naming an unknown actions.<id> is a load failure, not a runtime miss, the same reject-at-load rule already applied to a binding collision.
    • Reference classification is strict at load. A map-index reference (actions[expr]), a non-literal index, and a reference to an unknown prior id are all rejected when the playbook loads; references are classified by identifier versus static access, and the when-compilation helper is shared between the load-time and runtime paths.
    • Dispatch idempotency ledger. A playbook_dispatches row records a dispatch against (playbook_id, playbook_version, event_id, action_id), written with INSERT OR IGNORE and surfaced through the shared store.ErrAlreadyDispatched sentinel. Module, channel and forge action positions are therefore at-most-once, which is what unblocks the side-effecting positions that were previously rejected at load.
    • The ledger is wired into production. stateStoreDeps constructs Deps.PlaybookDispatcher, so the ledger RPCs no longer answer Unavailable in a running daemon. This defect was found by the pre-release review of this change rather than by its tests.

    Behaviour change: a playbook whose actions reference actions.<id> without declaring that id, declare a duplicate id, or index actions with a non-literal value now fails to load instead of failing at dispatch time.

    archie-agent

    The sandboxed runtime links storecontract and staterpc, so it carries the dispatch-ledger contract alongside archied:

    • The shared store.ErrAlreadyDispatched sentinel now describes both dedup ledgers – binding_dispatches per (binding_id, capture_id), and playbook_dispatches per (playbook_id, playbook_version, event_id, action_id). Each is an at-most-once guarantee.
    • RecordPlaybookDispatch is part of the store contract the runtime builds against.

    archied and archie-agent move together in this release.

    1.31.0

    archied — Dashboard replaced: Preact -> Vue 3 + shadcn-vue

    The dashboard is now a Vue 3 application built on shadcn-vue. This is the large piece of this release; it touches every page.

    • History routing, a grouped topbar built from components, the violet palette with self-hosted Geist, and a command palette with live tasks.
    • Chat is a FAB-opened panel that behaves like a chat window and scrolls its transcript with MessageScroller.
    • Task actions and dangerous approvals are deliberate; the task detail page is a single head strip with honest states; the run page settles its head around an attempts pager, which is hidden for zero or one attempt.
    • Appearance and System navigation were refined, with a four-column appearance grid on wide screens.
    • A copy pass removed redundant tails and restating descriptions, empty states derive their own titles, and a stuck log read surfaces as an error rather than eternal loading.
    • The capture pane is bound to the list it sits beside and reads beside it, not over it.

    archied — Events is one page with three tabs

    • Inspector, Bindings and Mappings are now tabs of a single Events page.
    • The nav entry is always live, the tabs prune by capability, and the three old paths survive as bookmarks that redirect to their tab.
    • Tab selection lives in one module (ui/src/events/tab-selection.ts) that the page uses, rather than a copy of it.
    • feat(tools): a capture-intake sender exists for exercising the Events surfaces.

    archied — The channel travels with the message

    SessionSource.Platform – the first component of the session natural key, and the column GetByChannel filters on – was a constant "web", because one Router serves every channel and named itself after its own. Two things followed: the per-user identity policy was real code that no production call site reached with a real channel name, and a curator pass’s write to agent-user memory could not be read back by the turn that wrote it, because that turn resolved no UserID.

    • The frontends now name the channel they carry (telegram, email, webhook, web), the channel rides the message, and the Gateway stamps the session from it – falling back to its own name when a sender names none, which is what every existing row holds.
    • Identity resolution reads the platform off the inbound, so carriesPersonIdentity decides something in production: telegram and email resolve a person, the dashboard and a webhook resolve nothing, and an unknown platform fails closed.
    • Behaviour change: a chat whose active session came from /new or /branch re-resolves once, because session lookup now filters on the channel’s real name. A chat without /new re-resolves onto the same deterministic id and heals silently.
    • Deliberately unchanged: TurnRunnerConfig.Channel still keys tool availability, so no channel gains or loses a tool in this release.

    archied — Control plane: runtime administration, history, and derived schemas

    • The State Store’s gRPC server now carries runtime administration, and each process reports which settings version it is running; the dashboard shows it.
    • Resource history is exposed so edits can be reviewed and rolled back, and resource schemas are derived from the documents they describe – the document editor reads the derived schema (labels from title, format: duration -> 1m0s, hints from doc), and the abandoned schema-driven card is deleted.
    • A live settings replacement is checked before it is switched to, the daemon’s state surfaces are folded into one boot step, and a SIGHUP reload re-applies database-owned settings.
    • Forge intake settings that nothing reads are now rejected at load.

    archied — Configuration: judged where it is owned

    • The runtime config overlay is deleted; database-owned settings are judged at the layer that owns them rather than on the file load path.
    • A file overlay no longer drops the fields it omits inside a map entry, and a kind with no stored value leaves the file’s value in force.
    • The default config path is resolved in one place, and the channel document has its own shape.

    archied — State Store: offline backup, restore, validate and rollback

    • New offline backup / restore / validate / rollback path.
    • validate runs boot’s own gate; it no longer replaces the database, reads a kind the store does not hold as its seed, or touches the daemon’s log.
    • The recovery control-plane server is built on the shared step vocabulary.

    archied — Workflow: one step vocabulary and a gate.diff-rules replacement

    • The step vocabulary is owned by a family manager registered at each composition root, replacing .archie/gate.go with gate.diff-rules, which fails closed on a change it never read.
    • Workflow roots are pinned and the dead vocabulary is removed; the workflow pin crosses the wire.
    • The schedules resource skips the legacy cron jobs it cannot hold, and the scheduling policy carries the label its trigger pairs with.

    archied — EDA: the playbook coordinator reaches production selection

    • The playbook coordinator is wired into production workflow selection, so a matching playbook decides a real task’s workflow at the daemon’s definition pin, inheriting idempotency from TaskEnvelope.

    archied — Reliability and operations

    • cronstore writes a schedule interval as a duration, not nanoseconds – a persisted 1m no longer round-trips as 60000000000.
    • Worktrees are cut from the mapped base branch, and the Gateway’s worktree manager is built so it serves review_pr.
    • A late max-uptime callback no longer resurrects teardown state.
    • The state store dial installs client keepalive, and its server policy accepts the dialer’s pings; control-plane watch streams re-establish themselves after they end.
    • /status serves only the health facts a reply can carry; the daemon reports systemd readiness and loop-driven watchdog heartbeats.
    • A webhook route path no longer becomes a sender identity.
    • A chat session compresses when a turn crosses its context budget.
    • The MCP client supports per-server parallel_tool_calls, carried through the tool-settings projection.
    • Resource request-ID idempotency keys are scoped to their kind.
    • The session curator addresses memory by the deployment’s bot user.

    archie-agent

    The sandboxed runtime links the same shared packages as archied, so this release carries the control-plane and workflow changes alongside it:

    • Runtime administration over the State Store’s gRPC server, resource history, and control-plane apply status on the store contract.
    • The shared step vocabulary, owned by a family manager registered at each composition root, and gate.diff-rules in place of .archie/gate.go (fails closed on a change it never read).
    • The workflow pin crosses the wire.

    Runtime-specific changes:

    • refactor(plugin): the unused Registry type is deleted.
    • yaegiutil refuses incomplete Yaegi interface wrappers at load rather than running them.
    • The runtime config overlay is deleted.
    • The state store dial installs client keepalive, and the server policy accepts the dialer’s pings.
    • The MCP client supports per-server parallel_tool_calls.
    • A late max-uptime callback no longer resurrects teardown state.
    • A webhook route path no longer becomes a sender identity.

    Note: the archie-agent image is rebuilt by this tag through CI (.github/workflows/deploy.yml); a gateway-only release would not have rebuilt it. docker compose pull agent is required to pick it up.

    1.30.0

    archied — Messaging Service extraction completed

    Telegram, email and webhook no longer run inside the daemon. They run in archie-messaging and reach the daemon through the Gateway’s ChatContract over gRPC; the daemon builds no channel and no gateway.Router (#899).

    • The operator surface is re-wired in the extracted service: /update (built from its own [chat.telegram] commands), the update-report relay, the show_tool_calls projection, and /restart’s config reload, which re-resolves the token and allowlist from this service’s own file and refuses a reload that resolves to an empty token.
    • /version is sourced from the Gateway through a new ChatSnapshot.Version field. cmd/archie-messaging deliberately takes no version ldflags, so it cannot report a partial upgrade as a matched one.
    • Channel configuration is validated at composition, so a configured-but- invalid front-end fails the service instead of being silently dropped.
    • The inbound rate limiter moves to the Gateway, which now owns the only Router and is therefore the one place a per-sender budget can apply to every channel’s turns.

    RunningVersions and ReleaseAnnouncements are deliberately left unwired: both need a component’s real running version, and the only versions this process can obtain are another binary’s stamps. See docs/architecture/migration-decisions.md.

    archied — Configuration

    • diff_cap_lines = 0 now switches the cap off, as the dashboard and the workflow step have always documented. It was a plain int, so the defaults pass could not tell an absent key from an explicit 0 and rewrote both to 400 – the documented way to disable the cap was unreachable. Behaviour change: a config that set 0 was silently getting 400 and will now get no cap.
    • The same ambiguity was failing open per identity: configForIdentity assigned the identity’s value unconditionally, so an identity that merely omitted diff_cap_lines overwrote the shared cap with the zero value and disabled the safety rail entirely. An identity now overrides only when it sets the key.
    • A diff-cap park no longer tells the operator to “approve manually”. A parked task’s actions are retry, abandon and reject, so there is no approve path out of diff-cap; it now names the two things that work.
    • [health].dependency_timeout makes the daemon’s readiness probe timeout configurable, matching the extracted services.

    archied — Chat rendering

    • /status and /tasks are line-oriented reports but separated lines with a plain newline, which is CommonMark’s soft wrap: the Telegram renderer joined them into one run-on paragraph. The renderer implements CommonMark’s hard line break and the reports use it. Ordinary prose still soft-wraps.
    • A park reason is capped to its first line in the /tasks list. It carries whatever the failing stage reported, which for a lint gate is a whole tool log; unbounded, one parked task pushed every other task out of the reply. The full reason is unchanged on the task, in task_list and on the dashboard.

    archied — Review

    • Review findings are posted as line-anchored PR comments with suggested fixes, and a suggestion must be single-line – GitHub applies a multi-line suggestion only up to its first line, silently corrupting the file (#891).
    • The remediate workflow handles PR review comments and requested changes.

    archied — /status health surface

    /status reports the live broker connection and the last-known outcome of this process’s chat-model calls, alongside the queue depth and runtime block (#892).

    • A provider error is flattened and capped, so a multiline or oversized error cannot break the one-line-per-fact layout.
    • Concurrent model calls no longer reorder: the completion time is taken before the lock, so the newer outcome wins rather than whichever goroutine stored last.
    • Curator model calls are recorded too. They bypass the chat path, so a daemon whose only recent model traffic was curator work reported “no calls attempted yet” while the provider was demonstrably reachable.
    • Title generation does not record health. It runs detached under its own bound and its error is swallowed, so a cosmetic timeout was overwriting the line with “failed”.

    Known limitation: the container, poll and channel sections cannot render. Those facts live in the daemon, but the only Router lives in the Gateway process, which has no container pool and no poll loop. The command description says what actually appears; restoring the rest needs a cross-process health contract.

    archied — Dashboard and containers

    • The served lifecycle vocabulary reaches an already-painted page, the page registry matches the routes, and the build verifies ui/dist is fresh instead of never looking at it (#890, #898).
    • The container reaper no longer deletes teardown bookkeeping early, so a released container is not torn down twice (#893).

    archied — Build

    • task fmt runs golangci-lint fmt – the same engine and configuration the gate checks with. Standalone gofumpt cannot reproduce gci’s import grouping, so formatting and linting could not converge and no command satisfied the gate (#901).
    • goimports is deliberately absent from the formatter set: it re-reads and re-parses the module index once per file, ~135s across this tree.

    archied — Fixed

    • Config.Clone left the new diff-cap pointers aliased, so a clone could write through to the published snapshot (#902).
    • A curator asking for a completion on a daemon with no configured provider panicked the process; it now returns an error.

    archie-agent

    • The sandboxed runtime picks up line-anchored review comments: a finding is posted against the line it is about, with a suggested fix where it has one, and a suggestion is rejected unless it is single-line – GitHub applies a multi-line suggestion only up to its first line, silently corrupting the file (#891).
    • diff_cap_lines is an optional value in the shared config the runtime reconstructs, so an explicit 0 means “no cap” rather than being rewritten to the default. Behaviour change for a repo that set 0 expecting unlimited and was silently getting 400 (#899).
    • A diff-cap park names a remedy that exists: a parked task’s actions are retry, abandon and reject, so the reason no longer says “approve manually”.
    • A released container is not torn down twice – the reaper no longer deletes teardown bookkeeping before Release is finished with it (#893).
    • Build toolchain: gofumpt and golangci-lint are pinned as one matched pair, and task fmt uses the same engine the gate checks with, so the runtime’s own gate is satisfiable (#901).

    1.29.0

    archied — Security

    • google.golang.org/grpc bumped past v1.84.0 to patch GO-2026-6443, a server panic via a missing :authority/Host header reachable through archied’s gRPC gateway server. No stable release carries the fix yet, so this pins the pre-release commit that does (v1.85.0-dev.0.20260825072537-93e31b48545e) until grpc-go cuts v1.85.0.

    archied — Memory engine unification

    One memory engine, addressed by four typed scopes (global, agent, user, agent-user), replaces the two disconnected stores that previously existed: a chat-tool-written store nothing ever read back, and a curator-written store with no scope model.

    • internal/domain/memory is a CRUD contract (Create/Get/Query/List/ Update/Forget/Revisions) with retained revisions; updates supersede rather than overwrite, so a crash mid-write leaves a recoverable extra history entry, never a lost prior state (#886).
    • The chat turn reads its subject’s scopes synchronously before the prompt is built, rendering recalled records into a <memory> block; a failing or panicking engine degrades to no memory block rather than failing the turn (#887).
    • The model writes memory through four id-addressed tools (memory_create/update/delete/list), scoped to the turn’s own resolved identity – the model chooses the scope kind, never the ids, so it has no path to write into another user’s memory (#888).
    • The session curator now derives the agent-user scope from the session’s own user-role messages, instead of keying facts by a session id that stops meaning anything once the session ends.
    • A channel with no resolvable user (dashboard, webhook) reads and writes only global and agent scope; a webhook’s route path is never treated as a user identity.
    • Fixed a review finding on the read path: the per-scope record limit was being applied as one shared total across all scopes rather than per scope, and the rendered block’s byte cap was checked before template escaping rather than after, letting the escaped block exceed it.

    archied — Work intake

    • feat(workintake): define review reaction envelope
    • feat(workintake): authorize review reactions by owned PR

    archied — Cleanup

    • Deleted the unwired plugin capability-host health surface (Host.Health/Host.Manifests/ModuleStatus) and the Module.Health chain it fed – including the mcp/builtin tool-provider health implementations and their aggregation in tools/provider.Registry – none of which had ever had a production caller (#882).

    archie-agent

    • The sandboxed runtime picks up the review-reaction envelope and its owned-PR authorization, so an agent can only react to reviews on pull requests it opened itself.
    • google.golang.org/grpc bumped past v1.84.0 to patch GO-2026-6443 (shared dependency with archied; the pre-release commit is pinned pending a stable v1.85.0).

    1.28.0

    archied — Task detail and attempt attribution

    • New per-run task detail page, showing each attempt’s own events, changes and configuration rather than a single merged view.
    • Events, changes and config are attributed to the attempt that produced them; Event carries attempt and ReadTaskLogRequest carries stage.
    • The task detail page remounts when the task id changes, so switching tasks does not leave the previous one’s data on screen.

    archied — Configuration

    • Services are keyed by name through a registry, so the State Store and Gateway listen addresses are configurable rather than fixed.
    • A partial overlay no longer clears the fields it omits — an overlay that set one key was wiping the rest.
    • The Services map is cloned on publish, so an overlay can no longer mutate the snapshot other readers are holding.
    • The service context is enforced at registration.

    archied — Logging and park reasons

    • A parked run’s reason is recorded in its own attempt log, in both the daemon and the workflow, so “why did this park?” is answerable from the task itself.
    • TaskRegistry.Write takes the caller’s context.

    archied — Worktrees and containers

    • Retries recover from path-type conflicts instead of failing opaquely, and the underlying cause is no longer masked.
    • The worktree is handed back on every sandbox exit.
    • A container’s max-uptime reaper is cancelled on release, the cap stays active through the grace period, and teardown is claimed once rather than by cancelling a timer.

    archied — Daemon and startup

    • Every identity’s forge and repos are swept at startup, including the root forge.
    • A cancelled startup is no longer reported as an exhausted sweep budget; an exhausted budget names itself as the cause.

    archied — Other

    • grep can use the workspace codesearch index.
    • Forge labels are matched when namespaced, so label-driven routing works for namespaced labels.
    • Triage is given criteria for choosing between workflows, and a workflow is required when a code change is needed.
    • The Telegram adapter restart callback is wired into the chat router.
    • The ARCHIE_REACTIONS fan-out stream is provisioned and bounded by age.
    • archie-ui exits cleanly when graceful shutdown overruns its deadline.
    • The dashboard’s event pump retries priming until the State Store answers.
    • The update writer emits the agent version sidecar with a real newline.
    • The UI finishes its Preact port; the imperative DOM layer is deleted.
    • Collection fields decoded over the State Store gRPC contract are never nil slices, so an empty collection marshals as [] rather than null.

    archie-agent

    • The sandboxed runtime picks up the attempt-attribution contract, so the events and changes an agent produces are recorded against the attempt that produced them.
    • grep can use the workspace codesearch index.
    • A worktree is handed back on every sandbox exit, and container teardown is claimed once — a released container’s reaper is cancelled rather than re-firing during the grace period.
    • Retries recover from worktree path-type conflicts instead of failing opaquely.
    • A parked workflow run records its park reason in its own log.
    • Triage criteria distinguish the workflows, and a workflow is required when a code change is needed.
    • Namespaced forge labels match when routing by kind.
    • The ARCHIE_REACTIONS fan-out stream is provisioned.
    • Collection fields decoded over the State Store gRPC contract are never nil slices, so an empty collection marshals as [] rather than null.

    1.27.0

    archied — Dashboard task logs

    • Task logs are readable from the dashboard again, through a new State Store read contract (ReadTaskLog, StreamTaskLogContent) rather than the UI process reaching into the daemon’s log files. Wired server-side by the standalone state-store process.
    • Added GET /api/tasks/{id}/logs/download, serving an attempt’s raw log as a task-<id>-attempt-<n>.log attachment.
    • A process that cannot read logs and an attempt that recorded no log are now distinguishable (“cannot read” answers 503, “no log” answers 404) instead of both rendering as a claim about a configuration setting.

    archied — Telegram output

    • Tool results are summarised rather than quoted: a search reports how many matches came back, a truncated result reports the tool’s own total. The renderer no longer states a count it computed from its own truncated sample.
    • Repeated successful tool calls collapse into one counted entry.
    • The tool-activity block is capped to a third of the live frame, keeps the newest lines, and marks what it dropped with a +N earlier indicator. Every line that fits is kept.
    • Every clamped answer marks its cut with an ellipsis, including the opening frame, which previously appeared to begin mid-sentence.
    • An error response from the log download no longer ships as a .log file.

    archied — Readiness and shutdown

    • The disk probe reports per-filesystem results and checks the root filesystem as well as the work directory, so a full root is no longer invisible.
    • A path shared by several disk targets keeps the strictest requirement any target places on it, so an optional target can no longer mask a required one.
    • The shutdown-watchdog test no longer races the Go scheduler, which was intermittently failing the quality gate and parking work unrelated to it.

    archied — Other

    • Messages persist the channel-native sender id.
    • go-telegram/bot bumped to v1.27.0, fixing a streaming bug where the multipart body could not be replayed and sendMessage/editMessageText failed until the connection dropped.

    archie-agent

    • The per-task runtime picks up the new State Store task-log read contract, so the sandboxed agents share one log-reading path with the daemon and the dashboard.

    1.26.0

    archied

    • fix(webui): publish per-identity forges so multi-identity task rows keep their links
    • feat(config): add [scheduling] config block
    • feat(configuration): translate [scheduling] into scheduling.EngineConfig
    • feat(cronevents): adapt the events bus to scheduling.Sink
    • fix(webui): count every chat front-end in the published projection
    • fix(scheduling): respect configuration ownership
    • feat(ratelimit): wire per-identity inbound rate limiting into the gateway
    • fix(tools): judge the rm guard by base name so absolute paths cannot bypass it
    • fix(store): keep an empty binding secret empty so a partial edit cannot erase it
    • fix(archied): stop advertising review_pr when no reviewer can run
    • fix(daemon): carry kind/label routing bindings to the process that routes
    • feat(configuration): add archied setup, the caller the first-run flow was built for
    • fix(configuration): stop letting a secret value be set from the command line
    • feat(configuration): let setup reference a secret without carrying its value
    • fix(archied): disable a provider whose credential is missing instead of refusing to boot
    • refactor(install): install.sh delegates config generation, and tests stop reading hand-written configs
    • fix(daemon): guard binding dispatch loop against nil dispatcher/creator
    • fix(webui): enforce CSRF/origin gate on binding and mapping mutations
    • fix(secret): recover a panicking secret engine instead of crashing
    • fix(config): deep-copy Image.Hosted/Image.Local in Config.Clone
    • fix(email): stop dropping the first paragraph of plain-text bodies
    • fix(logging): keep the live descriptor open across a failed rotation
    • feat(configuration): report config keys no decode target consumed
    • feat(archied): warn at boot when the config file has unrecognised keys
    • feat(archied): wire the scheduling ticker engine at boot
    • fix(agentworker): wire configured tool-result policy into worker’s LoopRunner
    • refactor(staterpc): delete the superseded single-token auth interceptor
    • refactor(memory): delete the unreachable fence scrubber
    • fix(channels): delete unreachable Telegram webhook delivery mode
    • fix(gateway): delete unwired Router.Dangerous approval path
    • refactor(gateway): delete orphaned SessionState goal/steer/queue machinery
    • refactor(archied): delete the daemon’s unused webui.Server and UI adapters
    • refactor(tools): delete unreachable dispatch/gating engine
    • feat(channels): wire chat.webhook route config through to the gateway
    • refactor(tools): delete unreachable AST-based tool discovery
    • refactor(tools): delete unused plugin-tool registration API from builtin.Registry
    • feat(channels): wire ConfigSchema/ValidateConfig into a startup validation loop
    • refactor(state): delete the dead IncrementRetryCount RPC (breaking change, accepted)
    • fix(curator): populate PassInput.Since with the prior pass time
    • fix(memory): install the threat scanner the composition root never wired
    • fix(staterpc): preserve marshal_error marker in eventDataJSON
    • fix(gate): validate finding level and share the blocking threshold
    • fix(scheduling): record a completed run so a recurring job stops re-firing every tick
    • fix(releaseupdate): don’t treat empty available as deferred
    • fix(tools/provider/mcp): preserve MCP binary tool results for delivery
    • refactor(gateway): share sensitive-key markers with webhookguard
    • refactor(daemon): remove unreachable SQLite poll/drain path
    • refactor(tools/mcp): delete unreachable MCP adaptation path
    • fix(taskactions): resolve max_retries from the task’s owning identity
    • fix(daemon): forward configured MCP servers to task agents
    • refactor(skill): delete dead Discover/DiscoverPlugins/Skill path
    • refactor(skillbuild): delete dead AugmentRegistry path
    • fix(builtin): bound read/edit filesystem work by DefaultToolTimeout
    • refactor(binding): delete dead Matcher.Overlaps method
    • refactor(forge): delete dead CreateIssue surface
    • fix(mcp): cancel in-flight SSE reconnect on Stop
    • fix(container): enforce MaxUptime lifetime cap with a timer
    • refactor(store): use taskstate status constants in SQL
    • fix(ui): unbreak binding approve and the two deletes, and centralise the client
    • fix(tools): stop testing on the text of other files, and ungate contractaudit
    • refactor(forge): delete the unwired RepliesAfter surface
    • refactor(config): delete the two decoded-but-unread policy fields

    This release is dominated by dead-code removal and the completion of the scheduling capability. Roughly half the commits delete surfaces that no longer had a caller: the unreachable SQLite poll/drain path, the unwired MCP adaptation path, the AST-based tool discovery, the superseded single-token auth interceptor, and several dead forge and binding methods. The IncrementRetryCount State Store RPC is gone with them – a breaking change to the wire contract, accepted because nothing called it.

    The cron/scheduling epic lands its remaining slices: the [scheduling] config block, its translation into the engine’s own settings, the events-bus sink adapter, and the boot wiring that starts the ticker. A recurring job now records a completed run, so it stops re-firing on every tick.

    Operator-facing work: archied setup gives the first-run flow the caller it was built for, configuration no longer accepts a secret value from the command line, and a provider whose credential is missing is disabled rather than refusing to boot. A secret engine that panics is now recovered instead of crashing the daemon.

    archie-agent

    • feat(config): add [scheduling] config block
    • fix(webui): count every chat front-end in the published projection
    • fix(scheduling): respect configuration ownership
    • feat(ratelimit): wire per-identity inbound rate limiting into the gateway
    • fix(tools): judge the rm guard by base name so absolute paths cannot bypass it
    • fix(daemon): carry kind/label routing bindings to the process that routes
    • fix(config): deep-copy Image.Hosted/Image.Local in Config.Clone
    • fix(logging): keep the live descriptor open across a failed rotation
    • fix(agentworker): wire configured tool-result policy into worker’s LoopRunner
    • refactor(staterpc): delete the superseded single-token auth interceptor
    • refactor(tools): delete unreachable dispatch/gating engine
    • feat(channels): wire chat.webhook route config through to the gateway
    • refactor(tools): delete unreachable AST-based tool discovery
    • refactor(tools): delete unused plugin-tool registration API from builtin.Registry
    • refactor(state): delete the dead IncrementRetryCount RPC (breaking change, accepted)
    • fix(staterpc): preserve marshal_error marker in eventDataJSON
    • fix(gate): validate finding level and share the blocking threshold
    • fix(tools/provider/mcp): preserve MCP binary tool results for delivery
    • refactor(tools/mcp): delete unreachable MCP adaptation path
    • refactor(skill): delete dead Discover/DiscoverPlugins/Skill path
    • refactor(skillbuild): delete dead AugmentRegistry path
    • fix(builtin): bound read/edit filesystem work by DefaultToolTimeout
    • refactor(binding): delete dead Matcher.Overlaps method
    • refactor(forge): delete dead CreateIssue surface
    • fix(mcp): cancel in-flight SSE reconnect on Stop
    • fix(container): enforce MaxUptime lifetime cap with a timer
    • refactor(forge): delete the unwired RepliesAfter surface
    • refactor(config): delete the two decoded-but-unread policy fields

    The runtime carries a smaller, more focused set of changes than the same version’s archied entry: agent-side tool-result policy is now wired into the worker’s loop, MCP binary tool results survive to delivery, the container MaxUptime lifetime cap is enforced with a timer, and a scheduled run records completion so it does not re-fire each tick.

    Note that several bullets above name config, webui and ratelimit packages. Those are attributed here by the release tool’s package-closure rule (go list -deps over the agent binary), not because the agent owns them; the substantive runtime changes are the worker, MCP, container and scheduling fixes.

    This entry also confirms the removal of the dead IncrementRetryCount State Store RPC, which the agent reaches through staterpc rather than by calling it directly.

    1.25.0

    archied

    • fix(update): resolve releases without a checkout, and fail loudly when it cannot
    • fix(update): back up the task store the daemon actually uses, or refuse
    • fix(update): build each component from its own approved release tag

    Components are independently versioned, so the newest archied/v* and archie/v* tags usually sit on different commits. The installer required both tags to resolve to one commit whenever both components changed, which refused every update once the two newest releases diverged – a deployment stuck on 1.22.0 could not take any update. Each component now builds from its own approved tag.

    archie-agent

    • chore: no user-facing changes; versioned so the 1.25.0 release tags both components at the same commit

    1.24.0

    archied

    Makes 1.23.0 deployable. That release split archied into separate processes, but the self-updater still installed only the archied binary and restarted only archied.service, so updating to it left the State Store, Gateway and UI on the previous release. archied cannot boot without a reachable State Store, so the update failed its health check and rolled back. Update to this release rather than to 1.23.0.

    If your host does not yet run the four units in deployments/systemd-user-service.md, create them first: the updater now refuses, naming what is missing, instead of installing binaries onto a host it would leave broken.

    • fix(update): install and cycle every process in the release
    • fix(telegram): stop the relay corrupting identifiers and code

    Also in this release, though outside the version-stamped package closure:

    • ci(deploy): produce a complete distribution zip on every release. No zip was built for v1.23.0 at all, and the zip omitted archie-ui.

    Page 5 of 10