Commit Graph

493 Commits

Author SHA1 Message Date
Peter Steinberger b080dd1e76 refactor: consolidate coercion contracts (#122458)
* refactor: consolidate coercion contracts

Centralize exact string, record, numeric, date, Boolean, argument, and structured-error coercions while preserving call-site semantics.

Migrate canonical-name collisions and deprecated internal SDK bypasses, deleting 55 net production/tooling lines. Expand declaration ownership enforcement to 101 allowed helpers and add a narrow export-completeness audit.

* fix: preserve standalone script coercions

Keep copied Control UI tooling self-contained and retain the trusted release harness module-relative source seam when the harness runs against an old target cwd.
2026-08-11 23:26:37 -07:00
Peter Steinberger 964c8c84c1 refactor: consolidate coercion ownership (#122299)
* refactor: consolidate coercion ownership

Centralize four canonical coercion helpers, migrate exact core and plugin duplicates through narrow Plugin SDK facades, and enforce declaration and plugin-normalization ownership boundaries.

The sweep adds eight focused SDK exports while deleting more production and tooling code than it adds. User-visible behavior is unchanged except for safer equivalent object and UI parsing at existing boundaries.

* fix: guard integer option ownership

Register resolveIntegerOption with the canonical function owner and extend the declaration-guard fixture so future local duplicates fail validation.

* fix: keep integer helpers on numeric facade

Remove the unshipped duplicate string-coerce exports and route every affected plugin consumer through the existing number-runtime contract.

* fix: point numeric coercion to number runtime

Make boundary and declaration diagnostics recommend the canonical numeric facade, with failing-before coverage for both guidance paths.
2026-08-11 17:14:53 -07:00
Ayaan Zaidi 2c8ed54ddb feat(heartbeat): default delivery to the configured owner, never groups (#121988)
Unset heartbeat.target now resolves "owner": elected heartbeat notifications deliver to the operator's DM resolved from commands.ownerAllowFrom or the channel allowFrom (first concrete entry; wildcards and channel-scoped wildcards excluded; configured owners exhausted across channels before any channel-local fallback). Delivery requires the channel's own classifier to positively prove a direct destination — every bundled messaging plugin now ships an inferTargetChatType contract — and unproven or group-shaped destinations fail closed to the visible no-route state. The first implicitly-routed delivery carries a one-line self-explanation naming the target: "none" opt-out. Explicit target "last" remains as the follow-the-conversation opt-in. Refines the unreleased #121892 default before it ships; refs #121880.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 13:18:22 +00:00
Peter Steinberger fa03d9b913 refactor: consolidate coercion helpers (#121366)
* refactor: consolidate coercion helpers

* fix: remove duplicate coercion imports

* fix: preserve serialized coercion guard

* chore: ratchet coercion helper carve-outs

* fix(test): keep gauntlet subprocess startup lean

* fix: preserve imported session timestamp semantics

* fix: preserve catalog timestamp string semantics

* chore: align plugin SDK surface ratchet

* fix: preserve trajectory and SDK string contracts

* fix(test): preserve QA record assertion semantics

* fix: complete standalone record guard rename

* refactor(cron): use canonical string coercion

* fix(acpx): preserve Pi timestamp parsing

* test(channels): adapt custody test harnesses

* test(telegram): classify media harness as test support

* test(acpx): split timestamp contract coverage

* test(channels): support generated custody contracts

* chore: ban the full coercion helper name set

Extends the declaration guard to all eleven consolidated helper names and
renames the cron schedule-identity readNumber wrapper to readScheduleInteger
so the banned generic name cannot regrow.

* fix(scripts): repair release-validation guard drift and lint cause

Restores the renamed isJsonRecord guard in assertTrustedWorkflowHarness after
main added isRecord call sites in parallel, and attaches the caught YAML error
as the thrown error cause (preserve-caught-error was red on main).

* fix: preserve Claude timestamp string semantics

* fix: preserve persisted timestamp string semantics

* fix: preserve date-first timestamp contracts

* fix(openai): harden delegation failure formatting

* chore: close coercion helper guard gaps

* test(openai): model non-error delegation rejection

* chore: refresh plugin SDK API contract

* fix(tasks): use canonical string field reader

* fix(ai): use canonical provider error field coercion

* fix(browser): migrate native bootstrap coercion

* docs(plugin-sdk): clarify text record export compatibility

* fix(gateway): normalize approval execution identity

* test(outbound): isolate message action poll harness
2026-08-11 00:02:18 -07:00
Peter Steinberger fd1b965f2b refactor(plugins): remove orphan test API barrels (#121761)
* test(plugins): remove orphan test API barrels

* refactor(plugins): remove orphan test-only exports

* refactor(imessage): remove orphan test plugin

* test(plugins): remove stale package guard timeout
2026-08-10 16:42:34 -07:00
Peter Steinberger 3b3c540896 refactor: remove dead branches and test-only helpers (#121345)
* refactor: remove dead branches and test-only helpers

* fix: preserve codex cleanup error causes

* fix: preserve gateway error code compatibility

* chore: update plugin sdk api baseline

* docs: fix live cache runner path
2026-08-10 06:47:43 -07:00
Peter Steinberger 6192673da4 perf(doctor): delete the heavy doctor barrel and finish slimming enumeration (#120882)
* refactor(plugin-sdk): delete the heavy runtime-doctor barrel

Nothing may pull the state-db/kysely graph through a doctor barrel anymore.
The barrel's remaining heavy exports move to two narrow private-local
subpaths, each with a single purpose:

- doctor-repair-runtime: install-path diagnosis, plugin config removal, and
  state-database schema detect/repair (matrix doctor, voice-call lazy import)
- plugin-state-store-runtime: the sync keyed-store factory. It stays out of
  plugin-state-runtime because hot channel entrypoints import that at module
  load and opening a store pulls the state-database graph.

Doctor closures also stop pulling ssrf-runtime (fetch-guard + gateway net)
for two legacy private-network helpers that live in the lighter ssrf-policy
subpath: mattermost, nextcloud-talk, tlon, matrix.

The closure guard now forbids the two new heavy subpaths instead of the
deleted barrel, so the invariant keeps being enforced where it still applies.

* perf(doctor): keep heavy graphs out of every doctor closure

Doctor enumeration cold-loads each declaring plugin's contract closure, so
one heavy import in a closure is paid by the whole sweep. Four barrels were
still dragging unrelated graphs in for trivial helpers; each is repaired at
the leaf rather than by caching downstream:

- Legacy private-network config migration moves to a config leaf. It only
  reshapes records, but lived beside the SSRF runtime (DNS, proxy, logging),
  costing mattermost ~2.7s. ssrf-policy re-exports it, surface unchanged.
- Streaming config readers move to a leaf. They read two config keys, but
  streaming.ts also formats tool aggregates, pulling tool-display/logging/
  acp-core; that cost slack ~2.3s.
- signal took the channel-secret barrel for isRecord; the canonical plugin
  record guard is string-coerce-runtime (root AGENTS.md).
- llm-task took the provider-model barrel for parseModelRef, now a narrow
  model-ref-parse subpath.

Full doctor enumeration of all 42 declaring plugins, built mode:
legacy config rules 6668ms -> 1265ms, state migrations 184ms -> 127ms.
No plugin remains an outlier; the slowest is now ~380ms against a ~200ms floor.

Public export surfaces of every touched SDK subpath are byte-identical
(verified by diffing built module exports before/after); the API baseline
hashes move only because re-exported declarations emit differently.

The closure guard gains rules for each repaired barrel so the invariant
holds for future closures.

* fix(release): exclude new private-local declarations from the published package

Same pack-path rule as c41da3759f: private-local subpaths ship without d.ts.

* fix(doctor): repair the closure guard violations that break main

The landed guard fails on main: three closures import heavy barrels for one
symbol each. Two more surfaced once the guard learned about the provider-model
barrel. Each gets a narrow subpath at the leaf:

- telegram sent-message-cache + state-migrations took the session-store barrel
  (session accessor + state-db) for resolveStorePath -> session-store-paths
- discord thread-bindings.state took the channel-outbound barrel (reply
  pipeline + channel registry) for one identity write -> outbound-echo-runtime
- discord model-picker took the provider-model barrel for normalizeProviderId,
  which model-ref-parse now exposes beside parseModelRef

The guard also stops walking artifacts of plugins whose manifest declares no
doctor surface. Such a declaration gates the artifact off every enumeration
path exactly as resolvePluginDoctorContracts does, so its closure cost is never
paid; anthropic ("doctorContract": {}) was being held to a cost it cannot
incur. Absent declarations still load eagerly and stay enforced.

Side effect worth naming: discord's built doctor contract now loads again.
On main both discord and telegram fail to require in packaged builds (an
ESM-only transitive dep) and silently lose their repairs; this restores
discord and takes enumerated legacy config rules from 87 to 99. Telegram's
built artifact still pulls execa through dist chunking - a build-level defect
with a different owner, filed as follow-up.
2026-08-08 22:01:44 -07:00
Peter Steinberger 75dbe52e3e refactor: one code path behind doctor legacy-state migrations (#120716)
* refactor(doctor): prefer manifest route-state owners

* refactor(doctor): unify config repair declarations

* refactor(doctor): unify legacy state migrations

* fix(doctor): satisfy migration pipeline guards

* fix(plugin-sdk): keep doctor adapter inside boundary
2026-08-08 18:23:15 -07:00
Peter Steinberger da4a656cdb improve: doctor migration checks no longer load every bundled plugin runtime (#120678)
* perf(plugins): declare doctor contract surfaces

* perf(doctor): slim migration import closures

* perf(plugins): narrow doctor declaration record surface and wire owner-test lane

Registry records carry only the doctorContract declaration instead of the whole
parsed manifest, and check:changed now selects the src/plugins-owned declaration
honesty and closure-guard tests for extension module/manifest changes so
cross-lane drift cannot pass PR classification.

* fix(doctor): keep control-plane dist imports require-safe

Keep doctor and channel control-plane chunks off exec-class dependencies, and enforce native require(esm) loading during postbuild.

* chore(plugin-sdk): regenerate API baseline

* chore(plugin-sdk): sync export ordering

* fix(plugins): satisfy doctor contract CI boundaries

* perf(doctor): make qqbot doctor closure dependency-light

qqbot was the last plugin above 5s in doctor state-migration enumeration
(~8s under tsx/jiti). The cost was not the state-key builder (already a
leaf): its doctor closure value-imported the runtime-doctor SDK barrel,
whose plugin-state-store/state-db re-exports pull kysely (~330 modules),
plus security-runtime for one fileExists (~200 modules), all resolved
per-module by jiti during enumeration.

Split the migration-define helpers and light re-exports into a new
private-local plugin-sdk/runtime-doctor-migrations subpath; runtime-doctor
re-exports it so its public surface is byte-identical (API baseline hash
unchanged). qqbot's doctor-contract and state-migrations now import only
the light subpath, swapping fileExists for the equivalent async
legacyStateFileExists already in the closure.

qqbot enumeration: ~8.0s/531 modules -> ~0.25s/18 modules.

* chore(plugin-sdk): drop private-local subpath from API baseline

runtime-doctor-migrations is private-local-only; the baseline tracks public
modules, and the earlier line was generated before the classification.

* fix(plugins): register runtime-doctor-migrations boundary paths

The private-local subpath list feeds the extension package boundary map;
the shared paths config and xai's derived overrides must carry the same
entry or the boundary contract test fails.
2026-08-08 13:29:18 -07:00
Peter Steinberger 48639663b0 chore(release): prepare 2026.8.1 (#120375) 2026-08-07 18:44:12 -07:00
Patrick Erichsen 1aea2df935 fix(plugins): refresh bundled channel skills (#119020) 2026-08-03 17:31:00 -07:00
Jesse Merhi 68be0e3378 feat: enable rich setup controls in custodian chat (#114631)
* feat(protocol): carry the awaited wizard step on the chat result

* fix(system-agent): strip sensitive wizard prefill from chat results

* fix(wizard): keep setup secrets server-side

* test(wizard): preserve prompt mock typing

* fix(ui): add reveal toggle to wizard secrets

* refactor(ui): adopt Carapace sensitive input

* fix(ui): hide revealed sensitive input mask

* test(twitch): cover environment-only setup

* feat(custodian): render rich wizard steps

* fix(custodian): validate wizard text replies

* feat(custodian): submit typed wizard answers

* refactor(gateway): isolate custodian chat turns

* fix(gateway): accept session engine adapter

* fix(ui): narrow wizard control values

* refactor: simplify rich wizard answer flow

* fix(custodian): recover evicted wizard sessions

* docs: note custodian rich setup controls

* test(gateway): split wizard answer coverage
2026-08-03 22:18:27 +10:00
Peter Steinberger 7764cc544c test(tlon): dedupe upload hardening fixtures (#118320) 2026-08-02 17:18:54 -07:00
NIO df8cc5a458 fix(tlon): cancel unread channel-ops and SSE connect bodies (#111275)
* fix(tlon): cancel unread channel-ops and SSE connect bodies

* fix(tlon): own guarded response cleanup across transports

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-01 23:09:51 -07:00
Peter Steinberger ccee629359 refactor(plugins): delete registry compat scaffolding (#117749)
* refactor(plugins): delete registry compat scaffolding

* test(plugins): update CLI registry handle mock

* fix(plugins): preserve explicitly initialized hook registries

* test(plugins): update registry ownership fixtures

* fix(channels): restore registry snapshot memo
2026-08-01 21:18:47 -07:00
chenyangjun-xy 8d7b858685 fix(tlon): honor configured user timezone in summarization history (#117429)
Channel history timestamps in summarization requests were rendered with
new Date().toLocaleString(), using the host process timezone instead of
the configured agents.defaults.userTimezone. Reuse the shared inbound
envelope formatter (formatAgentEnvelope + resolveEnvelopeFormatOptions)
so timestamps match the user timezone, consistent with Mattermost/Feishu.

Adds formatSummarizationHistoryText with coverage for the UTC baseline
and non-UTC offsets.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-01 14:29:41 -07:00
zengLingbiao c539192b5c fix(tlon): cancel unread error bodies in urbit channel ops (#117475)
* fix(tlon): cancel unread error bodies in urbit channel ops

* fix(tlon): start error body cancellation without awaiting it
2026-08-01 14:12:06 -07:00
chenyangjun-xy b24881eb04 fix(tlon): chunk outbound text over the declared delivery limit (#117438)
* fix(tlon): chunk outbound text over the declared delivery limit

* fix(tlon): guard optional outbound adapter in chunking test

* test(tlon): prove chunked outbound over real urbit loopback
2026-08-01 13:19:51 -07:00
Peter Steinberger 568ea29d2e refactor(plugins): inherit shared package boundary settings (#117474) 2026-08-01 09:11:09 -07:00
Ayaan Gazali 11069c3df5 fix(channels): config validation rejects documented channels.<id>.configWrites on 13 channels (#117206) 2026-08-01 15:33:16 +08:00
ml12580 02457657f0 fix(tlon): wire autoDiscoverChannels through the settings-store round-trip (#114949)
parseSettingsResponse and applySettingsUpdate read/wrote a dead
`autoDiscover` key, while every consumer (monitor/settings-helpers.ts)
and the settings migration use `autoDiscoverChannels`. As a result the
settings-store hot-reload override for auto-discover-channels never took
effect and the migration re-fired on every restart. Align the field name
and add a regression test covering both the load and subscription paths.

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-31 20:05:16 -07:00
Peter Steinberger 9e4381eb1c refactor(channels): unify bundled channel setup contracts (#117106)
* refactor(channels): canonicalize bundled setup contracts

* test(matrix): use scoped environment fixtures
2026-07-31 16:57:29 -07:00
wahaha1223 030dbe9a7e fix(tlon): stop SSE reconnects after client close (#108168)
* fix(tlon): stop reconnecting after SSE client close

* fix(tlon): cancel SSE reconnect timers when monitoring stops

Preserve the original Tlon SSE reconnect fix while canceling both retry timers at stopReceiving(), the real monitor shutdown boundary.

Verified against an authenticated, SSRF-guarded loopback SSE server; both reconnect waits settle immediately without changing replay, close cleanup, or uninterrupted reconnection.

Co-authored-by: wahaha1223 <0668001153@xydigit.com>

* fix(tlon): prepare conflict-free reconnect refresh

Prepare a conflict-free refresh of the original Tlon SSE shutdown correction without changing its ownership or losing the contributor commit.

Co-authored-by: wahaha1223 <0668001153@xydigit.com>

* fix(tlon): cancel reconnect timers when monitoring stops

Cancel both Tlon SSE reconnect waits at stopReceiving(), the monitor-owned shutdown boundary, while preserving guarded HTTP, durable same-channel replay, and the original contributor's fix.

Verified with authenticated loopback SSE, both real retry delays, normal reconnection, all 252 Tlon tests, extension type checks, lint, and focused owner regressions.

Co-authored-by: wahaha1223 <0668001153@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-29 12:49:11 -04:00
Peter Steinberger 986e5d1758 refactor(channels): share ingress retention defaults (#115824) 2026-07-29 06:24:30 -04:00
Peter Steinberger bde6b166c0 refactor(channels): deduplicate ingress monitor shells (#115792)
* refactor(channels): deduplicate ingress monitor shells

* fix(channels): preserve ingress error overload types

* fix(channels): type ingress error overload implementation

* chore(plugin-sdk): ratchet ingress error surface
2026-07-29 05:33:00 -04:00
Peter Steinberger 4232126bba chore: update dependencies across workspace (#115677)
* chore(deps): update dependencies

* fix(deps): restore CI compatibility
2026-07-29 05:16:42 -04:00
Peter Steinberger 302f262e6b refactor: deduplicate extension normalization primitives (#115650)
* refactor(plugins): reuse SDK normalization primitives

* fix(ci): repair code-mode matrix checks

* fix(ci): satisfy code-mode matrix gates

* fix(ci): use matrix evidence export

* fix(ci): validate matrix evidence artifact
2026-07-29 04:10:06 -04:00
SunnyShu 07c4f7b721 fix(tlon): use waitUntilAbort to fix monitor abort-race hang (#114940)
* [AI] fix(tlon): use waitUntilAbort to fix monitor abort-race hang

Replace ad-hoc abort listener with the shared waitUntilAbort
primitive, hoist pollInterval for unified finally cleanup, and
add .unref() per codebase convention.

The original code registered an abort listener inside a Promise
constructor without checking signal.aborted first. Per the
AbortSignal contract, a listener attached after abort has fired
is never called, so the monitor hung without running cleanup.

The fix reuses waitUntilAbort from plugin-sdk/channel-outbound,
which correctly handles already-aborted, normal, and absent
signals. pollInterval is hoisted and cleared in finally as a
single cleanup owner.

Co-Authored-By: Claude <noreply@anthropic.com>

Fixes #114886

* fix(tlon): prove abort-safe Urbit monitor cleanup

---------

Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
2026-07-28 06:53:37 -04:00
Peter Steinberger 08b1ff73e2 refactor(channels): fix account resolution and setup isolation (#114395)
* refactor(channels): fix account resolution and setup isolation

* fix(channels): keep account resolvers safely destructurable
2026-07-27 03:49:37 -04:00
Peter Steinberger f6131a4fbf build(deps): remove npm shrinkwrap; mirror pnpm lock into transient package locks (#114006)
* build(deps): remove npm shrinkwrap; mirror pnpm lock into transient package locks

npm 12 removed shrinkwrap (command + tarball/root loading). Delete all 82
committed npm-shrinkwrap.json files and stop publishing lockfiles; keep
pnpm-lock.yaml as the single reviewed dependency boundary. The generator
becomes scripts/generate-npm-package-lock.mjs and feeds plugin bundling via
a transient package-lock.json + npm ci (works on npm 11 and 12). Tarball
validation treats the published 2026.7.2 beta train as a shrinkwrap
transition; self-update npm detection now uses install topology instead of
the shipped shrinkwrap.

* fix(deps): repair lint, deadcode, and test-type lanes for the npm 12 migration

- sort integrity comparisons with an explicit comparator (oxlint)
- keep resolveBunGlobalNodeModules module-local (knip unused-export gate)
- model npm pack --json as npm<=11 array / npm 12 name-keyed object
- default calver destructuring in the tarball test fixture
2026-07-26 01:29:55 -04:00
Peter Steinberger 26cb29a171 refactor(channels): finish factory migrations for line/tlon/zalouser (#113646)
* refactor(line): use shared DM policy factory

* refactor(line): use shared channel probe runner

* refactor(zalouser): use shared channel probe runner

* refactor(tlon): use shared channel probe runner

Honor the status adapter timeoutMs instead of discarding it.

* refactor(line): use canonical inbound context builder

* refactor(line): drop stale setup policy export

* fix(tlon): honor adapter probe timeoutMs
2026-07-25 05:46:32 -07:00
Peter Steinberger acd92f6a3d chore(deps): refresh repository dependencies (#112453)
* build(deps): update QA broker dependency

* build(deps): refresh repository dependencies

* build(deps): reconcile rebased shrinkwraps

* test(plugins): remove stale loader test state

* test(deps): stabilize updated dependency coverage

* fix(swift): use caller-isolated TaskLocal overload

* build(deps): regenerate rebased shrinkwraps

* test(msteams): preserve DNS validation in fetch helper

* fix(deps): avoid vulnerable optional image stack

* test(deps): validate generated LRU override

* refactor(ui): extract chat resizable divider

* test(ui): update divider ownership path

* fix(matrix): retain restart-compatible SDK

* style(cron): format update test
2026-07-23 16:17:13 +00:00
Peter Steinberger 9b050232a1 feat(tlon): render Markdown lists as native listings (#112968)
* feat(tlon): render markdown lists natively

* fix(tlon): preserve unsupported loose lists
2026-07-23 03:48:48 -04:00
Jesse Merhi 4a2a600809 feat(channels): add channel-owned setup contracts (#112176)
* feat(channels): add channel-owned setup contracts

* test(channels): align legacy setup fixtures

* chore(channels): regenerate config and SDK baselines after rebase

* fix(update): run fresh doctor after current-process core changes

* fix(channels): align add pre-scan with execution precedence

* style(cli): format channels-cli test additions

* fix(channels): restore option-before-positional channel resolution via metadata arity scan

* fix(channels): keep help flags out of metadata arity escalation

* test(update): mock fresh post-update doctor in current-process suites

* style: format review fixes and correct entrypoint mock type

* fix(channels): register only modern contract options for dual-publishing plugins

* test(update): align downgrade suites with fresh-doctor child invocation

* docs(channels): record empty-contract and input-forwarding invariants

* fix(line): keep the shipped --token switch as a channel access token alias

* fix(signal): stop treating exact cross-family loopback endpoints as bind-aligned

* chore(config): regenerate docs config baselines after second rebase

* style: format rebased channels add tests

* fix(channels): enforce field-key and flag-name agreement in setup contracts

* fix(signal): detect container endpoints for bare --http-url setup

* fix(signal): ignore unconfigured accounts in transport collision checks

* fix(channels): validate negated setup flags in contract and normalizer

* fix(signal): preserve existing transport kind when setup detection is unreachable

* style(signal): use direct boolean check in collision guard

* style(signal): type test config literals

* docs(update): record two-read design of fresh-doctor validation gate

* fix(channels): satisfy post-rebase architecture gates

* docs: refresh channel setup map

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-22 19:57:42 -04:00
Peter Steinberger a95c059f11 feat(media): thread ordered media facts through the prompt path (#112601)
Media-facts program PR 5 — the planned additive bridge. Structured
facts travel alongside existing prompt text through prompt prelude,
GetReplyOptions, FollowupRun, queue collect/defer/retry, active
steering, embedded/CLI runs, Gateway offloads (offloadedRefs no longer
discarded; AgentContentPhaseResult carries media), Tlon, and late-media
projection — with prompt bytes golden-equal everywhere. Facts follow
the same adoption/idempotency/late-append lifecycle as prompt text.
Intentionally +175 prod LOC per the audit; the facts-first
hydration/prune deletion PR consumes this carrier next.
2026-07-22 01:14:49 -07:00
Peter Steinberger f236e83de7 refactor(channels): shrink ChannelSetupInput to a generic envelope with a deprecated compatibility tier (#112319)
* refactor(channels)!: shrink ChannelSetupInput to a generic envelope with a deprecated compatibility tier

* fix(channels): keep ChannelSetupInput structurally assignable without an index signature

* docs: regenerate docs map
2026-07-21 22:17:03 -07:00
Peter Steinberger edecdbd05e refactor(config): config-surface reduction tranche 3 — product consolidations (review request) (#111527)
* refactor(config): consolidate media model lists

* refactor(config): unify memory configuration

* refactor(config): consolidate TTS ownership

* refactor(config): move typing policy to agents

* refactor(config): retire product-level config surfaces

* refactor(config): share scoped tool policy type

* chore(config): refresh generated baselines

* fix(config): honor agent typing overrides

* fix(config): migrate sibling config consumers

* refactor(infra): keep base64url decoder private

* fix(config): strip invalid legacy TTS values

* chore(config): refresh rebased baseline hash

* fix(doctor): route legacy messages.tts.realtime voice to talk during tts move

* refactor(config): polish final layout names

* refactor(config): freeze retired tuning defaults

* feat(config): add fast mode default symmetry

* refactor(config): key agent entries by id

* docs(config): update final layout reference

* test(config): cover final layout migrations

* chore(config): refresh final layout baselines

* fix(config): align final layout runtime readers

* fix(config): align remaining readers

* fix(config): stabilize final layout migrations

* fix(config): finalize config projection proof

* fix(config): address final layout review

* docs(release): preserve historical config names

* fix(config): complete keyed agent migration

* fix(config): close final migration gaps

* fix(config): finish full-branch review

* fix(config): complete runtime secret detection

* fix(config): close final review findings

* fix(config): finish canonical docs and heartbeat migration

* fix(config): integrate latest main after rebase

* refactor(env): isolate test-only controls

* refactor(env): isolate build and development controls

* refactor(env): collapse process identity indirection

* refactor(env): remove duplicate config and temp aliases

* docs(env): define the operator-facing allowlist

* ci(env): ratchet production variable count

* fix(env): remove stale provider helper import

* fix(env): make ratchet sorting explicit

* test(env): keep test seam in dead-code audit

* test(env): cover ratchet growth and boundary; document surface budgets

* docs(config): document tier-eval consolidations

* docs(config): clarify speech preference ownership

* test(memory): align retired tuning fixtures

* refactor(memory): freeze engine heuristics

* refactor(config): apply tier-eval tranche

* refactor(tts): move persona shaping to providers

* refactor(compaction): move prompt policy to providers

* test(config): align hookified prompt fixtures

* chore(deadcode): classify test-only exports

* chore(github): remove unused spawn helper

* chore(deadcode): classify queue diagnostics

* chore(deadcode): remove unused lane snapshot export

* chore(plugin-sdk): ratchet consolidated surface

* fix(config): integrate latest main after rebase
2026-07-21 20:28:43 -07:00
Peter Steinberger e1d5d3dc16 refactor(channels): move single-account promotion keys to plugin declarations (#112293)
* refactor(channels): move single-account promotion keys to plugin declarations

* fix(channels): keep legacy promotion tier for undeclared setup adapters

* fix(channels): keep plugin discovery lazy in setup promotion helpers

* fix(channels): resolve bundled promotion surfaces from setup-only artifacts

* test(matrix): use vi.stubEnv in setup test env helper
2026-07-21 06:48:30 -07:00
Peter Steinberger d725632ee7 refactor(channels): move channel-flavored setup flags into plugin manifests (#112239)
* refactor(channels): move channel-flavored setup flags into plugin manifests

* refactor(channels): normalize manifest cliAddOptions formatting, drop changelog entry

* fix(channels): dedupe channels add options by commander switch identity

* fix(channels): let the selected channel's cliAddOptions win switch dedupe
2026-07-21 02:50:19 -07:00
mikasa 1e7318e072 fix(tlon): stop monitor tracking state from growing forever (#103658)
* fix(tlon): bound monitor tracking state

* fix(tlon): fence invite snapshot generations

* fix(tlon): simplify bounded monitor tracking

Co-authored-by: mikasa0818 <0668001030@xydigit.com>

* fix(tlon): keep thread limit internal

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-20 22:00:47 -07:00
Peter Steinberger e024aa38b9 fix(tlon): cancel failed auth response bodies (#112059) 2026-07-20 21:23:00 -07:00
LZY3538 4e9b1f4775 fix(tlon): bound Urbit auth response body drain to prevent OOM (#109697)
* fix(tlon): bound Urbit auth response body drain to prevent OOM

Replace the unbounded response.text() body drain (discarded after reading
to finalize set-cookie headers) with a streaming reader capped at 64 KiB.
When no body stream is available, fall back to text() for compatibility.
A hostile or misconfigured Urbit endpoint could previously stream an
arbitrarily large body into memory during login.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(tlon): add curly braces to drain loop for lint compliance

* fix(tlon): remove unbounded text() fallback, cancel reader in finally

Remove the unbounded response.text() body-less fallback path. When no body
stream is available, there is nothing to drain — cookie headers are already
finalised. Move reader.cancel() into a finally block so the reader is
released even when read() throws.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-20 20:05:36 -07:00
Peter Steinberger 938e3d5f20 refactor(channels): share durable ingress monitor (#111186)
* refactor(signal): share durable ingress monitor

* refactor(slack): share durable ingress monitor

* refactor(discord): share durable ingress monitor

* refactor(imessage): share durable ingress monitor

* refactor(twitch): share durable ingress monitor

* refactor(tlon): share durable ingress monitor
2026-07-18 21:33:09 -07:00
Alix-007 84ad63ef00 fix(tlon): reject unusable setup URLs (#111099)
* fix(tlon): reject unusable setup URLs

* fix(tlon): preserve validated partial setup

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 20:47:13 -07:00
Wynne668 5bb969f7de fix(tlon): preserve shutdown when body cancellation fails (#111106)
* fix(tlon): observe shutdown body cancellation failures

* test(tlon): streamline shutdown cleanup proof

* test(tlon): narrow shutdown fixtures

---------

Co-authored-by: ZengWen-DT <290981215+ZengWen-DT@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 19:32:04 -07:00
sunlit-deng 4dbeb84c25 fix(tlon): account checks leave streaming responses open (#111081)
* fix(tlon): release account probe response bodies

* test(tlon): assert probe cleanup ordering

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 19:18:30 -07:00
Wynne668 37b0b12eb7 fix(tlon): release failed upload response bodies (#110442)
* fix(tlon): release failed upload response bodies

* fix(tlon): settle guarded upload responses

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-18 21:19:03 +01:00
Peter Steinberger 138d2d071c feat(tlon): add durable ingress (#110910) 2026-07-18 20:19:04 +01:00
Peter Steinberger 31ed59bdf6 feat: keep main agents aware of group activity (#110332)
* feat(sessions): auto-watch group activity from main

* feat(sessions): allow watchers to read watched sessions

* fix(sessions): skip group watches for system turns

* fix(sessions): preserve watched session semantics

* fix(channels): propagate effective dm scope

* fix(sessions): canonicalize main watch identity

* fix(sessions): distinguish ambient group watches

* fix(sessions): revoke ineligible ambient watches

* chore: drop CHANGELOG edit (release generation owns it)
2026-07-18 04:06:58 +01:00
Peter Steinberger 0e792b6de3 refactor(channels): centralize inbound orchestration and remove internal compat (#109716)
* refactor(channels): centralize inbound turn orchestration

* refactor(runtime): remove stale compatibility paths

* chore(guards): reject internal deprecated API use

* refactor(channels): simplify core turn planning

* chore(guards): keep deprecated checks boundary-focused

* refactor(memory): keep modern config off compat barrel

* fix(msteams): preserve feedback learning

* test(channels): align modern inbound fixtures

* refactor(channels): finish modern inbound migration

* refactor(channels): tighten core inbound kernel

* fix(channels): preserve turn assembly narrowing

* test(sdk): keep runtime mock binding immutable

* test(matrix): isolate read policy runtime

* test(msteams): mock canonical reply factory

* test(slack): mock core inbound turn dispatch

* test(telegram): inject core session recorder

* test(signal): inject core session recorder

* test(googlechat): assert canonical inbound routing

* test(synology-chat): align core turn fixture

* fix(sdk): preserve direct DM runtime compat

* refactor(channels): own inbound envelope compat in core

* refactor(channels): trim inbound dispatch seams

* refactor(channels): remove redundant async wrappers

* test(synology-chat): type canonical dispatcher mock

* refactor(channels): remove remaining dead compat seams

* chore(sdk): refresh API baseline after rebase

* fix(channels): preserve direct DM identity metadata
2026-07-17 00:56:46 -07:00