Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
8555530
orchestrator: pin the built-in definition hashes and list the files t…
nikhilunni Nov 11, 2026
a1426c1
orchestrator: one event route and one signature verifier for every pr…
nikhilunni Nov 11, 2026
058c4b8
orchestrator: one model-router seam; OpenRouter is one implementation
nikhilunni Nov 11, 2026
1ee3f50
orchestrator: the event route has one clock and passes an unknown pro…
nikhilunni Nov 11, 2026
ea50f7a
orchestrator: the catalog refresher lists secret names once per pass
nikhilunni Nov 11, 2026
1dd6733
orchestrator: LiteLLM as a second model router
nikhilunni Nov 11, 2026
decb58a
orchestrator: bound the chat decision call and keep unset router sett…
nikhilunni Nov 11, 2026
475a0ed
forge: git credentials follow the session's capabilities; GitLab git …
nikhilunni Nov 11, 2026
718c97a
orchestrator: an Azure DevOps connector with git over HTTPS
nikhilunni Nov 11, 2026
df3bd3b
egress-proxy: git path rules match the path and the query apart
nikhilunni Nov 11, 2026
0522770
orchestrator: a git-forge seam; GitHub is its first implementation
nikhilunni Nov 11, 2026
a431e37
helm: backend selectors have no default
nikhilunni Nov 11, 2026
fb5c430
orchestrator: pr_ref keeps its old unique index for one release; forg…
nikhilunni Nov 11, 2026
3f89601
web: router features ask for a decision model, not for OpenRouter
nikhilunni Nov 11, 2026
c79323c
orchestrator: a chat seam; Slack is its first implementation
nikhilunni Nov 11, 2026
7b4abeb
orchestrator: the PR-link upsert tries twice before it skips a key co…
nikhilunni Nov 11, 2026
444326f
web: role model fields keep the typed value until the save succeeds
nikhilunni Nov 11, 2026
2e125b4
orchestrator: the code-review built-in is one builder with a variant …
nikhilunni Nov 11, 2026
e108c72
orchestrator: the chat-threads built-in is one builder with a variant…
nikhilunni Nov 11, 2026
8fd192f
orchestrator: a relay stays until its closing message is posted; chat…
nikhilunni Nov 11, 2026
8b8fba9
web: a role model save does not hold back another field's save
nikhilunni Nov 11, 2026
770e0ab
orchestrator: a posted review with no readable id is logged
nikhilunni Nov 11, 2026
052bcd6
orchestrator: a built-in variant states every slot its builder reads
nikhilunni Nov 11, 2026
98dcd5c
orchestrator: remove the tool presenters field; nothing reads it
nikhilunni Nov 11, 2026
f5c657d
orchestrator: five more files name no provider
nikhilunni Nov 11, 2026
85fefec
orchestrator: the review-command parser is forge-neutral
nikhilunni Nov 11, 2026
ee41bf1
orchestrator: GitLab is a git forge with a merge-request review
nikhilunni Nov 11, 2026
0a23140
web: the builder and the review repositories read providers from the …
nikhilunni Nov 11, 2026
ba30453
orchestrator: a GitLab review completes after a failure part way; rev…
nikhilunni Nov 11, 2026
3f486f3
orchestrator, web: review fixes for the relay, retry, and role model …
nikhilunni Nov 11, 2026
2f931ab
orchestrator, web: the forge builds a review's links and the API send…
nikhilunni Nov 11, 2026
0e43b8f
web: a review's run link opens the review automation of its forge
nikhilunni Nov 11, 2026
4f1797a
docs: the integration roles, how to add a provider, and the changelog
nikhilunni Nov 11, 2026
61e12e6
orchestrator: a GitLab review checks each position first and owns its…
nikhilunni Nov 11, 2026
31f1375
orchestrator, web: GetReview names the automation of a pass's run; re…
nikhilunni Nov 11, 2026
ad8667b
docs: the changelog entries of this branch are under Unreleased
nikhilunni Nov 11, 2026
17e7957
docs: the changelog entries name their pull request
nikhilunni Nov 11, 2026
a550482
orchestrator: the pr_ref store test reads the rejection itself
nikhilunni Nov 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,23 @@ jobs:
-f "$chart/ci/render-values.yaml" -f "$stub" > /dev/null
done
done
# A backend selector has no default, so an install states its cloud.
- name: helm template (an unset backend selector fails)
run: |
set -euo pipefail
check() {
chart="deploy/helm/$1"
if helm template test-release "$chart" \
-f "$chart/ci/render-values.yaml" --set "$2=" > /dev/null 2>&1; then
echo "$1 renders with $2 unset" >&2
exit 1
fi
}
check engram blob.backend
check engram kek.provider
check engram secrets.backend
check engram-host-fleet blob.backend
check engram-host-fleet egress.caSource
# Node prep's disk scheduler script against constructed sysfs trees,
# and the chart default that turns it on.
- name: host-fleet io scheduler
Expand Down
40 changes: 40 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,45 @@ starts with **Upgrade notes**: read them before you upgrade. The upgrade procedu

## [Unreleased]

### Upgrade notes

