Imported from lidge-ai/cli-jaw (
structure/AGENTS.md). Install upstream withnpx skills add lidge-ai/cli-jaw --skill structure. Copyright stays with the author.
📚 INDEX · Sync Checklist · Commands · Server API · Stream Events · str_func
structure/ — Sync Guide
- The canonical desktop release workflow must Developer ID-sign macOS with Team
U9ATA49N28, notarize, staple, verify the final app, and verify channel metadata plus the update ZIP SHA-512 before upload.electron:dist:mac:signedis the equivalent opt-in local path; ordinaryelectron:dist:macremains ad-hoc. Windows remains unsigned. Keep README andinfra.mdaligned; fixture tests do not prove a signed/notarized artifact, and the first signed release is a manual-DMG bootstrap before in-app updates can be trusted.
Electron Builder 26 copies sidecar node_modules through an explicit extraResources FileSet with the sidecar exclusions preserved; local default/signed macOS commands and every desktop release matrix leg must smoke the packaged server tree after packaging and before upload.
-
Auto (
permissions:auto) grants qualified direct-local Jaw API authority across supported runtimes, independently of per-turn secrets. Keep actual/effective loopback, exact browser origin, proxy provenance, explicit outbound destinations and server-only resource options. Safe/custom keep existing scoped/operator paths; full API authority is instance-wide, distinct from provider Safe and task scope. Preserve no-descendant/read-only assignments, captured worker context and honest capability/receipt evidence. See../docs/slack-tools.mdandserver_api.md. -
Slack group DMs use
message.mpim, which requiresmpim:history— without it group DMs do not arrive at all; existing IM/channel installs keep working and merely report the optional capability gap. Exactchannel_type: mpimmentions retain channel allowlist and thread policy, never the one-to-one DM bypass. an absent scope header is unknown and a present empty header is a known empty grant. Keeptelegram.mdand the validation API docs synchronized. -
Native Code: synchronize
runtime-integration.md,server_api.md,INDEX.mdand root guides forsrc/code-mode/and/api/code. Code uses separate per-backend storage and direct native adapters; preserve append/status replay, complete active snapshots, byte budgets, early resource registration and physical-exit proof. Interruption must seal callbacks before owner-checked accepted-buffer persistence; both hosts usesrc/routes/code-body-parser.tsfor Code envelope/decoded limits. Compact replay has one carve-out: a Claude rollback deletes the removed items and their events, so replay from below itsreplay_floor_sequenceanswersinvalid_sequenceand a higherhistoryGenerationmeans a new snapshot. Private prompt boundaries never reach the wire, the fork is verified before one CAS commit, and the source native session is never changed. -
Linux
/api/file/openacknowledges asynchronousxdg-openlaunch, not desktop application success. Keep detached/ignored-stdio dispatch and launch-error handling; never wait synchronously for the opener. Seeserver_api.md. -
Sidecar build/smoke: sync
infra.mdand root notes for transactional source/stage/lock ownership, runtime-candidate/seal matching, outside-checkout target-Node execution, preserved asset/prune/native/no-JWC gates and explicit retained evidence/cleanup. Ordinary import, live server readiness and final packaged native UI are separate proofs; no timeout or skipped green. -
Isolated desktop QA:
src/shared/isolated-qa.tsowns opt-in role paths/strict ports/child env; Electron, dashboard CLI and Manager enforce the captured launch policy before their owned side effects. Keep the supervisor-before-import boundary, no global registration/installer or foreign scan/peer/lifecycle actions, normal-mode compatibility and lifetime-safe QA cleanup explicit ininfra.mdand root docs. Do not conflate mocked/compiled launch checks with final packaged native UI proof. -
Keep this folder aligned with the live
cli-jawtree;INDEX.mdlists the public architecture docs and support tools. -
Private plans, audits, evidence, and history belong only in a separate sibling clone of cli-jaw-internal; request access through an issue. Never create private records inside this checkout, including
devlog,_plan,_fin, or.jwcaliases at any depth, even when generic skill defaults suggest them.docs/andstructure/are for public product documentation; omit private record paths from public docs and source. Agent harness state under the gitignored.codexclaw/(sessions, goalplans, ledgers) is local tool state, not a record store: plans, audits and reviews never go there either. -
Update
INDEX.mdwhenever a doc is added, removed, renamed, or re-scoped. Keep the doc map, tier list, and quick links in sync. -
Update
str_func.mdfile-tree entries when files are added, removed or renamed inserver.ts,src/routes/*,src/cli/handlers*.ts,src/cli/api-auth.ts,src/manager/*(multi-instance dashboard),bin/commands/*,bin/star-prompt.ts,tests/,public/, or generated-dist exclusions change.verify-counts.shchecks that every file-tree entry instr_func.mdpoints at a real file (it records no line counts). -
stream-events.mdis the SSE/WS/event-trace companion forfrontend.md,server_api.md, and the ProcessBlock pipeline. KeepGET /api/events, replay behavior, and fallback WS current. -
When a command, API, UI, memory, or orchestration surface changes, sync the relevant doc(s) in this directory in the same change.
-
Route refactors belong in
INDEX.md,server_api.md,infra.md, andstr_func.md. CLI handler splits and auth helper changes belong incommands.md,memory_architecture.md,telegram.md, andstr_func.md. -
Manager sidebar selection and Sessions/Stop/Open use separate interactive targets. Keep list navigation scoped to the focused row selector, stable session-disclosure links, and preferred width separate from viewport clamping. Pointer and keyboard resize completion persist the latest value; see
frontend.md. -
Manager terminal presentation preserves backend PTY ownership across hide/unmount. Keep hydration-first bounded creation, explicit recovery, stable tab identity and focus ownership separate from native Code API sessions; theme updates must not recreate shells. See
frontend.md.
Current sync hotspots (2026-06)
-
Recent non-strict hotspots: Workbench modernization uses a one-row Activity header with Codex-style expanded rows/groups; the Workbench Settings tab and the command-bar gear are both removed, leaving the sidebar rail as the only settings entry point; it renders manager scope only and Meta+, opens it. A unified settings registry separates Instance/Manager scopes and shares the standalone
dist/settingsentry with the Classic header-gear settings page; Classic uses the t3 token shell. Preserve per-page save owners, dirty guards, Preview iframe identity and independent live Requests; seefrontend.md. -
Classic retained Activity: keep
activity-history.ts(discovery disclosure removed 260908), the one-rowactivity-view.tssummary header, shared fixed-through reads, MESSAGEwithSession=1and exact saved-answer lookup in sync. TUI retains its discovery reader. Preserve stored scope, unrelated live progress, namespace/ID separation, bounded queue/eviction and80-row raw paging. Old metadata-free cache is not chat authority; fork answers never acquire original Trace access. See frontend/API/runtime docs. -
Classic live Activity:
activity-state.ts/activity-replay.tsown bounded preview state;activity-view.tsowns disclosure,activity-live.tsuses injected host actions to avoid the legacy renderer SCC. Preserve original snapshot/request bridge ownership, shared bounded pre-admission event/gap queue, native-absent diagnostic separation, late canonical/public final reconciliation and captured-scope cache correction. Additive VS hooks must not replace existing lazy/post callbacks. Cold transcript history has a separate bounded reader owner; live remounting alone does not restore it. Keep frontend/stream/root notes aligned. -
presentation.modedefaults/activity and Legacy opt-in sharesrc/shared/presentation.tswith the existing identity parser. Explicit known mode and/or eligible transport-only API patches preserve admitted ownership and captured completion buckets; mixed execution changes and external-file transport edits retain invalidation. Keep legacy presentation-subtree side-effect skips separate from this strict exception. Keep config/ingress/runtime-settings side-effect boundaries, Classic preference generation/bounded reads, Manager Display draft/instance guards and Classic, retained history, Manager and TUI ownership synchronized in frontend/API/runtime docs. No transport-default migration or messaging restart is implied. -
Print Activity observer/accepted parser hooks, exact-pointer terminal recovery and latest run-scoped tool merge are documented in runtime/stream/spawn/API docs. Preserve lifecycle-selected final, native terminal defaults, trace-failure containment and current channel sends. Snapshot known-omission is a conservative retained loss signal, never a sum of overlapping source counts or a claim of complete reconstruction.
-
Interactive TUI Activity is now connected: Ctrl+O disclosure, read-only F6 journal/Enter and saved-answer/A views, snapshot-owned admission, exact MESSAGE over compatibility, missing-journal receipt binding and old-run cleanup isolation. Keep GET/queue bounds, original history scope, paste-drain lifetime, terminal sanitation/shared cell geometry and draft-safe late line output. Commit queue acceptance is not flush; release payload only after actual native commit. Raw/simple unchanged. Sync commands/frontend/stream/tui-scrollback/root notes; final integrated Electron QA remains separate.
-
Durable Activity journal: synchronize trace owner columns/original-message backfill, six native/print admission headers, internal append/public replay separation, explicit-session raw drawer reads, immutable event/first-loss control and whole-prefix retention in runtime/API/stream/infra docs. Current finality and messaging contracts remain independent; no Activity display/default rollout is implied by journal availability.
When refreshing docs from recent non-strict commits, check these first:
-
src/orchestrator/parser.ts/pipeline.ts:/continueis slash-only; do not document natural-language continue as resume. -
src/cli/commands.ts/src/cli/handlers/session-handlers.ts/src/core/chat-sessions.ts: slash registry currently includes 55 commands total / 54 non-hidden (only/filehidden), with/queueCLI-only and hidden from cmdline. Keep quoted-argumenttokenizeArgs(), Levenshtein unknown-command recovery,/goalplan,/gd,/review,/search,/queue,/task, and/forkreflected incommands.md. -
src/prompt/templates/a1-system.md/src/prompt/templates/skills.md/skills_ref/jaw-search/SKILL.md/skills_ref/jaw-browser/SKILL.md: Korean/source-sensitive search defaults to native cli-jaw search with focused query rewrite + original-page verification;agbrowse research planis optional planning help only. Private runtime skills such ask-writing(Korean promotional/content writing; retired label:k-thread-gen) andlecture-sttare active-skill deployments, notskills_refpublic entries. Route Korean promotional/content writing through activek-writing, not free-form prose or the retired label. -
src/agent/lifecycle-handler.ts/src/trace/redact.ts: retry docs should mention exponential backoff attempt metadata and trace redaction should include AWS, Anthropic, JWT, and expanded secret key patterns. -
src/cli/commands.ts/src/cli/handlers-workflows.ts/src/cli/handlers-search.ts/src/command-contract/catalog.ts/src/workflows/*: workflow helper commands are/plan,/interview,/deliberate,/planaudit,/review,/search, and/goal;/planis a PABCD P compatibility guide, not a second planning mode;/searchis search-skill routing that discovers candidate URLs before browser commands; bounded automation belongs under/goal run ..., not a top-level/autopilot; keep/planauditremote-safe and do not document/plan-auditas registered unless an interface-aware alias layer exists. -
src/agent/args.ts+src/agent/spawn.ts: Gemini full-access must keep auto-approval and pass OS home roots through--include-directoriesso cwd-external folders do not fail withPath not in workspace; WSL should include both Linux home and the Windows user home when discoverable. -
src/shared/tool-log-sanitize.ts: bounded tool-log storage/delivery protects Web UI and Manager ProcessBlock hydration. -
src/core/platform-kind.ts: canonical platform classification (windows-native | wsl | linux | darwin | other).process.platformdecides first, so awin32process is neverwsl, andWSLENVmust never be treated as a WSL signal — Microsoft shares it with the Windows host, which is what madedoctor/postinstallmisfire on native Windows.browser-open.ts,browser-open-default.ts,browser/connection.ts, andbin/commands/doctor.tsdelegate to it;bin/postinstall.tsasks the separate launch-origin question viaisWindowsNodeLaunchedFromWsl+resolveInvocationCwd.src/lib/tui/terminal.tsis excluded on purpose (vendored, outside the roottsconfig). Do not add a new hand-rolled WSL check. -
Slack text sends preserve Markdown and explicit Block Kit
blocks, splitting multiple tables into separate messages.ok:truemeans every chunk was posted, independently of rendering verification. Inspectdelivery.verification(verified,failed, orunavailable) anddelivery.messagesfor each posted chunk's timestamp, verification error, table-content status, and feature evidence. A persisted mismatch isfailed; missing permission, unavailable/malformed readback, or a missing timestamp isunavailable. Neither stops remaining posts or triggers reposting. Actual validation/POST failures retainok:false; partial receipts includepostedChunks,totalChunks, andsent:true, retryable:false. Never blindly resend posted chunks.tableContentcompares ordered text, numeric value/display, links and supported styles; ordinary Markdown character references decode once while code and escaped ampersands stay literal.richContentandsourceAccuracyremainnot_checked, and readback stays bounded to 1 MiB. -
src/messaging/send.ts+src/routes/messaging.ts:/api/channel/sendis canonical outbound channel delivery. Concurrent inbound gateway:messaging.enabledChannels(array) +messaging.homeChannel; legacysettings.channelis a deprecated read-only alias for one major version; restart only affects changed channels. Heartbeat destination send afterresolveHeartbeatBindingmay set in-processfullAccess; HTTP JSON cannot. Slack Socket reconnect defaults to unlimited (src/slack/socket.ts); a finite ceiling is caller opt-in andlink_disabledstays terminal. -
Mid-run steer defaults to
'steer': Codex App uses in-band input; native Cursor uses original-cancelled-response/drain/idle followed by same-session cancel-reprompt. Its separatereplaceTurnhook and local-dispatch commit barrier keep one logical final and never queue fatal failures. Preserve the remaining runtimes' existing kill/salvage behavior and explicit followup/collect queues;/queue steerremains a separate forced interrupt. Syncprompt_flow.mdandcommands.md. -
src/prompt/conversation-context.ts+src/agent/spawn.ts: Slack Boss turns get explicitchannel_idand parentthread_tsin the per-turn user prompt regardless of multi-session state; keep this separate from the cache-stable system prompt and internal session labels. -
src/slack/mention-watch.ts+src/slack/mention-watch-match.ts+src/memory/heartbeat-mention-watch.ts+src/memory/heartbeat.ts+src/messaging/forwarder-origin.ts: Slack mention watching is an opt-inmentionWatchmode insiderunHeartbeatJob, not a daemon. OptionaluserIds+conditions(mention|talk) keep the default as mention-of-userId; talk is opt-in and inboundmentionOnlystays a different gate. It uses bot-tokenconversations.historybecausesearch.messagesis user-token-only, keeps per-channel frontier/resume state, rotates channels, stops a tick on 429, reports overflow beyond 60 channels, and re-intersects the configured non-empty channel subset with the live allowlist. Each hit yields to PABCD/agent/message-queue/pending-replay work; the agent returns answer text only, the server sends it to the source thread and records seen after success, and producer-ownedheartbeatoutput bypasses channel forwarders. Delivery is at-least-once. The answer turn runs with the answered thread's ownchatSessionIdbut in a dedicatedmention-watch:<remoteKey>execution scope, never the thread's inbound scope: sharing it would make the background turn visible as busy to the next human message, which is then steered into it instead of starting its own run. That per-thread placement also replaces the global-only yield withgetState(remoteKey) === 'IDLE'+hasChatSessionWork(chatSessionId)+ a non-blockingsessionLanes.hasPendingcheck, and the session is minted only once a hit is actually being answered because a remote-bound session row cannot be deleted afterwards. -
src/memory/mention-watch-ledger.ts+src/memory/legacy-mention-watch-quarantine.ts+src/slack/verified-workspace.ts: The receipt/cursor ledger is keyed by (jobId, workspaceId, userId): Slack identifies a person as (team_id, id) and one runtime can re-authenticate against a different workspace, so a job-only key hands one person's cursor to another. The workspace id comes from a bot-tokenauth.testcached per token, never from mutablesettings.slack.teamId, and a failed lookup skips the tick rather than guessing. Pre-v2 ledger rows carry no workspace or user, so a job holding them is HELD out of scheduling until an operator restarts it with a freshsincethroughPOST /api/heartbeat/:jobId/mention-watch-fresh-start; the hold is durable in SQLite becauseheartbeat.jsonis operator intent while the hold is the system's judgement, and a downgrade that writes v1 rows again re-quarantines. A duplicate job id in one PUT is a 400, since two jobs under one id share one namespace. -
src/core/config.ts+src/routes/settings.ts+bin/commands/init.ts/slack.ts+ Slack Settings UIs: configuredSLACK_*variables own their matching fields at runtime. API snapshots expose variable names only; Settings/reset and CLI setup stay conservatively locked while any are present, generic mutation rejects only env-owned paths, and persistence strips only those paths so effective env values never entersettings.jsonor delete unrelated file-backed credentials. -
src/core/event-bus.ts+src/routes/events.ts+public/js/event-channel.ts: Web event delivery is SSE-first throughGET /api/eventswith WebSocket fallback for legacy servers. -
Pi capability/cleanup: one per-instance async version observation gates actual prompt writes, feeds both live pool getters and preserves typed finality. Direct child cancellation and RPC exit start the same paired owner; persistent failure claims before drain. Pi-only temporary-directory allocation/identity plus the immutable physical receipt controls deletion, not mutable settings. Keep explicit unknown-close retention and resolver/opaque-wrapper/shutdown limits synchronized in
runtime-integration.mdand root notes; no new process registry or numeric tree signalling. -
src/agent/runtime/requests.ts+acp/callbacks.ts+src/routes/runtime-requests.ts: exact-session native decision GET/POST, opaque handles, canonical pre-insertion sanitization/32KiB event budget,128-entry/120s registry and32-callback limits. Preserve currentness/cancellation; retire an unflushed ACP selected write on cancel. Route-owned notices map captured chat to presentation delivery scope without changing execution IDs or messaging.public/js/features/native-request-bridge.tsandnative-requests.tsown the live response panel, SSE health/epoch and manual freshness. Instance auth is not a tenant ACL. Keep runtime/server API and root docs synchronized; Activity layout/default/history remain independent. -
src/shared/runtime-contract.ts+src/agent/runtime/*: canonical Codex/Pi projection bypasses internal messaging listeners; explicit native outcome is optional and preserves null/empty finality and partial MESSAGE salvage. Keep terminal finality/status/optional stopCause/trace correlation aligned across lifecycle, pipeline/collector and web/TUI. Native formatter-empty guards must not alter untagged delivery/ACK/queue behavior. Syncruntime-integration.mdandstream-events.mdbefore adapter activation. -
Pi private diagnostics retain bounded resolved stderr and redacted caught errors under captured-turn ownership; they do not expand public outcomes or annotate stopped turns. Captured internal kill reasons must not become user Stop through legacy flags.
-
src/agent/runtime/selection.ts: Cursor/Grok/Claude native/print selection, independent main/worker implementation flags and isolated native-v1 buckets. Keep boot/init/watch validation, captured spawn/lifecycle identity, exact reset/compact semantics and additive CLI-status diagnostics synchronized inruntime-integration.md. Existing absence or print migrates to native once per migration id (nativeTransportMigrationv2 re-runs over v1 stamps) where permissions let native run; print chosen after the v2 stamp is operator intent, not a fresh-default opt-in. Codex App/Pi retain legacy keys. -
Claude integration uses
claude-runtime-pool.ts, the type-onlyruntime-pool-contract.ts,claude-runtime-run.tsand the existing shared host/lifecycle. Keep logical settlement separate from captured main/worker physical cleanup; rejected unleased cleanup retains its control and only workers own instruction-directory removal. All three main-steer callers use main-only waits while scoped/global shutdown stays inclusive, with the existing exit-settle/salvage barrier. Document deferred claim/finalization and hard Stop separately from supported worker/approval/image/foreground-child paths. No-start fallback precedes compatibility completion; conditional trace finalization preserves completed headers. Sync runtime-integration/prompt_flow and root notes. -
Native Cursor main uses
runtime/acp/runtime-session.tsplusnative-runtime-run.ts; explicit auto only, no worker activation. Early guard precedes all preparation, private I/O liveness never carries text to messaging, and explicit execution bindings survive the global multi-session toggle. Claims/finalizers, live trace ownership, retirement fences and exact exit-settler cleanup are separate from provider wire completion. -
Native Grok main reuses the same host/facade/pool with an optional provider-neutral replacement strategy.
acp/replacement-turn.tsowns one logical result across cancelled attempts and a synchronous input-commit barrier;runtime/replace-turn.tsmaps typed receipts. Literal auto only; restrictive/worker activation remains blocked before preparation.grok-session.tsowns existing auth/model setup andgrok-events.tsmaps only observed result usage. -
runtime/acp/replacement*.tsowns private prompt-attempt epochs and one logical result;runtime/replace-turn.tsmaps local-dispatch/no-start/fatal receipts. Cursor's captured prompt closure restores bounded original/accepted/partial context and active rules. Main object and canonical generation must still match at input commit; trace/log observer failure must not cause inference retry. Anonymous same-session frames after B admission depend on provider ordering and cannot be identified by a local epoch alone. -
src/browser/runtime-*,src/browser/tab-lifecycle.ts,src/browser/web-ai/session*.ts: browser docs should mention runtime diagnostics, orphan cleanup, tab lifecycle, and web-ai session reattach. -
src/browser/adaptive-fetch/*,src/routes/browser.ts,bin/commands/browser.ts: browser docs should keepbrowser fetch <url>scoped as an adaptive URL/search-result reader, not generic search, with browser escalation and third-party reader opt-in boundaries explicit. -
src/routes/traces.ts/src/trace/*: server docs should include public trace read routes and related WebSocket/event surfaces such asalert_escalation. -
src/notes/search.ts/src/manager/notes/routes.ts/public/manager/src/notes/NotesSearchSidebar.tsx: Manager notes docs should include ripgrep-backed search,/api/dashboard/notes/search, typed errors, abortable sidebar search, and search CSS. -
src/manager/reminders/*/public/manager/src/dashboard-reminders/*: Manager docs should include dashboard reminders API, notification scheduler, matrix buckets, top-priority strip, detail popover, and drag/drop bucket moves. -
src/orchestrator/pipeline.ts/src/orchestrator/state-machine.ts/skills_ref/dev*/SKILL.md: PABCD docs should keep theProject root: <absolute path>dispatch contract and strict TypeScript + existing source-of-truth discovery guidance aligned. Repository-specific private record boundaries override generic planning locations. -
src/orchestrator/worker-registry.ts/src/routes/orchestrate.ts/bin/commands/dispatch.ts/bin/commands/worker.ts: worker progress query/watch is memory-only, keyed by stable employeeagentIdplus per-dispatchrunIdfor recent history, safe-summary only, and must not expose employee thinking detail. Humandispatchfollows safe progress by default;--quietand--jsonmust remain quiet. -
src/agent/agy-capabilities.ts+src/agent/args.ts+src/agent/spawn.ts+src/agent/spawn-env.ts+src/cli/registry.ts+src/cli/readiness.ts: AGY is a top-levelagyruntime. It usesagy -pprint mode with capability-probed optional flags (--modelobserved in AGY 1.0.12; probe failure logs and falls back to legacy emit-all compatibility), exact resume via--conversation <sessionId>, plain-text stdout,NO_COLOR=1, run-time auth checking. No per-run--effortflag. Native AGY context-file ingestion is separate from cli-jaw wrapper contracts such as injected operational context, transcript anchoring, quota UI, and post-compaction retention. -
src/cli/cli-status.ts+src/cli/cli-status-worker.ts+src/cli/readiness.ts: clean installs prefer capability/auth-ready Codex App, while existing settings use the authenticated accept/keep migration route. Status requests return nullable checking/stale snapshots immediately; raw detection, auth, and capability probes run in a bounded child.src/cli/opencodex-runtime.tsandsrc/core/codex-config.tsprovide read-only config/live-health diagnostics and never write the Codex endpoint. -
src/routes/quota.ts: Grok quota reads~/.grok/auth.jsonOIDC credentials and prefers JSON weekly credits before bounded Grok Build gRPC-web and legacy monthly billing fallbacks. -
src/agent/cursor-runtime.ts+src/agent/events/cursor.ts+src/agent/args.ts+src/cli/registry.ts+src/cli/readiness.ts: Cursor is a top-levelcursorruntime. It usescursor-agent -p --trust --output-format stream-json, exact resume via--resume <chatId>, model ids resolved from model+effort before spawn, auth viaCURSOR_API_KEYorcursor-agent status, and native quota from its selected credential store with explicit dashboard-cookie fallback. -
src/manager/telegram-hub/*/src/manager/routes/telegram-hub.ts/src/telegram/hub-callback.ts/src/messaging/thread-target.ts: Telegram Hub P0–P4 — synctelegram.md+server_api.mdManager surface (per-topicmodel/systemPromptoverrides). -
public/js/features/process-block.ts: hydrated expand (reconstructStepsFromBlock),data-had-detailrelease placeholder —frontend.md+stream-events.md§12. -
src/goal/pause-gate.ts/src/agent/lifecycle-handler.ts:goal_pause_gate_pendingcontinuation suppression —stream-events.md,INDEX.mddelta. -
src/agent/events/claude.ts: plainclaudetext_deltalive streaming —stream-events.md§3. -
tests/run.mts/package.jsontest scripts: programmatic test driver (--scope/--shard i/N/--list, per-file test home) —infra.mdscripts table; CI job graph, aggregate truth table and quarantine list —infra.md§ CI job graph. -
scripts/release-preview.sh/scripts/promote-to-main.sh/.github/workflows/publish.yml: release path isfeature → preview → mainthen aworkflow_dispatch-only npm publish;devis never in the release path. Promotion requires an already-certifiedpreviewSHA, the promotedmaincommit is a new SHA with the same tree, and the promote script exits without checking the publish outcome and cannot be re-run afterwards. Keep the flow, thepublish.ymlinput names, and the partial-release recovery steps ininfra.md§ 릴리스 파이프라인과 부분 실패 복구 aligned with the actual scripts, and mirror the precondition in rootREADME.md. -
bin/commands/service.ts/src/core/instance-lifecycle.ts: home-scopedservice stop|restart, ownership pidfile, and native-service delegation —commands.md, root README/AGENTS/CLAUDE. -
src/orchestrator/attestation.ts: PABCD--attestevidence gate —prompt_flow.md,INDEX.md. -
src/cli/handlers-skill-invoke.ts: dynamic/skill:<id>—commands.md,INDEX.md. -
src/browser/adaptive-fetch/scheduler.ts/src/browser/web-ai/session-artifacts.ts: adaptive-fetch P0 + web-ai parity wave —infra.md,str_func.mdentries. -
Keep root
AGENTS.md,CLAUDE.md,README.md, and publicdocs/dev/pages aligned with this folder when the architecture map changes. -
The Classic permission selector offers Auto (YOLO) / Safe choices, stored as literal
auto/safe. Server startup preserves the saved policy; never reintroduce the obsolete safe-to-auto coercion. Existing runtime-specific policy support and settings invalidation still apply.
Retirement changes must synchronize the saved-selection diagnostic and executable
key split in runtime-integration.md, CLI tombstone behavior in commands.md,
and local TUI/package absence contracts in infra.md. Preserve stored user data.
Quota reader contract
Native quota readers follow the OpenCodex source contract: Codex window duration/plan policy, Spark and reset-credit metadata; Claude model-scoped windows and credential-scoped cache. Missing measurements remain unknown, 429 alone never means 100%, and upstream bodies are bounded. See docs/migration/quota-reader-parity.md.
-
Boss user prompts include host-local civil dates and Monday–Sunday ranges via
src/agent/calendar-context.ts; the timestamp and calendar share one clock sample. Explicit user timezone/week conventions take precedence; system-prompt caching and worker/internal prompts stay unchanged. -
Optional pinned local services use
scripts/service-artifact.mjswith an externally anchored manifest digest and an immutable package tree. Activation and registration remain explicit; keep the prior registration for rollback. See../docs/pinned-service-artifacts.md. -
Slack progress uses a one-second native heartbeat under a shared append budget, delta-only cards and dispatch-time snapshots. Known file tools expose only validated project-relative filenames or outside basenames under captured workingDir; preserve request identity, final/ACK ownership and raw-content exclusion. See
telegram.md. -
Slack semantic activity uses
progress-detail.tsandprogress-files.ts: explicit Cursor shell tool purposes, finite literal command summaries and validated targets, never raw script bodies or credential arguments. Description-only same-ID updates do not reset accepted Cursor answer text; sparse terminal details retain the same observed purpose. Seetelegram.mdandstream-events.md.
Slack file CLI uses an explicit conversation and completion-only upload receipts (sent: boolean|unknown, no auto retry or caption fallback); cancellation preserves known/unknown delivery. Sync commands/API/Slack docs.
Slack trustedBotTriggers lets one named bot start a turn here: a fully validated rule plus a self-mention opens exactly the bot_message subtype, allowBots and mention_via_app_mention refusals, and nothing else. One malformed rule voids the whole list, and isSlackMention stays narrow because it also decides thread ownership. See structure/infra.md §src/slack/.
Optional workflowSkill selects the operator-configured execution route only after the actual sender/channel/bot-user/marker match and self-mention. Load only the selected enabled skill, bounded to 64 KiB; unverified sender/request context or unavailable or ambiguous skill selection is visibly blocked with no model fallback. Four-key rules keep legacy behavior. Empty or standalone SILENT workflow results require an unconfirmed notice and failure ACK, with no automatic rerun because effects may already exist. Preserve normal approval, tool grants and source permissions; an AI reply is not business-completion proof. See ../docs/slack-tools.md.
Opted-in workflow requests use the followup queue when busy; never steer or collect them into an unrelated running turn. Read the selected skill at admission and preserve its captured content, hash and source metadata across queueing and restart. Silent outcomes settle the workflow request as unconfirmed/failed while preserving provider/native final text and status; never automatically rerun.
Root contract notes (moved from AGENTS.md, 2026-09-25)
Architecture Docs Sync
-
The canonical desktop release workflow must Developer ID-sign macOS with Team
U9ATA49N28, notarize, staple, verify the final app, and verify channel metadata plus the update ZIP SHA-512 before upload.electron:dist:mac:signedis the equivalent opt-in local path; ordinaryelectron:dist:macremains ad-hoc. Windows remains unsigned. Keep README andstructure/infra.mdaligned; fixture tests do not prove a signed/notarized artifact, and the first signed release is a manual-DMG bootstrap before in-app updates can be trusted. -
Channel forwarders deliver to the destination captured when a run was admitted, never to a per-channel last-active slot.
src/messaging/run-pin.tsbuilds the identity block (origin/requestId/scope/sessionId/remoteKey/target) that everyagent_donecarries, andresolveForwarderTargetrefuses an event with no destination or one addressed to another channel. Slack, Discord and Telegram forwarders no longer accept agetLastTarget/getLastChatIdoption, so web and CLI turns are not mirrored into chat rooms. Heartbeat destinations are complete or held: a Slack destination needs a thread or an explicitscope: "channel_root", an absent destination sends nothing, threaded jobs verifyconversations.repliesbefore runner work, a bound destination send carriesfullAccessafter binding (not an HTTP JSON voucher; mention-watch hit posts do not copy it), and a 25-minute server-ownedenforceDestinationgrant is injected into print, native, employee and script runtimes before work so omitted targets pin and mismatches fail without process-global locking. Live hold reasons remain visible to GET/UI until recovery.authorizeExplicitTargetvouches for a send without rewriting its address. Slack progress cards end their live loop onmessage_not_found/cant_update_messageor three consecutive failures rather than retrying a dead message. Seestructure/telegram.mdandstructure/server_api.md. -
Auto (
permissions:auto) grants qualified direct-local Jaw API authority across supported runtimes, independently of per-turn secrets. Keep actual/effective loopback, exact browser origin, proxy provenance, explicit outbound destinations and server-only resource options. Safe/custom keep existing scoped/operator paths; full API authority is instance-wide, distinct from provider Safe and task scope. Preserve no-descendant/read-only assignments, captured worker context and honest capability/receipt evidence. Seedocs/slack-tools.mdandstructure/server_api.md. -
Slack group DMs use
message.mpimand optionalmpim:history; exactchannel_type: mpimmentions retain channel allowlist and thread policy, never the one-to-one DM bypass. An install withoutmpim:historyreceives no group-DM traffic at all; that gap is reported inmissingCapabilitiesand logged as a reception limitation rather than failing credential validation. An absent scope header is unknown and a present empty header is a known empty grant. Keepstructure/telegram.mdand the validation API docs synchronized. -
Slack Socket Mode app-token ownership is coordinated across homes by a connected, fresh, live-PID claim; uncertainty fails open, conflicts disable inbound only, and the runtime notice/activation epoch must remain generation-bound. A long-running server keeps retrying Socket reconnects until Slack answers (finite
maxReconnectAttemptsis caller opt-in;link_disabledstays terminal). A bound heartbeat destination send usesfullAccessafterresolveHeartbeatBindingand never last-active retarget;/api/channel/senddoes not acceptfullAccessfrom JSON. Seestructure/telegram.mdandstructure/server_api.md. -
Manager sidebar selection and Sessions/Stop/Open use separate interactive targets. Keep list navigation scoped to the focused row selector, stable session-disclosure links, and preferred width separate from viewport clamping. Pointer and keyboard resize completion persist the latest value; see
structure/frontend.md. -
Manager terminal presentation preserves backend PTY ownership across hide/unmount. Keep hydration-first bounded creation, explicit recovery, stable tab identity and focus ownership separate from native Code API sessions; theme updates must not recreate shells. See
structure/frontend.md. -
Linux
/api/file/openacknowledges asynchronousxdg-openlaunch, not desktop application success. Keep detached/ignored-stdio dispatch and launch-error handling; never wait synchronously for the opener. Seestructure/server_api.md. -
Sidecar builds use exclusive owned staging/source snapshots and retained failure evidence; preserve the existing compiled-asset/prune/native/no-JWC gates. Smoke executes a byte-matched copy outside checkout dependency ancestors with the target Node, strict process/IPC/listener/HTTP/close checks and evidence before cleanup. Never equate timeout/skipped with pass, relabel retained roots as deleted, adopt unknown output, or force-remove locks. Input relative contained symlinks are preserved verbatim; output fingerprinting is local provenance, not a signature. Final builder-filtered native UI remains separate. See
structure/infra.md. -
Isolated desktop QA is explicit via
CLI_JAW_ISOLATED_QA_ROOT;src/shared/isolated-qa.tsowns fixed role homes, strict W/M/P ports and fresh child environment. The supervisor validates before imports; Electron applies paths before lock/session and suppresses global registration/installer actions. QA Manager rejects foreign scans/peers and lifecycle actions before side effects; ordinary mode is unchanged. Preserve captured policy and lifetime-safe QA cleanup. This is controlled launch containment, not an arbitrary-command sandbox or packaged/native QA certification. Syncstructure/infra.md, README and root/structure notes. -
Native event foundation:
src/shared/runtime-contract.ts+src/agent/runtime/*own canonical Codex/Pi projections and optional explicit outcomes.agent_runtime/agent_runtime_gappublish directly to SSE, bypassing messaging listeners. Native compatibility terminals carry finality/status, optionalstopCauseon stoppedorchestrate_done, and existing trace identity; no public partial/outcome object. Preserve legacy final selection when outcome is absent, and interrupted MESSAGE salvage before exit settlement. Seestructure/runtime-integration.mdandstructure/stream-events.md; Classic live Activity and its default preference are implemented separately from this event foundation; Classic history has its own bounded restoration owner; Interactive TUI has its own scoped consumer described in rootAGENTS.md(Interactive TUI Activity). -
Runtime selection: only Cursor/Grok/Claude accept
perCli.<cli>.transport; existing homes migrate absent/print to native once per migration id (nativeTransportMigrationv2, re-run over v1 stamps; permission-blocked engines are skipped and retried only from a v2partial) and print chosen after the v2 stamp is operator intent. Native switchable keys prefix the whole legacy bucket withnative-v1:and never overwrite the print singleton. Capture transport/bucket once, forward through lifecycle persistence/compact, and keep scoped resets exact. Unsupported main/worker native adapters fail before print/fallback work; compiled support in/api/cli-statusis separate from cached auth/binary readiness. Codex App/Pi keys remain unchanged. -
Claude native: the optional SDK, shared pool/host and existing lifecycle own sequential main turns, fresh worker assignments, immutable terminal claims, hard Stop and interrupted MESSAGE before exit-settle. Default jaw steer remains kill/resume, never advertised as in-band; the one exception is Code-only: an
/api/codeClaude session (inBandSteer, set bysrc/code-mode/providers/claude.tsalone) accepts one in-band follow-up per streaming turn, settled on the result that consumes it (runtime-integration.md#native-code-sessions). Auto (YOLO) / Safe decisions use live requests; deny/unknown profiles fail before preparation, including the memory extractor. Images are bounded and child activity is foreground-only. Child declarations reconcile from both parent/child frames; their ID ownership survives child completion and is not the same as live permission eligibility. Pre-start failure/Stop use one cached fallback before compatibility output;onlyIfRunningpreserves finished trace headers. Background tasks are unavailable: the pool seedsCLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1when the caller left it unset, because the PreToolUse hook refuses only an explicitrun_in_background:truewhile Claude backgrounds a long foreground Bash command on its own, which ended the turn. A mid-turn session failure now fillsctx.runtimeDiagnosticfromfacade.lastError, and lifecycle prefers that sentence over the stderr classification so a failed turn with no text reports a cause instead oftg.noResponse. -
Cursor native main: explicit native/auto only; restrictive permissions and unsupported workers fail before
regenerateB, bucket/bootstrap/snapshot, detection or pool work.AcpRuntimeSessionkeeps raw final/partial independent of bounded Activity and claims an immutable logical result before lifecycle; passive finalization survives main-map removal. Native run cleanup holds the exact lease through application settlement and uses captured exit-barrier identity. Server-explicit scope/chat bindings survive multi-session off; private identity-only I/O liveness keeps the owning collector alive without messaging content. Preserve legacy/manual compact while excluding print-era automatic compact/count heuristics from explicit native outcomes. -
structure/is the current public architecture-doc hub. -
Keep
README.md, rootAGENTS.md, rootCLAUDE.md, andstructure/AGENTS.mdsynchronized when command/API/orchestration surfaces change. -
Recent non-strict hotspots: explicit
/continue, workflow helper slash commands (/planas PABCD P compatibility guide,/interview,/deliberate,/planaudit,/review,/search,/goal,/goalplan,/team,/task,/fork,/gd; forward PABCD transitions requirecli-jaw orchestrate <phase> --attest '{"from","to","did",...}'), pre-prompt context hooks (context-hooks.json,cli-jaw hooks), bounded local search contract (narrow-path Grep/rg; external search via active search skill), Telegram Hub P0–P4 (structure/telegram.md,/api/dashboard/telegram-hub), goal pause gate continuation suppression (goal_pause_gate_pending),tests/run.mtsprogrammatic test driver,/goal planand/goalplanstore user direction asplanHintand require/goal refinebefore checkpoints; agent pause first-tap state is exposed as derivedpauseGateon status/API surfaces while persisted status remainsactive; bounded automation is/goal run ..., not top-level/autopilot), Codex App clean-install default with opt-in migration for existing settings, bounded child-backed nullable CLI status, read-only OpenCodex root-URL/live-health diagnostics, Pi top-levelpi --mode rpcruntime with isolatedPI_CODING_AGENT_DIRprofiles, AGY-pprint-mode runtime with capability-probed optional--model(observed in AGY 1.0.12), Grok weekly quota via native credentials and JSON credits, then bounded Grok Build gRPC-web and legacy monthly fallbacks, SSE-firstGET /api/eventsevent channel with WebSocket fallback, bounded tool-log sanitizer, worker progress query/watch, canonical/api/channel/send, heartbeatevery/cronschedules, heartbeat Slack mention watch insiderunHeartbeatJob(mentionWatch, optionaluserIds/conditionsfor mention|talk while default remains mention-of-userIdand inboundmentionOnlystays separate, bot-tokenconversations.historyscan instead of user-token-onlysearch.messages, frontier/resume/round-robin/429 stop/60-channel cap, per-item busy yield, server-owned thread send then seen receipt, at-least-once delivery; the ledger is keyed by(jobId, workspaceId, userId)with the workspace id taken from a per-tokenauth.testrather thansettings.slack.teamId, pre-v2 rows hold a job in a durable SQLite quarantine cleared only byPOST /api/heartbeat/:jobId/mention-watch-fresh-startwith a newsince, and a duplicate job id in one PUT is a 400; the answer turn carries the answered thread'schatSessionIdbut runs in a dedicatedmention-watch:<remoteKey>scope so inbound Slack cannot steer it, with a per-conversation guard ofgetState(remoteKey) === 'IDLE'+hasChatSessionWork+ non-blockingsessionLanes.hasPending, and the thread session is minted only on admission) , browser runtime diagnostics/session lifecycle, Electron Node sidecar packaging, private activek-writingrouting for Korean promotional/content writing, inbound ACK reactions and queue-notice lifecycle owned bysrc/messaging/ack-reaction.ts+src/messaging/queue-notice.ts(channels supply transport factories only; the notice is deleted only AFTER a successful answer and rewritten on timeout/shutdown;QueueNoticeRegistry.drainbounds shutdown and actually aborts; ACK settles immediately after successful text delivery and BEFORE the optional image relay, because uploads are uncancellable and would otherwise strand the reaction onrunningafter the answer is already visible), canonical platform classification viasrc/core/platform-kind.ts(windows-native|wsl|linux|darwin|other;process.platformdecides first andWSLENVis never a WSL signal), andnpm run gate:all. Workbench modernization uses a one-row Activity header with Codex-style expanded rows/groups; the Workbench Settings tab is replaced by a ZCode-style full settings page that swaps the workspace (header gear / Meta+,,← Back to workspace, grouped icon nav, card content), persisted as Manager registryui.instanceSettingsOpen. A unified settings registry separates Instance/Manager scopes and the same page is served standalone fromdist/settingsbehind the Classic header gear (the right-panel 설정 tab is gone); Classic uses the t3 token shell. Preserve per-page save owners, dirty guards, Preview iframe identity and independent live Requests; seestructure/frontend.md. -
Standalone lifecycle is home-scoped:
jaw --home <path> service stop|restart [--port N]verifies<JAW_HOME>/jaw.pid.jsonbefore signalling; registered launchd/systemd instances delegate to their native manager. Never recommend killing every Node process. -
Slack connection environment variables own their matching fields at runtime. Settings exposes only variable names and conservatively locks connection editing/reset while any are present; CLI setup refuses mixed input. Generic settings writes reject only env-owned paths, and persistence strips only those fields so env values never enter
settings.jsonor erase unrelated file-backed credentials. -
Slack text sends preserve Markdown and explicit Block Kit
blocks, splitting multiple tables into separate messages.ok:truemeans every chunk was posted, independently of rendering verification. Inspectdelivery.verification(verified,failed, orunavailable) anddelivery.messagesfor each posted chunk's timestamp, verification error, table-content status, and feature evidence. A persisted mismatch isfailed; missing permission, unavailable/malformed readback, or a missing timestamp isunavailable. Neither stops remaining posts or triggers reposting. Actual validation/POST failures retainok:false; partial receipts includepostedChunks,totalChunks, andsent:true, retryable:false. Never blindly resend posted chunks.tableContentcompares ordered text, numeric value/display, links and supported styles; ordinary Markdown character references decode once while code and escaped ampersands stay literal.richContentandsourceAccuracyremainnot_checked, and readback stays bounded to 1 MiB. -
File sends across Slack, Telegram and Discord share one confirmation vocabulary. A send the vendor will not name is refused, not reported as delivered: Slack keeps its
files[]echo requirement, Telegram requires amessage_idgreater than zero, and Discord requires a readable Create Message body. Those cases areok:falsewithconfirmation: 'unconfirmed', replacing the olderok:true, ambiguous:truethat no consumer read. Callers that forward a file result must preserveconfirmation; dropping it makes a caption post twice. Seestructure/infra.mdandstructure/telegram.md. -
Slack progress uses one bounded native task plan for direct and queued requests, with exact request/run correlation and no raw tool details. Native elapsed time updates every second when the shared API budget permits; only changed cards are sent. Known file tools show bounded, sanitized project-relative filenames (outside the captured project: basename only). Cursor shell tool-call purposes and bounded English action/target summaries distinguish shell-based reads, searches, tests and scripts; raw command bodies and argument values remain excluded. Final delivery stays with the verified sender; known failure/cancellation cannot become a success ACK. Restore and shutdown use captured ownership and bounded cleanup. See
structure/telegram.md. -
Slack-triggered Boss turns receive
channel_idand parentthread_tsin the per-turn user prompt regardless of multi-session state; agents must use that explicit context for Slack lookup/send APIs instead of parsing session labels. -
Optimization/score-maximization goals follow the optimization-loop discipline (LOOP-PHASE-DEATH/CONTINUITY/CANDIDATE-ANCHOR/INSTANCE-CHECK + GATE-ORACLE-VALIDITY): classify candidate changes, ban a class after 3 consecutive discards, force evaluator-gate work on repeated D-phase deaths. Canonical: dev-pabcd §10, dev-testing §9.5; injected via orchestration template and goal continuation.
-
structure/reading map: start atstructure/INDEX.md; depth —telegram.md(Hub),prompt_flow.md(attest/hooks/bounded search),stream-events.md(pause gate/SSE),infra.md(test scripts),commands.md+server_api.md(slash/API surfaces). Concurrent inbound gateway docs:structure/INDEX.md§gateway,structure/infra.md§src/messaging/,structure/telegram.md§common messaging layer; legacysettings.channelis a deprecated read-only alias for one major version. -
Grok main native ACP requires literal auto, existing advertised authentication/model/effort, and no leader. Its optional common replacement strategy waits for original cancellation and drain, preserves one logical final, commits input only after local dispatch with current ownership, and never queues fatal failures. Restrictive policies and workers fail before preparation. Sync
structure/runtime-integration.md.
