responder

module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 7, 2026 License: MIT

README

Responder

CI Release

Responder turns authenticated alerts into focused Slack incident rooms backed by isolated Coop sessions and Emisar MCP access.

It is a single-host incident controller for pragmatic on-call teams:

  • accepts bounded Grafana or mapped JSON webhooks;
  • triages human and monitoring-app messages in configured Slack alert feeds, answering human questions in place and opening incidents only from credible app alerts, explicit requests, or operator-confirmed offers;
  • correlates related signals and deduplicates webhook delivery;
  • records source-attributed evidence, health-layer coverage, and an incident timeline separately from agent prose;
  • creates one Slack channel and one pinned investigation card per incident occurrence;
  • creates one Coop session and isolated fork under a predeclared repository policy;
  • forwards only operator messages, concise agent responses, and review evidence;
  • parks between turns, resumes the same agent conversation, and survives process restarts;
  • tracks every accepted investigation or engineering promise as durable work, and exposes it in App Home and through /responder work;
  • exposes an App Home, Agent Messages tab, message shortcut, semantic progress, lightweight acknowledgements, and deterministic controls for status, evidence, handoff, changes, review, draft PR publication, retained-work disposal, stop, and close;
  • can return bounded generated images and evidence-backed charts in the same Slack conversation, when the configured agent has an appropriate image or chart tool;
  • investigates live infrastructure through Emisar and can submit an exact, directly requested incident action to Emisar's policy and approval workflow.

Responder does not merge, deploy, sign commits, or grant infrastructure authority. Coop owns the fork and agent boundary. When explicitly configured, Responder can reproduce Coop's exact approved tree, push only a lease-protected Responder branch, and create or update a draft GitHub pull request. Emisar owns infrastructure policy, approval, execution, and audit.

See How Responder works for end-to-end diagrams covering Slack message routing, Coop turns, memory, evidence, standing rules, incidents, approvals, retries, and garbage collection.

Quick start

Requirements:

  • Go 1.26.5 or a released Responder binary;
  • Coop with the local session API (coop sessions serve);
  • a Slack workspace app created from deploy/slack-app-manifest.yaml and configured using the Slack app guide;
  • an observe-scoped Emisar API key in EMISAR_API_KEY;
  • a TLS reverse proxy for public webhook delivery.

After creating the Slack app, upload deploy/slack-app-icon.png, create an app-level token with connections:write, and use that xapp- value as SLACK_APP_TOKEN. The manifest enables Socket Mode and contains the complete supported event, scope, interactivity, and presentation configuration.

Install the current source build for your user:

make install

This writes ~/.local/bin/responder; override INSTALL_DIR when needed. For a system installation from source:

make build
sudo install -m 0755 bin/responder /usr/local/bin/responder

Or install the binary at the root of an unpacked release archive:

sudo install -m 0755 ./responder /usr/local/bin/responder

Release archives have a signed checksum manifest and GitHub build provenance. Verify them before installation using the commands in docs/operations.md.

Then create the service account and configuration:

getent passwd responder >/dev/null || \
  sudo useradd --system --home-dir /var/lib/responder --shell /usr/sbin/nologin responder
sudo install -d -o root -g responder -m 0750 /etc/responder
sudo install -d -o responder -g responder -m 0700 /var/lib/responder
sudo install -o root -g responder -m 0640 \
  config/responder.example.yaml /etc/responder/responder.yaml
sudo install -o root -g responder -m 0640 \
  deploy/coop/session-policies.example.yaml /etc/responder/session-policies.yaml
sudo install -o root -g responder -m 0640 \
  deploy/systemd/responder.env.example /etc/responder/responder.env

The account-creation command keeps an existing responder user. Edit the Slack IDs, repository path, Coop policy, webhook route, and /etc/responder/responder.env. For a manual foreground trial, export the same variables:

export SLACK_BOT_TOKEN='xoxb-...'
export SLACK_APP_TOKEN='xapp-...'
export EMISAR_API_KEY='...'
export GRAFANA_WEBHOOK_TOKEN='...'
export GENERIC_WEBHOOK_SECRET='...'

