Skip to content

fix(migration): add outbound_capabilities to fleet.yaml schema diff (#230 forward-link)#65

Merged
suzuke merged 2 commits into
mainfrom
fix/migration-outbound-capabilities
Apr 27, 2026
Merged

fix(migration): add outbound_capabilities to fleet.yaml schema diff (#230 forward-link)#65
suzuke merged 2 commits into
mainfrom
fix/migration-outbound-capabilities

Conversation

@suzuke

@suzuke suzuke commented Apr 27, 2026

Copy link
Copy Markdown
Owner

Summary

Cross-team Sprint 22 P0 PR #230 on agend-terminal introduced a breaking change: InstanceConfig.outbound_capabilities flipped from Option<Vec<...>> to required. Existing fleet.yaml files ported from @suzuke/agend will silently log a FATAL warn-but-permit line on Sprint 22 P0, then fail to load entirely once Sprint 23 ships. The migration guide must surface this before operators try to port.

This PR adds High-friction change #3 to §3 (between #2 group_id and the top-level keys table) plus a row in the "Rust-only fields you may want to add" table. Mirrors the user_allowlist / High-friction #1 treatment: tri-state semantics, exact symptom log line, explicit migration action with YAML example, and a forward-link to the operator deeper-dive at agend-terminal/docs/MIGRATION-OUTBOUND-CAPS.md.

Cross-team source

dev-impl-2 (PR #230 author) confirmed semantics via single-hop query (m-20260427044154458574-342). Source pointers verified against agend-terminal main:

What the doc adds

  • Tri-state semantics mirroring High-friction feat: inject fleet context system prompt into CCD instances #1's channel.user_allowlist: [ops...] permitted / [] fail-closed / absent → FATAL warn-but-permit one daemon cycle (Sprint 22 P0) → hard parse error (Sprint 23).
  • Exact symptom log line (tracing::error!) plus the rate-limiting note (mutex-guarded HashSet, once-per-instance per daemon process).
  • Built-in auto-inject explanation for TS users: general and future auto-created coordinators get [reply, react, edit, inject_provenance] injected automatically; user-authored YAML entries do not.
  • Migration action with YAML example covering both the explicit-list case (outbound_capabilities: [reply, react]) and the explicit-empty lockdown case (outbound_capabilities: []).
  • Forward-link from the new section to the agend-terminal-side docs/MIGRATION-OUTBOUND-CAPS.md for the full enum reference, 2-stage transition rationale, and cross-channel architecture notes.

Scope

Stats

  • 2 files changed, 78 insertions(+)
  • Pure addition — no rewrite of existing sections.

Reviewer dispatch

  • ts-reviewer — TS-side: writing quality + zh-TW parity + skeleton anchor preservation. audit_mode: light_review (no TS-side facts to audit; this is a Rust-only addition).
  • dev-reviewer-2 (cross-team) — Rust correctness re #230 semantics fidelity. audit_mode: scope_conformance.

🤖 Generated with Claude Code

suzuke and others added 2 commits April 27, 2026 12:47
…#230 forward-link)

Cross-team Sprint 22 P0 PR #230 on agend-terminal introduced a
breaking change: `InstanceConfig.outbound_capabilities` flipped from
`Option<Vec<...>>` to required. Existing `fleet.yaml` files ported
from `@suzuke/agend` will silently log a FATAL warn-but-permit line
on Sprint 22 P0, then fail to load entirely once Sprint 23 ships.
The migration guide must surface this before operators try to port.

Adds High-friction change #3 to §3 (between #2 group_id and the
top-level keys table) plus a row in the "Rust-only fields you may
want to add" table. Mirrors the user_allowlist / High-friction #1
treatment: tri-state semantics table, exact symptom log line,
explicit migration action with YAML example, and a forward-link to
the operator deeper-dive at agend-terminal/docs/MIGRATION-OUTBOUND-CAPS.md.

Content covered:
- `instances.<name>.outbound_capabilities: Vec<ChannelOpKind>` framing
  as Rust-only (no TS equivalent — TS had implicit channel ACLs).
- Four current ChannelOpKind variants + YAML snake_case mapping:
  reply / react / edit / inject_provenance ↔ Reply / React / Edit /
  InjectProvenance.
- Tri-state semantics: list of ops permitted / `[]` fail-closed /
  absent FATAL warn-but-permit-one-cycle (Sprint 22 P0) → hard parse
  error (Sprint 23).
- Symptom log line via `tracing::error!`, once-per-instance per
  daemon process (mutex-guarded HashSet).
- Built-in coordinator auto-inject: `general` (and any future
  auto-created coordinator) gets [reply, react, edit,
  inject_provenance] via bootstrap::fleet_normalize::auto_create_general
  (src/bootstrap/fleet_normalize.rs:24-67). User-authored YAML
  entries are NOT auto-injected.
- Migration action with YAML example covering both the explicit-list
  case and the explicit-empty (lockdown) case.

Source pointers all verified against agend-terminal main per
dev-impl-2's confirmation (cross-team query, m-20260427044154458574-342):
- `src/fleet.rs:173-208` (field doc-comment)
- `src/channel/auth.rs::gate_outbound_for_agent`
- `src/channel/auth.rs::ChannelOpKind` (enum)
- `src/bootstrap/fleet_normalize.rs:24-67` (auto-create-general)
- Forward-link to `docs/MIGRATION-OUTBOUND-CAPS.md` for the full enum
  reference, 2-stage transition rationale, and cross-channel
  architecture notes.

zh-TW pair updated identically. 39 lines added on each side, 78
total. No content rewrite of existing sections; pure addition.

Surrogate authority: `d-20260427025246010573-0`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ewer-2 F1)

dev-reviewer-2 cross-team audit on PR #65 (reviewed_head 38a32ee)
flagged the `auto_create_general` line-range cite as drifted:

- Doc cited :L24-L67 in two places (EN + zh-TW).
- Actual `fn auto_create_general` spans :L38-L87 in agend-terminal main.
- Lines :L24-L29 are the `default_built_in_outbound_capabilities()`
  helper's `vec!` literal, not the fn body.
- :L67 sliced the fn mid-body (between `if !persist { return; }` and
  the `let entry = …` block).

Per ts-lead's option (a) recommendation, both citations now use the
inclusive range :L23-L87 — single anchor that covers both the helper
(four-cap source) and the fn (call site) without splitting the
operator's mental model. Added a parenthetical clarifying the helper
+ fn coverage so the reader knows what they're seeing on click-through.

EN line 199 + zh-TW line 197. New commit on top of 38a32ee per
CLAUDE.md (no amend).

ts-reviewer F1 cross-link 404 NOT addressed in this PR (resolves
naturally on agend-terminal #230 merge per dev-lead's sequential merge
plan; my PR body already frames the link as forward-link).
ts-reviewer O1 table shape NOT changed (justified by phased rollout
narrative; non-blocking).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@suzuke suzuke merged commit 9292f69 into main Apr 27, 2026
1 check passed
@suzuke suzuke deleted the fix/migration-outbound-capabilities branch April 27, 2026 05:00
suzuke added a commit that referenced this pull request Apr 27, 2026
… + Known incompatibilities (#66)

Final phase of TS→Rust migration guide. 7-section guide complete. Verdicts: ts-reviewer full_review VERIFIED + dev-reviewer-2 scope_conformance VERIFIED at head 9638d5e. Polish revision 1fc19d4 (M1 medium Sprint 11 timeline reframe + L1 LOW portable-pty crate caveat + O1 LOW busy-gate note for delegate_task smoke test) + micro-fix a9509de (Rust PR #197/#199 → #149/#161 citation correction per dev-reviewer-2 cross-team git-blame). Polish + micro-fix inspected by ts-lead as surgical mechanical, no substantive change. Sprint 2 ledger now complete: Phase A (#63 + #65 follow-up) + Phase B (#64) + Phase C (#66) = 4 PRs landing 7-section migration guide ready for agend-terminal Sprint 24 input.
suzuke added a commit that referenced this pull request Apr 27, 2026
#67)

Sprint 2 outcome: 4 PRs (#63, #64, #65, #66) ship the canonical TS→Rust
migration guide as docs/migration-to-agend-terminal.md (+ zh-TW pair).
Cross-team coordination with dev-team (agend-terminal Rust) operationalised
general's D3 single-hop dispatch pattern; 7-section guide complete with
stable anchors ready for agend-terminal Sprint 24 input.

Wall time ~1h40m for full pipeline including all phases, audits, polish
cycles, cross-team merge-ordering, and architectural side-fix routing
(F-NEW-OUTBOUND-DROP-LOG-SEVERITY-1 routed to dev-team Sprint 22 P1).
suzuke added a commit that referenced this pull request May 4, 2026
…lt-open semantics (#242 forward-link) (#68)

Cross-team Sprint 23 P1 PR #242 on agend-terminal merged 12:34:05Z and
reversed the Sprint 22 P0 fail-closed default for
`InstanceConfig.outbound_capabilities` to default-open per operator
philosophy ("absent ≡ all permitted"). Phase A follow-up PR #65's §3
content is now stale on three points; this PR corrects them.

Three changes (per dev-impl-1 m-20260427120947207036-102 +
dev-lead m-20260427123428908163-123):

1. Tri-state framing reverse. Old §3.3 row asserted absent → FATAL
   warn-but-permit one daemon cycle (Sprint 22 P0) → hard parse error
   (Sprint 23). New row: absent → all ops permitted (default-open).
   The full decision matrix is now: absent → all permitted, listed →
   only listed permitted, [] → all rejected.

2. Remove FATAL log expectation. The `gate_outbound_for_agent` warning
   logic was removed in #242 along with the original fail-closed
   default. The "Symptom when key is absent" subsection (with the
   `tracing::error!` line and the mutex-guarded HashSet rate-limit
   description) is removed entirely.

3. Remove `general` auto-inject paragraph. Built-in coordinators now
   inherit default-open like every other instance — no special
   `[reply, react, edit, inject_provenance]` injection. The forward
   link to `bootstrap::fleet_normalize::auto_create_general` (which
   may be refactored upstream per #242) is no longer cited.

Threat-model distinction made explicit (per ts-lead spec). The §3.3
section now opens with a heading change ("…with a deliberately-different
default than `user_allowlist`") and includes a 2-row alignment table
contrasting the two gates:

- `channel.user_allowlist` (per-channel, channel ingress) → fail-closed.
  An open default is one credential leak away from internet-driven
  fleet abuse; silent operator regression is possible.
- `outbound_capabilities` (per-instance, per-op outbound) → default-open.
  Closed default would force every operator-defined instance to
  declare every op without a corresponding cascade-attack risk;
  over-specification.

Operator reading the doc now sees the deliberate design split, not an
inconsistency.

Forward link to docs/MIGRATION-OUTBOUND-CAPS.md preserved (upstream
already updated per dev-impl-1 to reflect Sprint 23 P1 semantics).

Stats: 2 files / +48 / -40 (deletions of stale FATAL/auto-inject
paragraphs + addition of decision matrix + threat-model alignment
table). Scope strictly §3 outbound_capabilities row + Rust-only fields
table cell — other sections (§1, §6, §7) intentionally not touched
per ts-lead constraints; will surface remaining stale references to
ts-lead in the report for a follow-up decision.

EN line 218-254 + zh-TW line 216-252 reworded; EN line 304 + zh-TW
line 306 (Rust-only fields table cell) updated to default-open.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant