[feat] Add channels - #5803
Conversation
Planning docs (context, plan, status, research index) plus the accepted research inputs: the RFC, the change-set interface spec, and the runner lifecycle architecture.
Both spikes are green. The decisions log records what was accepted from each spike and the seven product calls still open.
change-set, commit-transaction, read-config (engine-spike); execution-authorization, workspace-import, adapter-matrix (runner-spike). The value_from schema conflict is arbitrated; twelve product calls open.
…lls deduped to six
…orded Strict canonical serializer, multi-source atomicity, honest TOCTOU model, descendant confinement, harmless-forgery acknowledgement design, canonical generation payload, text-file import into text fields with diff approval, four-layer executable permission split.
…witch, S7c0 foundation slice, accepted Daytona risk
…ions, six open calls
…es, refactor plan, decision context
…ctions; inline marker validated; harness included
… errors, path normalization, selector forgiveness, optional free-text on all tools
…ditions; message derived server-side; invalid_operation split; v3 spike results
…ass match tolerance, uncommittable build kit
…irectives, .agenta-imports rename, folder policy dissolved by @ag.file, v3 assets, codex upstream check
… single-flag kill switch; open-issues log added
… rename costs nothing
…; cross-contract banners updated @ag.file marker, .agenta-imports root, list selector key with wrapper forgiveness, per-class match tolerance with length-preserving folds, derived commit message, split error codes with next-steps, platform-tool rejection, uniform reopen note, v3 instructions folded in as normative.
…tching (§18.2 with measured corruption examples)
…ssage/description); dao lock conditions
… absolute-path row struck, stale budget notes removed
… s7e credential handoff brief
…tion-honest semantics
…st settled; build-mode card gap logged
The {list,key} grammar fixed in every contract example (the old form is
refused by the shipped endpoint), the revision-selector contradiction
resolved on both sides with the implemented equality rule and the
recorded fallback, the on-acceptance list struck through with what
actually happened, and the unsafe pre-review wording in decisions.md
amended with why both halves were unsafe.
…s note, open issues)
feat(runner): bind an approval to the exact call that may execute
feat(runner): reopen a harness session without losing the sandbox
feat(runner): rotate a credential without deleting the sandbox
…-runner feat(runner): show the real change on the card, commit those bytes
feat(sdk): deliver the approval manifest to the live approval card
…-removal refactor (keep the Badge idiom from release, keep the defaultOpen/sectionOpenState feature from the lane, drop the stale antd imports)
…-web feat(frontend): show the frozen content and diff on commit approvals
…-mount fix(runner): steered sessions keep their workspace mount (pre-existing)
…migration feat(api): agent behavior leaves the public API: handler-mode ops, one error envelope, routes deleted
chore(clients): regenerate both API clients from the branch spec
…e benchmark's run identity is now derived from non-secret values only (base+project context hash replaces the API-key fingerprint; the record only needs to say which deployment context produced a run); the runner test asserts the fence shape with startsWith/endsWith instead of a regex CodeQL reads as HTML filtering; the web test parses rendered HTML with the test environment's DOM instead of regex tag-stripping, which is also more correct. No product code changes.
fix(ci): clear the CodeQL highs (test and benchmark code only)
The tab icon on agenta.ai did not match the docs (and every other Agenta surface). Browsers prefer the SVG favicon over the .ico when both are declared, so favicon.svg — not favicon.ico — is what actually renders, and it was the only asset in the set drawn from different measurements. The two .ico files are byte-identical; favicon.svg was hand-authored separately in the on-page-SEO commit and its transform was eyeballed: the symbol came out at 53.1% x 43.8% of the tile against ~71.5% x 58.6% everywhere else, on a #0A0A0B tile instead of #1E1C1D. Rescale the symbol to scale(2.14) at translate(73 105) and correct the tile fill and radius, which reproduces the bounding box of android-chrome-512x512.png to within a pixel: favicon.svg x[73..437] y[105..403] canonical x[73..438] y[106..404] Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Closes the last C0 gap. The design stated "one function composes it, no exceptions" but never said how, and the function name in circulation was invented rather than specified. external_key becomes a UUID — uuid5 over the adapter's declared key fields for that grain — rather than a joined string. A join needs an escaping rule for platforms whose ids carry the delimiter (Teams), and an untested escaping rule is a latent collision that merges two conversations. Adapters declare identity.key_fields per grain and never compose; core composes. The field set is the fragile part either way: change it and every row re-keys, and a hash makes that invisible rather than merely quiet. A declaration is checkable, so WP2's contract suite holds adapters to it — including the distinctness case, since a too-small field set silently merges threads. Renames the wire field data.space.external_key to data.space.locator: a bridge sends its platform's fields, never a key, and the old name would have invited a raw string into a UUID column. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Review pass. Each of these was the same concept said twice, or a platform
word in a channel-neutral place.
- ChannelDeliveryState.PENDING -> CREATED. Past tense like the trigger
states, and it records what we did rather than asserting a queue we do
not have.
- Inbox `content`/`sender` move under `processed`, which is what the table
below them already called that pair. `raw` stays commented on both sides.
- Agent DTOs inherit the house `Slug` mixin instead of declaring `slug: str`.
- Dropped `name` from the agent and space queries.
- ChannelSpaceCandidate: no external_key (it would key an unconfigured
place), `name` -> `display_name`, and a note on why a view holds its
locator flat.
- Catalog routes lose the repeated domain: /channels/catalog/, not
/channels/catalog/channels/.
- text.format is markdown|html|plain, never a platform's dialect name;
identity.scope and conversation.default_unit documented.
- addressing.sigils.{agent,command} and protocol.versions grouped.
- Protocol starts at 0.1.0. CloudEvents' specversion keeps its own name and
its own 1.0 — three version fields at three granularities, now
distinguished, with parsers dispatching on event type not protocol.
- adapter port gains discover_spaces (seven methods); verify_signature
returns the installation id, not bool — verification and identification
are one act.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Researched against the platforms' own docs and written into channels.md,
each with the values that are uncertain or tier-dependent called out rather
than rounded, and every non-obvious number cited.
The research broke the schema in four places, all of them one scalar being
asked to hold two real values, so the schema changed:
- files splits by direction. Telegram is 50 MB up / 20 MB down and Discord's
bot cap is not its user cap, so one max_bytes was wrong for two of three
first-class channels.
- Limits are now stated as "what the adapter renders against", not the
largest the platform documents. Slack publishes 4000 as guidance while
Block Kit enforces 3000; Telegram is 4096 plain but 1024 for a caption;
Discord 2000 plain but 4096 in an embed. Under-declaring degrades,
over-declaring fails at send.
- identity.scope can depend on the install, not just the platform: Slack
under Enterprise Grid issues one global user id. Declare the narrower
workspace value and let the wider install be a superset — the reverse
cannot distinguish two people sharing an id across workspaces.
- buttons.max: Slack has two live APIs with two real caps (legacy 5,
Block Kit 25). Declare the one the adapter builds against.
Grouping pass over the declaration, same theme as the last commit:
rendering.controls.{update,ephemeral}, addressing.commands.{native,
in_conversation}, conversation.default, identity.keys.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…gate Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
C0 of the channels workstreams: the frozen interface surface every parallel package codes against. Declarations only — no behaviour, no persistence, no routes mounted. - core/channels/dtos.py: entities, flags, policy documents, capability declaration, requests and responses - core/channels/types.py: the domain exception hierarchy - core/channels/interfaces.py: ChannelsDAOInterface - core/channels/adapters/interface.py: ChannelAdapterInterface, seven methods - core/channels/utils.py: compose_external_key and the key derivations; resolve_policy left NotImplementedError for WP1 - entrypoints/routers.py: the Channels tag and the mount scaffold compose_external_key is uuid5 over the adapter's declared identity.keys for a grain, so no platform field set is hardcoded in core. The seed tests assert the properties WP2's contract suite will hold every adapter to: grain distinctness, canonicalisation, the no-threads None, and a raise on an incomplete locator. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
20e8d2c to
d6b3e53
Compare
|
JP's channels work continues on |
No description provided.