Every configured secret must contain at least 16 bytes. Use independently generated random values for webhook authentication.

Create Coop's private MCP projection:

sudo -u responder env EMISAR_API_KEY="$EMISAR_API_KEY" \
  responder bootstrap-coop --config /etc/responder/responder.yaml

To expose additional MCP servers to every Responder turn, set coop.additional_mcp_file to an owner-private 0600 file using the standard {"mcpServers": {...}} shape. Put any MCP-only NAME=value credentials in a separate coop.additional_env_file, also owner-private. Responder merges those sources into Coop's private projection, reserves the emisar server name, and refuses to project configured Slack or webhook secrets. Stop Coop and rerun bootstrap-coop after either source changes.

Authenticate the agent account into that same dedicated Coop configuration:

sudo -u responder env COOP_CONFIG_DIR=/var/lib/responder/coop/agents \
  coop login codex@oncall

A policy's target may instead be an ordered fallback ladder of up to four targets, which may cross providers:

    target: [codex:gpt-5.6/medium@oncall, claude@oncall]

Coop moves a rate-limited session to the next rung and re-delivers the same turn, so a usage limit mid-incident costs a retry rather than the investigation. Sign in every rung — responder doctor checks all of them, not just the one sessions start on.

The policy repositories must already be canonical Git worktrees owned by or writable to responder; cloning them as that account under /srv/repos is the simplest setup:

sudo install -d -o responder -g responder -m 0700 /srv/repos
sudo -u responder git clone <infrastructure-repository-url> /srv/repos/infrastructure
sudo -u responder git clone <backend-repository-url> /srv/repos/backend

For a one-command foreground trial, set coop.supervise: true in Responder's configuration. Both doctor and serve then launch Coop with the configured binary, state, policies, socket, and private agent configuration. doctor stops its temporary child after preflight; serve restarts Coop after unexpected exits and stops it when Responder shuts down. Before accepting Slack work, managed startup verifies the real Coop box image and builds it when missing. responder doctor fails with the exact coop build remediation when the execution image is unavailable:

sudo -u responder -g docker env \
  SLACK_BOT_TOKEN="$SLACK_BOT_TOKEN" \
  SLACK_APP_TOKEN="$SLACK_APP_TOKEN" \
  EMISAR_API_KEY="$EMISAR_API_KEY" \
  GRAFANA_WEBHOOK_TOKEN="$GRAFANA_WEBHOOK_TOKEN" \
  GENERIC_WEBHOOK_SECRET="$GENERIC_WEBHOOK_SECRET" \
  responder serve --config /etc/responder/responder.yaml

Responder refuses managed mode when another process owns the configured Coop socket. It also removes the configured Slack, webhook, and Emisar variables from the child process environment; Coop receives Emisar access through the private files written by bootstrap-coop, which project EMISAR_CLIENT=responder into every incident box for client attribution.

With coop.supervise: false, start coop sessions serve separately or use the shipped split systemd units. Then verify local state, Coop, Slack, and the authenticated Emisar MCP tool catalog:

sudo -u responder env \
  SLACK_BOT_TOKEN="$SLACK_BOT_TOKEN" \
  SLACK_APP_TOKEN="$SLACK_APP_TOKEN" \
  EMISAR_API_KEY="$EMISAR_API_KEY" \
  GRAFANA_WEBHOOK_TOKEN="$GRAFANA_WEBHOOK_TOKEN" \
  GENERIC_WEBHOOK_SECRET="$GENERIC_WEBHOOK_SECRET" \
  responder doctor --config /etc/responder/responder.yaml

For a supervised installation, install the units from deploy/systemd/, then enable responder.service; it starts Coop first:

sudo install -o root -g root -m 0644 \
  deploy/systemd/coop-responder.service /etc/systemd/system/coop-responder.service
sudo install -o root -g root -m 0644 \
  deploy/systemd/responder.service /etc/systemd/system/responder.service
sudo systemctl daemon-reload
sudo systemctl enable --now responder.service
sudo systemctl status coop-responder.service responder.service
curl -f http://127.0.0.1:8080/readyz

