Files
agent-lib/docs/fleet-handoff.md
T
m3ta-chiron 67cd4e4737 feat: e2e acceptance script, README and fleet handoff docs
- scripts/e2e-acceptance.sh: offline spec walk (fixture upstream -> vendor
  add/determinism/collisions/renames -> validate/list/inspect -> update
  cycle -> employee sync -> idempotence -> protected sync -> deletions ->
  status drift -> unreachable repo), 61 assertions on tree, lockfile,
  manifest and exit codes
- README: installation, curator guide (selection rules, renames), client
  guide (three-state semantics, notifications), security model,
  troubleshooting, scope
- docs/fleet-handoff.md: rollout (pinned release, admin-protected config,
  user-context scheduled task), token rotation, ADR draft superseding the
  exact-mirror doctrine, fleet verification checklist
2026-08-23 10:43:41 +02:00

138 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Fleet handoff — agent-lib v2 rollout
What az-fleet must roll out, and why. This document is written so the fleet
team can implement their role from this file alone.
## What the binary does (and does not do)
`agent-lib` is one static Go binary with two roles:
- **Curator** (maintainer machine): `vendor add/update/diff/remove/list/inspect`
plus `validate` — manages external content inside the company work
repository. Publication = `git commit && git push` by the maintainer.
- **Client** (employee machine): `sync` + `status` — pulls the work repository
and deploys skills/commands/agents into the OpenCode paths. Deploys with
three-state protection: user-modified managed items are skipped with a
warning (never steamrolled), self-created items are never touched,
unmodified items update/remove silently.
The binary handles all content transport itself. It never deploys or merges
MCP fragments — `mcp/` and `external/*/mcp/` stay under controller-side merge
and vault substitution (clone the work repository as before, now including
the external areas).
## Rollout components
### 1. Binary via pinned GitHub release
- Source of truth: GitHub releases of `m3tam3re/agent-lib`.
- Artifacts: `agent-lib_{windows_amd64,linux_amd64,linux_arm64,darwin_amd64,darwin_arm64}`
plus `checksums.txt` (tar.gz archives; windows is a zip).
- Fleet pins an exact release tag (installer-pin pattern already used for
other tools). **No self-update exists in the binary** — binary updates are
exclusively fleet rollouts. Content updates are pulled by the binary itself.
- Verify the checksum during rollout; install to a fixed path
(e.g. `C:\Program Files\agent-lib\agent-lib.exe` / `/usr/local/bin/agent-lib`).
### 2. Admin-protected client config
Path: `C:\ProgramData\agent-lib\config.json` (Windows, ACL restricted to
Administrators + read for Users) or `/etc/agent-lib/config.json` (Linux,
root-owned, mode 0644).
```json
{
"repo_url": "https://git.example.com/company/agent-content.git",
"ref": "main",
"token": "<read-only deploy token>",
"token_user": "oauth2"
}
```
- The token is a **shared read-only** deploy token scoped to the work
repository. It is used for HTTP basic auth only and never appears in the
lockfile, the manifest, logs, or error output.
- Employees must be able to read the config (sync runs in their context) but
must not be able to alter it.
- Per-run overrides for testing: `--config <path>` or `AGENT_LIB_CONFIG`.
Local state (manifest, cached bare repo, sync log) lives per-user:
`%LocalAppData%\agent-lib` on Windows, `~/.local/state/agent-lib` on Linux
(override with `AGENT_LIB_STATE_DIR`).
### 3. Scheduled task — logged-in user context (required)
- Schedule `agent-lib sync` per user, **running as the logged-in user, not
SYSTEM**. Two reasons:
1. Deployment targets (`~/.agents/skills`, `~/.config/opencode/...`) resolve
against the user's profile.
2. Windows toast notifications require an interactive user session. A task
running as SYSTEM produces no visible toasts.
- Suggested cadence: every 14 hours plus/except at logon. Sync is idempotent
and cheap when unchanged.
- Optional companion: a drift check running `agent-lib status --json`
headless; its non-zero exit (`problematic_drift: true`) means a user's local
modifications are blocking company updates — feed it into monitoring.
## Token rotation procedure
1. Create/rotate the read-only deploy token on the git host.
2. Update `token` in the admin-protected config via the fleet (single run;
config is fleet-managed, so this is one playbook task).
3. No client-side action: the next scheduled sync picks up the new token
(config is read on every run). The old token can be revoked once the
fleet run completed.
4. A failed sync never damages local state — a revoked token mid-rotation
only means "no updates until the config arrives".
## ADR draft — superseding the "exact mirror" doctrine
> # ADR-000X: agent-lib three-state sync supersedes exact-mirror deletion
>
> ## Status
> Proposed (supersedes ADR-0006 "exact mirror including deletion")
>
> ## Context
> The previous fleet doctrine required employee machines to be an exact
> mirror of the company content repository, including deletions. This
> steamrolled legitimate local work: employees' own skills and their local
> adjustments to company skills were destroyed by routine syncs.
>
> agent-lib v2 replaces the mirror sync with a **manifest-based three-state
> sync**: a local manifest records every item agent-lib deployed (name, type,
> origin, revision, content hash), and the planner compares repository,
> manifest and on-disk content per item.
>
> ## Decision
> 1. Managed items that the user modified locally are **skipped** — the local
> version wins, a warning is logged and (on Windows) toasted.
> 2. Items on disk that agent-lib never deployed are **unmanaged** — left
> untouched, reported by `status` as unrecognized.
> 3. Upstream deletions remove only the **unmodified** managed copies;
> modified copies are kept and warned about.
> 4. Everything else (new, changed-unmodified) updates silently; sync is
> idempotent and safe to schedule.
>
> ## Consequences
> - Employee machines are no longer exact mirrors by design; drift is
> visible (`status`, exit code) instead of silently destroyed.
> - "What's in the repo is what I have" holds for everything the user never
> touched.
> - Remediation for blocked updates is a human decision (restore the company
> version by deleting the local copy and re-syncing), not a forced
> overwrite.
> - The controller-side MCP merge is unaffected: it clones the work
> repository (now including `external/*/mcp/`) and continues to own
> activation, merging and vault substitution.
## Verification checklist for the fleet team
- [ ] Pinned binary installed, `agent-lib version` prints the release version.
- [ ] Config at the admin-protected path, readable by users, writable only by
admins; token present.
- [ ] Scheduled task runs as the logged-in user; toast appears when a
modified item is skipped (manual visual check on a Windows client).
- [ ] `agent-lib status` exits 0 on a clean machine, non-zero after editing a
deployed file (self-test).
- [ ] Drift monitoring consumes `status --json``problematic_drift`.