- **Set the backend selectors in your Helm values before you upgrade.** They have no
default now, and `helm upgrade` fails at render, before it changes the release, when one
is unset. An install that relied on the old defaults sets `blob.backend: gcs`,
`kek.provider: gcp-kms` and `secrets.backend: gcp` (`engram`), and `blob.backend: gcs`
and `egress.caSource: gcp-secret-manager` (`engram-host-fleet`). The example overlays
set all of them. ([#1793])
- **Upgrade the hosts before the control plane to use GitLab or Azure DevOps git.** A
session clones and pushes to them through the egress proxy of the new host agent.
([#1793])
- **A rollback past this release** makes a profile routed to LiteLLM, and the GitLab
review, fail until you upgrade again. Nothing else changes back. ([#1793])

### Added

- **LiteLLM is a model router.** Point engrams at your own LiteLLM proxy and route Claude
Code and Codex sessions, titles and decisions through it. An admin picks the model for
each of those roles on Settings → Model routers. ([#1793])
- **GitLab merge request review.** GitLab is a git forge: sessions clone and push with the
organization's token, which stays out of the VM, and a second review built-in reviews
merge requests. It needs GitLab 17.4 or later. An organization can use GitHub and GitLab
together. ([#1793])
- An Azure DevOps connector: git over HTTPS, pull requests, work items and pipelines. It
has no review built-in. ([#1793])

### Changed

- **Git forges, chat services and model routers are roles.** GitHub, Slack and OpenRouter
are implementations of them, and a new provider that fills a role gets the features built
on it. The pull request review and the Slack thread bot are unchanged. The site's "Add a
provider" page says what a provider implements. ([#1793])
- A Decide block and smart routing work with any connected router that has a decision
model. A router with no decisions endpoint answers with a structured chat completion.
([#1793])
- A session gets git credentials only for a forge that its profile grants. ([#1793])
- Every provider's webhooks arrive at `/api/v1/integrations/<provider>/events`. The URLs of
the existing providers are the same. ([#1793])

## [0.13.0] - 2026-11-11

### Upgrade notes
Expand Down Expand Up @@ -389,3 +428,4 @@ The first tagged release. See the
[#1784]: https://github.com/cortexapps/engrams/pull/1784
[#1788]: https://github.com/cortexapps/engrams/pull/1788
[#1789]: https://github.com/cortexapps/engrams/pull/1789
[#1793]: https://github.com/cortexapps/engrams/pull/1793
44 changes: 44 additions & 0 deletions DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,50 @@ pub trait SandboxBackend: Send + Sync {

Firecracker has no "exec a command in a running guest" primitive. Every guest runs `engram-agentd` (`crates/engram-agentd`) — a small Rust binary the stage-1 init copies out of its reserved bundle slot to `/run/engram/engram-agentd` and execs (ADR 0080; nothing engrams-owned is baked into the rootfs beyond the shim). It listens on AF_VSOCK port 1024 and proxies exec / stdin / stdout for the host agent. `SandboxBackend::exec_stream` on the Firecracker backend connects to Firecracker's vsock proxy at `<vsock_uds>`, performs the `CONNECT 1024\n` → `OK <peer_port>\n` handshake, sends a `WireExecRequest`, and streams `WireExecEvent`s back. Full design in the [In-guest agent](#in-guest-agent-engram-agentd) section below.

### Integration roles (in `orchestrator/`)

The product features that talk to an outside service go through three role seams. A
provider's code is under `orchestrator/src/providers/<name>/`; its connector JSON under
`orchestrator/src/connectors/` declares the hosts, the credential, the webhook, and the
actions. The guard for each fact is the test named beside it.

| Role | Interface | Registry | Implementations |
|---|---|---|---|
| Git forge | `GitForge` (`forges/forge.ts`) | `forges/registry.ts` | GitHub, GitLab |
| Chat | `ChatProvider` (`chat/chat.ts`) | `chat/registry.ts` | Slack |
| Model router | `ModelRouterSpec` (`model-routers/registry.ts`) | the same file | OpenRouter, LiteLLM |

- Code outside `providers/` names no provider. Four files are the exception, each with its
reason in the test (`only the listed files name a provider outside src/providers`).
- A role lookup with no implementation is an error or `null`, never another provider. A
stored row or block config from before the roles names no provider; it means the
provider whose spec has `legacyDefault`.
- Every provider's webhooks arrive on one route, `/api/v1/integrations/:provider/events`.
The connector's `webhook.ingress.scheme` selects the verifier in `automations/verify.ts`;
the provider supplies an `IntegrationEventSource` that says what a verified delivery
means.
- A built-in automation is a family: one builder holds the graph, and each provider fills
a variant (`ReviewVariant`, `ThreadsVariant`). Each variant is its own built-in row with
its own key and settings. The GitHub and Slack variants build the definitions that
shipped before the roles (`the PR review definition hash is unchanged`,
`the Slack threads definition hash is unchanged`); a changed hash stops every active run
of that built-in.
- A forge builds every link to itself (`GitForge.links`); the review API sends the links
and the web does not build them (`GetReview sends the forge's links for the pass and its
findings`).
- A forge that can check a commenter's permission and edit one comment has `typedReview`.
Its review variant uses the typed `review_facts` block; GitHub's variant keeps its
QuickJS facts step, because its definition hash must not change.
- A router with no native decisions endpoint answers a `decide` block with a structured
chat completion. A router with no built-in model for a role needs an admin's choice
before a feature that uses the role is offered.
- Git credentials follow the session's capabilities. A forge that mints short-lived tokens
(GitHub) answers git's credential helper in the guest. A forge with a static token
(GitLab, Azure DevOps) has git path rules in its connector, and the egress proxy adds
the token; the token is never in the guest.
- A `pr_ref` row is unique per `(provider, repo, pr_number)`. One connection per provider:
an org can use GitHub and GitLab together, but not two GitLab hosts.

---

## Communication architecture
Expand Down
Loading
Loading