Both systemd processes use the same restricted Unix account because Coop's v1 socket is owner-only. Only the Coop unit receives the docker supplementary group; the Responder process does not.

doctor and serve initialize Emisar MCP with the configured token and require the operational tools Responder depends on. This validates authentication and the tool catalog without executing an infrastructure action. Every Coop turn also receives a mandatory claim-based evidence policy: repository files establish declared topology and implementation, Emisar is preferred for live infrastructure checks, and other available MCP servers or tools are used when they own relevant evidence. A missing local cloud CLI is never treated as evidence that Emisar is unavailable.

Webhooks

The service listens on loopback. Publish only /v1/hooks/ through a TLS reverse proxy. Health and metrics can remain local.

Grafana route:

curl -f \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer example-secret' \
  -H 'X-Responder-Event-ID: grafana-delivery-123' \
  --data-binary @grafana-alert.json \
  http://127.0.0.1:8080/v1/hooks/grafana

Grafana's alert fingerprint is the stable signal identity. Its groupKey is the preferred incident correlation key; configured labels are the fallback. A resolved, unclosed incident can reactivate in its existing channel. A firing signal after manual close creates a new occurrence, channel, and fork.

Generic routes use deliberately small dot-path mappings. See docs/webhooks.md. There is no embedded scripting language.

Slack

Mention the bot in any channel where it has been invited to ask a question or request read-only work:

@Emisar investigate elevated checkout latency in production

Responder investigates and replies in that thread without creating an incident. An operator can ask it to open an incident for elevated checkout latency to create one directly, or approve an Open incident room offer after seeing the findings. In an incident channel, configured operators can talk to Responder anywhere without repeating an @mention. Outside incident rooms, a delivered triage answer opens a bounded 30-minute conversation window for nearby follow-ups in the same channel or thread location. It reads top-level messages and threads, replies in the originating conversation when addressed or when it has something useful to add, and may stay silent for ambient chatter. The pinned card updates in place with alert evidence, investigation state, and only currently valid controls. Incident channels are private by default, and all configured operators are invited automatically.

Alerts, ambient conversation, and inferred intent remain read-only. A configured operator can ask for one exact operational change in the current Slack conversation; Responder calls Emisar there, without requiring an incident room. Emisar still owns target validation, policy, approval, execution, and audit. A pending decision appears in the same conversation as a Review approval in Emisar link. Responder watches that exact run in the background, updates the existing card as it progresses, and automatically posts the terminal result plus read-only verification in the same conversation. Waiting consumes no model turn and survives a Responder restart. When an operator explicitly asks Responder to change repository files, the reply can include a concise Start task button instead of sending the operator to another client. Confirmation keeps the task in that Slack thread and creates an isolated writable Coop fork, where Responder can inspect, edit, test, and commit under the configured repository policy. Later replies in the same thread continue the same session without an @mention; unrelated channel messages remain in read-only triage. It does not create an incident, and it does not merge, push, deploy, sign, or mutate infrastructure.

Inviting @Emisar to a new channel first offers safe one-click defaults: mentions only or proactive participation, the deployment repository, in-place app-alert replies, and no additional incident invitees. Customize starts a four-question setup conversation for participation, repository or repository-set context, app-alert escalation, and incident audience. A repository set gives one primary writable repository plus exact-commit read-only companion snapshots. The final card shows the normalized typed values and safety boundary; nothing changes until a configured operator confirms it. Typed choices use Slack buttons. Configured operators are always invited to incident rooms; the audience step either adds no one else or accepts member and user-group mentions for additional invitees. Emisar follows the operator between the channel and known setup threads, including explicit switch to a thread and back to the channel requests, throughout the 30-minute setup.

The conversational surface is primary: ask @Emisar how are you configured here?, show open incidents, enable proactive mode, or reconfigure this channel. Those phrases use the same validated handlers below. slack.watch_channels supplies deployment defaults and /responder remains the compatibility and recovery surface:

/responder status
/responder work
/responder incidents
/responder incidents all
/responder proactive on
/responder proactive off
/responder proactive inherit
/responder proactive global on
/responder proactive global off
/responder proactive global inherit
/responder shadow on
/responder shadow off
/responder shadow inherit
/responder timeline
/responder evidence
/responder handoff
/responder postmortem
/responder memory
/responder preferences
/responder rules
/responder turn-limit
/responder turn-limit 1000
/responder turn-limit global 1000

The effective order is explicit channel override, confirmed channel setup, workspace override, then responder.yaml. Global on therefore watches every channel where Responder is a member and receives events, while a channel override can opt in or out. inherit removes that Slack override. Responder reads human and external-app messages in Slack timestamp order and gives each decision a chronological transcript centered on the target message. The default 20-message window includes the thread root, nearest preceding replies, the target, and up to three immediately following messages; top-level requests receive the equivalent channel window. It waits for a two-second quiet period so nearby human replies are visible, then scores addressee, urgency, confidence, novelty, and ownership. It chooses whether to stay silent, add a lightweight reaction, reply where the sender is speaking, or escalate. Ambient replies and reactions have separate configurable attention thresholds, while direct requests remain eligible regardless of those thresholds. Human messages do not automatically become incidents: Responder answers in place and can attach an Open incident room button when coordinated work would help. Only a configured operator can approve that button. A credible unresolved monitoring-app alert follows the channel's confirmed policy: reply in place, offer an incident button, or open automatically. An explicit human request to open, create, start, or declare an incident is honored directly. Both the context size and settling delay are configurable. An explicit repository-change request can instead offer a Start task transition in the same thread to a writable isolated fork. A configured summon mention starts the same read-only triage conversation; explicit incident wording remains deterministic.

When a decision-ready diagnosis establishes a narrow repository fix, Responder may also show Prepare code fix beside Open incident room. The choices are independent: the incident room coordinates operations, while the engineering task edits and validates code in the source thread. The fix button creates no PR by itself; after a real diff exists, the task card exposes the separate Create draft PR review control.

The Agent Messages tab supplies suggested health, alert, incident, and handoff prompts. The message shortcut Investigate message starts the same read-only triage for a selected message even when ordinary proactive listening is off. Long checks keep a native Slack progress indicator with semantic milestones until the reply or a clear failure is posted.

Each Slack conversation keeps a compact durable situation: channel purpose, current goal, active topics, verified topology, decisions, open loops, unresolved questions, and evidence references. Future turns receive the exact conversation summary, recent summaries from other conversations in the same channel, and recent summaries from public channels across the workspace. Same-repository work is preferred, while private-channel summaries never cross into another channel without a membership proof. Responder rotates the underlying per-channel Coop session after coop.watch_session_max_turns or coop.watch_session_max_age while preserving that summary. Recent conversation summaries are consolidated into privacy-scoped weekly continuity rollups after memory.compact_after, seven days by default, and expire after retention.conversation_memory, 90 days by default. The background pass is deterministic: it groups and bounds summaries the model already produced, so it adds no second model call. Public channel summaries may roll up by repository; private summaries remain scoped to their channel. Storage pressure can trigger earlier compaction while preserving the latest hour of conversation context. This session summary is separate from operator-confirmed durable memory. An operator can ask Responder to remember an alias, channel-to-repository binding, evidence route, entity relationship correction, or open-ended guidance such as when explaining a fix to me, start with a simple summary. Responder shows the normalized value, scope, and expiry in a confirmation card; nothing is saved until an operator confirms it. Personal guidance can follow that operator across channels, while channel and workspace guidance can encode explicit team conventions. Saved entries are bounded, deduplicated by logical key, expire automatically, can be forgotten from App Home, and are supplied to future model turns only as advisory context. Guidance cannot start work, authorize an incident or change, approve an action, or count as operational evidence. The current request, host safety policy, fresh live evidence, current repository content, and Responder configuration always take precedence. Recent structured evidence remains source-attributed; compact related summaries carry continuity across channels without becoming current-health proof.

Responder records when confirmed memory and continuity rollups are recalled. A scheduled review flags confirmed entries that have not been used or reviewed recently and identifies exact duplicate guidance, but it never silently edits operator-confirmed memory. /responder memory shows memory health and /responder memory review provides keep, merge, and forget decisions. Replacements keep a hash-only supersession record; old values are not copied into audit state. These mechanisms are inspired by the freshness, continuity, and reviewability goals in OpenAI's Memory and new controls for ChatGPT, while retaining Responder's stricter operational evidence and approval boundaries.

Responder also supports two operator-confirmed behavior catalogs. Preferences are typed defaults such as health_check_depth=deep, response_detail=concise, or response_location=prefer_thread; their precedence is operator, channel, repository, then workspace. Standing rules are typed channel subscriptions such as terraform_plan -> review_terraform_plan, restricted to human, app, or any matching message. A request such as when I ask about infrastructure health, always do a deep check or when you see a Terraform plan here, report its main diff and red flags produces a confirmation card showing the normalized behavior, scope, expiry, source filter, and fixed read-only safety boundary. Open-ended guidance may be remembered as advisory model context, but arbitrary prose is never stored as an executable trigger or authority. A configured operator can make this explicit setup request in any channel where Responder is invited, even when that channel is not otherwise a summon or proactive channel.

/responder preferences and /responder rules list active and disabled entries with enable, disable, edit, and delete controls. An enabled standing rule may admit only its deterministic message type even when broad proactive triage is off. A match asks the model to evaluate the event; it does not force a reply. The model may ignore an intermediate or duplicate event, react when that is sufficient, or reply in the source thread when it has a useful result. Later lifecycle updates are evaluated independently. Operational-alert replies must reconcile repository topology with fresh live evidence and return a decision-ready verdict, impact, and next action. Confirmed or likely issues also include an immediate mitigation and a durable solution; Responder sends shallow symptom summaries back to the same run for more investigation. Terraform reviews still require the exact plan; repository changes provide context but never replace it. Slack events remain ordered per channel, and each rule records its source event before incrementing its run count so retries cannot execute it twice. Expiry, capacity limits, channel deletion, repository removal, and maintenance pruning bound all durable behavior state.

Configured operators can also create one-time and recurring tasks in ordinary language: remind me in 4 hours, every weekday at 09:00 check production health, or on the first of each month prepare an SRE review. Emisar replies with a confirmation card containing the normalized task, destination, repository, recurrence, timezone, next run, expiry, and safety boundary. Nothing runs until an operator confirms it. /responder schedules lists the current channel's tasks with run-now, pause/resume, replace, and delete controls.

Schedules are durable wake-ups, not stored authority. Each occurrence enters the normal Slack/Coop agent pipeline with fresh repository, tool, memory, authorization, and Emisar policy context. The scheduler records each occurrence before dispatch, never overlaps two copies of the same task, and uses IANA timezone calendar arithmetic so local times follow daylight-saving changes. catch_up can run only the latest missed occurrence after downtime or skip it after the configured grace period. One-time tasks complete after their occurrence; run-now remains available for an explicit manual repeat. Expired tasks and old run records are removed by normal retention maintenance. /responder shadow runs the classifier and records its decision, evidence, and coverage without posting or creating an incident.

Every accepted model-backed request also creates a durable commitment before execution. The commitment follows the underlying run through queued, working, finishing, done, blocked, or cancelled state and survives restart. Ask what are you working on?, run /responder work, or open App Home to see the exact request, current status, and next operator action. This is distinct from memory: a commitment is work Emisar owes the team, not a fact to reuse later.

/responder incidents lists open incidents with native Slack channel mentions and labels retained channel names when a room is archived, deleted, or unavailable; /responder incidents all [page] includes closed history. /responder help explains the complete command surface and provides read-only buttons for current-channel status and incident directories. Slack exposes only one static usage hint for a slash command, so the manifest keeps that picker text short and moves detailed guidance into this interactive response. The same command also exposes timeline, evidence, handoff, postmortem, update, changes, review, publish, stop, and close in an incident room. The remediation timeline is derived from the alert, agent runs, evidence, approvals, governed actions, and draft-PR publication state instead of copying those facts into a second incident system. Closing posts the same evidence-grounded post-incident draft that /responder postmortem can regenerate from the durable record. Responder automatically allocates more Coop session capacity as authorized requests arrive. /responder turn-limit shows or changes the channel or workspace lifetime safety ceiling; operators do not estimate how many turns an investigation needs. Commands are deterministic, operator-authorized, durably processed, and never interpreted by the model.

New incident channels use the validated slack.channel_prefix setting, which defaults to ems. For example, channel_prefix: sre produces names beginning with sre-. Changing the setting does not rename existing Slack channels.

Only configured operator user IDs who are full members of the configured workspace can steer an incident agent or approve an incident offer. Watched-channel messages can produce only a host-validated ignore, reply, incident offer, or permitted incident decision; they cannot invoke incident controls or invent a repository or policy. Engineering-task offers bind to an exact configured repository; when several are plausible, Responder asks the operator instead of silently using the default. Infrastructure access remains constrained by the selected Coop and Emisar policies. Slack guests and external Slack Connect identities are denied. See docs/slack-ux.md for the complete interaction contract.

Operations

responder status --config /etc/responder/responder.yaml
responder status --config /etc/responder/responder.yaml --json
responder failures --config /etc/responder/responder.yaml
responder retry --config /etc/responder/responder.yaml delivery delivery_...
responder replay slack --config /etc/responder/responder.yaml \
  --url 'https://workspace.slack.com/archives/C0123/p1785652207489039'
curl -f http://127.0.0.1:8080/healthz
curl -f http://127.0.0.1:8080/readyz
curl -f http://127.0.0.1:8080/metrics

responder status --json returns both lifecycle counters and the bounded incident directory. responder failures lists retryability and the retained error for failed Slack inputs, webhooks, Slack deliveries, agent runs, publications, and cleanup work. responder replay slack is a post-fix live verification tool. It clones the saved text, attachments, actor, channel, thread, and timestamp behind a Slack permalink (or accepts --input or --channel plus --message-ts), gives the clone a fresh idempotency identity, and queues it through the running service. Replays are private by default: the normal model and tool path runs, but Responder suppresses Slack status, reactions, messages, offers, schedules, tasks, and incidents. The command validates the resulting action without impersonating a new user turn. Add --publish only when another real response in the original Slack conversation is intentional; published replay additionally requires confirmed delivery and deterministic UX validation of the exact persisted message payload. Use --expect react, ignore, incident, or any only when that outcome is intentional.

State is one owner-private SQLite database in state_dir. Slack inputs, webhook events, outgoing Slack deliveries, agent runs, incident mappings, channel lifecycle, structured evidence, coverage, channel memory, operator-confirmed operational memory, Emisar approval holds, timelines, evaluation decisions, audit records, and the scheduler's compact work index are durable. Before a schema upgrade Responder creates and verifies a private pre-migration snapshot and retains the three newest migration backups. Bounded retention removes expired operational payloads and closed work. Coop cleanup is restricted to exact session IDs recorded by Responder: clean closed sessions and sessions whose reviewed tree is durable in a draft PR are discarded after a grace period, while dirty or unpublished work is retained. Deleting a Slack room does not itself discard work. See docs/operations.md for retry and recovery behavior.

V1 scope

V1 supports one Slack workspace and one repository context per incident. A context may be one repository or an explicit repository set: one primary writable/publishable repository and up to 32 operator-configured read-only companion repositories pinned at session creation. Multiple routes can select different contexts and Coop policies. Responder never accepts host paths from Slack or model output; the local Coop policy is their only authority. It can publish an explicitly authorized reviewed primary tree as a draft GitHub pull request, but cannot publish companion changes, merge, deploy from repository changes, or archive Slack channels. Automatic and inferred operational changes remain disabled. In any Slack conversation, a configured operator may directly request one exact operational action. Emisar remains authoritative for target validation, policy, approval, execution, and audit; Slack only links to the exact pending approval returned by Emisar. Responder monitors and reports that exact run but cannot approve it, substitute another run, or repeat the mutation during terminal verification.

Use the fast deterministic development gate while iterating:

make dev-check

Run the full CI and release gate once before shipping concurrency, persistence, security, or shared-contract changes:

make check

make customer-check is the faster deterministic product-behavior gate: it runs the Go customer journeys and replays the checked-in redacted JSONL response corpus through strict production parsers. It does not call a model. make eval CONFIG=/path/to/responder.yaml is the actual behavior eval: every case calls the configured model through its own Coop session, uses the production prompts and tool configuration, scores the returned decision, then discards the workspace only after Coop proves it is clean. Use shadow mode to collect candidate decisions safely, review and redact them, then promote representative contracts into the replay or live corpus before changing prompts or models. Use --case, --repeat, and --results for focused variance testing and private sanitized diagnostics. make model-release-check additionally calibrates the qualitative judge, evaluates the rendered Slack experience, measures proactive precision and recall, runs multi-turn cross-channel and old-thread scenarios, and independently re-checks high-risk operational claims. make eval-productivity adds an observable commit-and-review outcome when a disposable writable Coop policy is available. See docs/testing.md for the coverage matrix and bounded live acceptance set.

make snapshot builds the exact unsigned release archive layout locally; make release-check runs the full gate, builds both Linux archives, checks every checksum and required deployment file, and smoke-tests the host binary. On Linux it also executes the packaged native binary. See docs/releasing.md for the tag and publication contract.

Directories

Path Synopsis
cmd
responder command
internal
app
channelsetup
Package channelsetup reads what an operator is asking for when they talk to Responder about a channel's configuration.
Package channelsetup reads what an operator is asking for when they talk to Responder about a channel's configuration.
decision
Package decision owns the shapes a model result arrives in and the rules for reading one: the watch decision, the agent report, their typed operation stream, and every validator that decides whether a result may be acted on.
Package decision owns the shapes a model result arrives in and the rules for reading one: the watch decision, the agent report, their typed operation stream, and every validator that decides whether a result may be acted on.
localstate
Package localstate holds the service's process-local coordination state.
Package localstate holds the service's process-local coordination state.
memory
Package memory owns what Responder is allowed to remember, for how long, and who may see it.
Package memory owns what Responder is allowed to remember, for how long, and who may see it.
provider
Package provider turns a model provider's failure text into something an operator can act on.
Package provider turns a model provider's failure text into something an operator can act on.
publication
Package publication tracks a published pull request through its remaining life: checks, merge, deployment, and the Slack messages that report each.
Package publication tracks a published pull request through its remaining life: checks, merge, deployment, and the Slack messages that report each.
recall
Package recall decides which remembered context reaches a prompt.
Package recall decides which remembered context reaches a prompt.
schedule
Package schedule owns when recurring work should next happen, and whether a requested schedule is one Responder can honour.
Package schedule owns when recurring work should next happen, and whether a requested schedule is one Responder can honour.
store/behaviorstore
Package behaviorstore owns the durable behaviour an operator has taught Responder: preferences and standing rules.
Package behaviorstore owns the durable behaviour an operator has taught Responder: preferences and standing rules.
store/intelligencestore
Package intelligencestore owns what an investigation learned: evidence, coverage, claim assessments, the incident timeline, and action proposals.
Package intelligencestore owns what an investigation learned: evidence, coverage, claim assessments, the incident timeline, and action proposals.
store/lifecyclecheck
Package lifecyclecheck compares the agent-run lifecycle against the episode lifecycle.
Package lifecyclecheck compares the agent-run lifecycle against the episode lifecycle.
store/memorystore
Package memorystore owns everything Responder remembers between turns: memory entries, rollups, the review queue, and conversation memories.
Package memorystore owns everything Responder remembers between turns: memory entries, rollups, the review queue, and conversation memories.
store/schemagen command
Command schemagen prints the complete schema a freshly opened store produces.
Command schemagen prints the complete schema a freshly opened store produces.
store/sqlutil
Package sqlutil holds the helpers every persistence package needs.
Package sqlutil holds the helpers every persistence package needs.
store/storetest
Package storetest gives an extracted repository a migrated database to test against.
Package storetest gives an extracted repository a migrated database to test against.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL