Skip to content

RFC: Fleet Metadata Repository & Team Sharing ​

Proposal — not a feature guide

This is a draft design proposal, not documentation of shipped behavior. Only an experimental first increment (the opt-in --team tier) has landed; see the Team Meta-Repo guide for what actually works today. Interfaces, commands and flags below may change or never ship.

  • Status: Draft (proposal)
  • Owner: Fleet platform
  • Scope: A companion <repo>-fleet-meta git repository plus a new "team tier" that lets teams share crews, skills, roles, workflows, context, and (phased) pooled intel, datasets, and team shadow — without committing .fleet/ into the code repo.

1. Summary ​

Teams using agents-fleet today have no first-class mechanism to share fleet configuration (skills, roles, crews, workflows, context documents) across repositories or machines. Configuration is per-user (~/.fleet/) or per-project (.fleet/), and the bundle export/import system (bundleExportV2 / bundleImportV2) is manual, crew-rooted, and offers no versioning, remote fetch, or push.

This RFC proposes:

  1. A fleet metadata repository (<team>-fleet-meta) — a standalone git repo with a defined layout for fleet artifacts, plans, insights, and (phased) intel datasets.
  2. A team tier added to the SkillRegistry tier stack (between user and project), loaded from a local clone of the meta-repo.
  3. A sync + writeback model: pull-on-start (read), opt-in PR writeback.
  4. (Phased) Intel aggregation with redaction-at-rest prerequisites, and team shadow / training with shared task suites and quorum-before-promote.

2. Motivation / Problem ​

2a. Team distribution of fleet configuration ​

Today's options for sharing fleet artifacts across a team:

ApproachDrawback
Commit .fleet/ to the code repoPollutes code PRs with prompt/config churn; repo-owner friction; workflows reference skills that live elsewhere.
Copy bundles manuallyNo versioning; no auto-sync; crew-rooted only — standalone roles/skills/context can't travel.
Share ~/.fleet/ via dotfiles repoNot multi-project-aware; no per-team scoping; leaks personal intel.

None of these support multi-repo teams where 5+ repos share the same fleet configuration, or onboarding where a new team member gets functional fleet config on first clone.

2b. Team learning loop ​

The intel subsystem stores rich operational data (outcomes, steering insights, eval runs, prompt history) — but exclusively per-machine in ~/.fleet/intel/fleet-intel.db. There is:

  • No cross-machine sharing of insights or outcome data.
  • No shared task suites for experiments / shadow evaluation.
  • No team-level quorum ("did 3/5 team members see the same improvement?") before promoting a shadow skill.
  • No training-data export (JSONL / fine-tune format) for external model improvement pipelines.

Combined, this means each team member operates in isolation: learnings don't compound across the team.

2c. Gaps cited (source-verified) ​

  • SkillRegistry.loadTier — only 3 local tiers (bundled, user, project); NO remote/team tier (src/skills/SkillRegistry.ts:238-240).
  • bundleExportV2 — crew-rooted transitive closure only; excludes context/ and intel/; no version registry; no remote push (src/skills/bundleExportV2.ts:1-11).
  • IntelDatabase — ~22 tables at ~/.fleet/intel/fleet-intel.db; raw unredacted prompts, paths, commits in prompt_history, steering_insights, errors, agent_runs (src/intel/SchemaManager.ts:150-172, 325-331).
  • PiiRedactor — called at export/worker-leak time, NOT at rest for prompt_history or steering_insights (src/intel/IntelDatasetExporter.ts:12-14, src/intel/SchemaManager.ts:575).
  • Shadow/eval — replays past tasks on current vs shadow; no shared suites, no cross-machine pooling (src/intel/EvalScheduler.ts:278, src/intel/AgentRunAnalytics.ts:263).

3. Goals / Non-Goals ​

Goals ​

  • G1: A team shares a single source-of-truth for fleet config across N repos.
  • G2: Sync is declarative (pointer in code repo) and offline-tolerant.
  • G3: Privacy-sensitive data never leaves a machine without explicit consent + redaction.
  • G4: The design composes with existing tier precedence / trust gates.
  • G5: Incremental — each increment is independently shippable and valuable.

Non-Goals ​

  • NG1: A hosted registry service (SaaS) — v1 is git-native; service is future.
  • NG2: Live multi-machine coordination (distributed locking, CRDTs).
  • NG3: Replacing project-tier .fleet/ — the project tier remains for repo-specific overrides.
  • NG4: Automatic promotion without human review (quorum is advisory).
  • NG5: Changing the intel schema's at-rest storage semantics for local use — /learn fidelity requires raw prompts locally.

4. Current State ​

4.1 Three-tier loading ​

SkillRegistry.reload() (src/skills/SkillRegistry.ts:228-240) loads:

bundled  →  user  →  project
  • Bundled: src/skills/bundled/ (read-only, process-lifetime cache per PERF-2; src/skills/SkillRegistry.ts:175-180).
  • User: resolveFleetHome() = ~/.fleet or $FLEET_HOME (src/utils/resolveFleetHome.ts:11-12). Subdirs: roles/ skills/ crews/ workflows/ intake/ context/ intel/ sessions/ shadows/ outbox/.
  • Project: <cwd>/.fleet/ (src/skills/SkillRegistry.ts:74). Subdirs: roles/ skills/ crews/ workflows/ intake/ context/.

Later tiers override earlier by name (upsertArtifact). loadTier is typed as 'bundled' | 'user' | 'project' (src/skills/SkillRegistry.ts:418).

4.2 Trust gates ​

GateDefaultOverride
Project skills/roles/crewsOFF--trust-project-skills / AGENTS_FLEET_TRUST_PROJECT_SKILLS=1 (src/commands/resolveTrustProjectSkills.ts)
Project workflow command synthesisON--no-trust-project-workflows (workflows still load; discoverWorkflowCommands.ts)
Project MCPOFF--trust-project-mcp / AGENTS_FLEET_MCP_TRUST_PROJECT=1 (McpDiscovery.ts)

4.3 Bundle export/import (v2) ​

BundleManifestV2 (src/skills/bundle.ts:30-41):

ts
interface BundleManifestV2 {
  bundleVersion: '2';
  exportedAt: string;
  crew: string;   // root of transitive closure
  artifacts: Array<{
    kind: 'role' | 'skill' | 'workflow' | 'crew';
    name: string;
    sha256: string;
    allowOverride?: boolean;
  }>;
}
  • Export: crew-rooted, walks transitive closure, dedupes by kind:name, sha256 per artifact (src/skills/bundleExportV2.ts:47-51).
  • Import: parse-validate-before-write; atomic (all-or-nothing); target = 'user' | 'project' tier (src/skills/bundleImportV2.ts:78-82).
  • Excludes: context/, intel/, standalone skills/roles not reachable from a crew.
  • No: remote fetch, registry, versioning, push.

4.4 Intel DB ​

SQLite at ~/.fleet/intel/fleet-intel.db (src/intel/SchemaManager.ts:41). ~22+ tables including sessions, agent_runs, errors, skill_usage, suggestions, steering_insights, prompt_history, worker_compositions, eval_runs, labeled_outcomes, worker_leaks, experiment_*.

Privacy blocker for sharing:

  • prompt_history.prompt, agent_runs.task_subject, errors.message, steering_insights.* — raw, unredacted at rest.
  • PiiRedactor is applied only on:
    • export (IntelDatasetExporter, defense-in-depth; src/intel/IntelDatasetExporter.ts:12-14).
    • worker-leak insert (WorkerLeakStore redacts via PiiRedactor BEFORE insert; src/intel/SchemaManager.ts:574-576).
    • labeled_outcomes insert (redacted at rest; src/intel/IntelDatasetExporter.ts:14).
  • IntelDatasetExporter.export() writes REDACTED cases into the SAME local SQLite (experiment task suites) — there is no file-based / JSONL / cross-machine export path.

4.5 Shadow / experiments ​

  • SkillEvolver proposes shadow variants; EvalRunner + EvalScheduler replay past tasks (getRecentTaskForSkill; src/intel/AgentRunAnalytics.ts:263) against current vs shadow; scored by VerifierNode + EvalJudge.
  • Experiments (src/intel/experiment/) add A/B/n with task suites — but suites are local, no shared suites, no cross-machine pooling, no quorum gate.

4.6 What's missing (summary) ​

  1. No remote/team tier in the loading stack.
  2. No declarative pointer from a code repo to a shared config source.
  3. No standalone-artifact bundles (skills/roles without a crew root).
  4. No redacted cross-machine export path (file/JSONL).
  5. No shared task suites or pooled eval results.
  6. No quorum-before-promote gate.
  7. No training-data export.

5. Proposed Design — Part A: Meta-repo + Team Tier (core) ​

5.1 Meta-repo layout ​

<team>-fleet-meta/
├── fleet-meta.toml        # manifest: team name, member repos, config
├── fleet.lock             # lockfile: artifact hashes for deterministic sync
├── crews/                 # *.crew.md
├── skills/                # *.skill.md
├── roles/                 # *.role.md
├── workflows/             # *.workflow.md
├── context/               # shared context documents (*.md)
├── plans/                 # shared plans / architecture notes
├── insights/              # exported steering insights (redacted)
└── intel/                 # (Phase B) metrics JSONL, task suites, eval results

fleet-meta.toml schema sketch ​

toml
[meta]
name = "acme-backend-team"
version = "1"                    # manifest schema version

[team]
description = "Backend squad fleet configuration"
members = ["alice", "bob"]       # advisory; not enforced

# Artifact precedence within the meta-repo (optional overrides)
[precedence]
# If two meta-repos are layered (future), later overrides earlier.
# Within a single meta-repo, all artifacts are peers.

[sync]
defaultRef = "main"
autoSyncOnStart = true
syncIntervalMinutes = 0          # 0 = on-start only; >0 = periodic background

fleet.lock ​

Tracks the per-artifact sha256 of the most recent synced state so the local clone can detect drift without network:

toml
# Auto-generated — do not hand-edit.
[[artifacts]]
kind = "role"
name = "backend-coder"
sha256 = "a1b2c3..."
synced_at = "2026-06-24T09:00:00Z"

[[artifacts]]
kind = "skill"
name = "api-review"
sha256 = "d4e5f6..."
synced_at = "2026-06-24T09:00:00Z"

5.2 Team tier ​

Add a 4th tier to SkillRegistry.loadTier:

bundled  <  user  <  team  <  project

Precedence rationale: The team tier provides shared defaults that sit above personal user config but below project-specific overrides. This matches organizational mental models: "the team agreed on X, but this particular repo needs Y."

Implementation: Extend the loadTier signature:

ts
private loadTier(
  rootDir: string,
  tier: 'bundled' | 'user' | 'team' | 'project'
): void;

In reload():

ts
this.loadTier(BUNDLED_DIR, 'bundled');
this.loadTier(getUserDir(), 'user');
if (teamDir) this.loadTier(teamDir, 'team');   // new
this.loadTier(getProjectDir(this.cwd), 'project');

The team tier root is resolved from the local clone path (see §5.3).

5.3 Pointer + discovery ​

A code repo opts in to a team meta-repo by committing a pointer file:

<repo>/.fleet/team.toml
toml
[source]
repo = "git@github.com:acme/acme-fleet-meta.git"
ref = "main"                     # branch/tag/commit
path = "."                       # subdirectory within the meta-repo (default root)

[member]
name = "alice"                   # optional: identifies members/<name> branch to fetch/write
                                 # absent = read-only consumer of main (no personal branch)

[sync]
autoSync = true                  # pull on agents-fleet start
intervalMinutes = 0              # 0 = on-start only

Why .fleet/team.toml (recommended) over alternatives:

AlternativeTradeoff
Global ~/.fleet/teams.toml mapNot discoverable per-project; requires manual setup per-machine; doesn't travel with the repo.
Convention-based (<repo>-fleet-meta)Fragile; doesn't support custom names or non-GitHub hosts; can't scope to a subdirectory.
CLI flag only (--team-repo=...)Not persistent; burdens every invocation; not discoverable by teammates.
Git submodule of .fleet/Tightly coupled to git; submodule UX is notoriously poor; CI complexity.

The .fleet/team.toml approach is explicit, discoverable, and travels with the repository.

5.4 Sync model ​

Clone location ​

~/.fleet/teams/<sha256(repo_url)[:12]>/

A content-addressed directory avoids collisions when a user works across multiple teams.

Sync lifecycle ​

  1. On start: If autoSync = true, git pull --ff-only the local clone (or clone if absent). Failure is non-fatal (offline-tolerant); the last successfully cloned state is used.
  2. /team sync command: Manual trigger. Fetches + fast-forwards. Reports diff summary.
  3. Periodic (optional): If intervalMinutes > 0, a background timer re-syncs.

Writeback (opt-in) ​

  • /team push — stages local changes (e.g., a newly evolved skill) and commits to the member's own members/<name> branch (see §5.4a). Never auto-pushes to main.
  • Implementation: git push origin members/<name> — the member's branch is their scratch space; no PR is required for personal writeback.
  • /team push --promote (or /team promote <artifact>) — opens a PR from members/<name> → main via gh pr create (if gh CLI is available) or prints the push URL.
  • The coordinator may suggest /team push after a successful shadow promotion.

Conflict handling ​

  • Sync uses --ff-only. If the local clone has uncommitted changes (from /team push prep), sync stashes first.
  • If fast-forward fails (diverged history), the user is prompted to resolve manually or --force reset to remote.
  • Artifacts are file-granular; merge conflicts within a single .md file are expected to be rare (each artifact = one file).

5.4a Branching, per-member isolation & promotion ​

The meta-repo uses a per-member branch model (Model B) for isolation:

main                          ← promoted/team-blessed artifact set
members/alice                 ← Alice's personal/experimental artifacts
members/bob                   ← Bob's personal/experimental artifacts
...

Design principles ​

  1. main = the promoted/team-blessed artifact set. Crews, skills, roles, workflows, context, and insights that the team has reviewed and accepted. Stays lean regardless of headcount.

  2. Each member owns a branch members/<name> in the meta-repo, holding their personal/experimental artifacts, draft insights, and (opt-in) intel exports. A member may freely push to their own branch without review.

  3. Team-tier loading — a member consumes main as the team tier, and MAY layer their own members/<name> branch on top as the highest-precedence team source:

    bundled  <  user  <  team(main)  <  team(members/<name>)  <  project

    In practice the team tier is loaded in two passes: first from the main checkout, then from the member's branch checkout (overlay). Artifacts on the member's branch override same-named artifacts from main within the team tier, but the project tier still wins overall.

  4. The scaling guarantee: Sync fetches ONLY main + the member's own branch:

    bash
    git fetch origin main members/<name>

    A client never pulls sibling members' branches. At 40–50 members per squad (or 400 across squads in a federated topology — see §5.8), no local clone contains others' experimental artifacts; the main tree stays small. Git fetches only requested refs — this is what makes per-member branches cheaper than a per-member namespace directory on main (see §11d).

  5. Promotion = reviewed PR members/<name> → main. The quorum-before- promote gate (§7.3) provides the additional consensus requirement for evolved skills before they land on main. Workflow:

    Alice evolves a skill locally
      → /team push                        (commits to members/alice)
      → /team promote api-review          (opens PR members/alice → main)
      → team reviews + quorum gate passes
      → merge → main now carries the skill
  6. Lifecycle / hygiene:

    • Stale members/<name> branches can be archived or pruned after a member leaves the team (admin action).
    • Protected-branch rules on main enforce PR review; member branches are unprotected by default.
    • fleet-meta.toml [team].members advisory list doubles as the known- branch registry for tooling (e.g., /team status --all or CI clean-up).

5.5 Trust ​

A team meta-repo is remote code (prompt/instruction content with tool-call side effects via workflows). It must be treated with the same caution as project-tier artifacts.

Trust model: TOFU (Trust On First Use) ​

  1. First time a .fleet/team.toml points to a meta-repo URL, the user is prompted interactively:
    ⚠ Team meta-repo "git@github.com:acme/acme-fleet-meta.git" is not yet trusted.
    Trust this repository? [y/N]
  2. On acceptance, the repo URL + its current commit sha are stored in ~/.fleet/trusted-teams.toml.
  3. Subsequent starts skip the prompt if the URL matches.
  4. A --trust-team flag bypasses the prompt (for CI/automation).

Override / revocation ​

  • --no-trust-team disables the team tier entirely (like --no-trust-project-skills).
  • AGENTS_FLEET_TRUST_TEAM=0 env var equivalent.
  • Removing the URL from ~/.fleet/trusted-teams.toml revokes trust.

Security rationale ​

  • The meta-repo is a private git repo (org-scoped); access control is delegated to the git host.
  • TOFU mirrors SSH host-key acceptance — appropriate for private repos within an org boundary.
  • Artifacts loaded from the team tier pass through the same ArtifactValidator as project-tier artifacts.

5.6 Extended bundles ​

Generalize BundleManifestV2 beyond crew-rooted to support standalone artifacts:

ts
interface BundleManifestV3 {
  bundleVersion: '3';
  exportedAt: string;
  // 'crew' field becomes optional (standalone bundles have no root crew)
  crew?: string;
  artifacts: Array<{
    kind: 'role' | 'skill' | 'workflow' | 'crew' | 'context';  // +context
    name: string;
    sha256: string;
    allowOverride?: boolean;
  }>;
}

Changes:

  • crew is optional — standalone skills/roles/context can be bundled.
  • 'context' added as a valid artifact kind.
  • Backward-compatible: v2 bundles continue to import; v3 import requires agents-fleet >= the implementing version.
  • context/ artifacts carry insights, plans, and shared memory.

5.7 New CLI surface ​

CommandDescription
/team initCreate a new fleet-meta.toml scaffold in a fresh meta-repo.
/team syncPull latest from main + own members/<name> branch.
/team pushStage + commit local changes to own members/<name> branch.
/team push --promotePush to members/<name> AND open a PR → main.
/team promote <artifact>Open a promotion PR for a specific artifact (members/<name> → main).
/team statusShow sync state, drift, last sync time, trust status.
FlagScopeDescription
--trust-teamCLISkip TOFU prompt; trust the meta-repo.
--no-trust-teamCLIDisable team tier entirely.
--team-ref <ref>CLIOverride the ref from team.toml (e.g., test a branch).
AGENTS_FLEET_TRUST_TEAMEnv0 = disable team tier; 1 = trust without prompt.

5.8 Federation / sub-team meta-repos (org scale) ​

For large organizations (hundreds of engineers), a single flat meta-repo becomes unwieldy. The recommended topology is federated tier-chaining:

┌─────────────────────────────────────────────────────┐
│  org-fleet-meta  (org tier — policies, shared roles)│
│  main                                               │
└──────────────────┬──────────────────────────────────┘
                   │  tier-chains (squad toml points up)
        ┌──────────┼──────────────┐
        ▼          ▼              ▼
┌────────────┐ ┌────────────┐ ┌────────────┐
│ squad-A    │ │ squad-B    │ │ squad-C    │
│ meta-repo  │ │ meta-repo  │ │ meta-repo  │
│ main       │ │ main       │ │ main       │
│ members/*  │ │ members/*  │ │ members/*  │
└────────────┘ └────────────┘ └────────────┘
   ~10-50          ~10-50          ~10-50

Tier-chain precedence ​

bundled  <  user  <  org(main)  <  squad(main)  <  squad(members/<name>)  <  project

The org tier provides company-wide policies and base roles; squad meta-repos refine and extend for their domain. Each clone stays scoped to ONE squad (plus the org layer) — never the full org graph.

Mechanism ​

fleet-meta.toml in a squad meta-repo adds an optional upstream pointer:

toml
[upstream]
repo = "git@github.com:acme/org-fleet-meta.git"
ref = "main"

The sync engine resolves tier-chains recursively (depth-bounded; max 3 levels recommended). Each level's main is fetched independently — no transitive member-branch pulls.

Two-stage promotion ​

  1. Member → squad: PR from members/<name> → squad main (standard promotion — see §5.4a).
  2. Squad → org: PR from squad main → org main. Typically reserved for mature artifacts that have proven value at the squad level (higher review bar; org-admin approval).

When to federate ​

Team sizeRecommended topology
1–15Single meta-repo, per-member branches
15–50Single squad meta-repo; consider org tier for shared policies
50+ (multi-squad)Federated: one org meta-repo + per-squad meta-repos

6. Proposed Design — Part B: Intel Aggregation (phased, privacy-gated) ​

6.1 Redaction-at-rest (PREREQUISITE) ​

Problem: Raw prompts, paths, branch names, commit shas, and error messages are stored unredacted in prompt_history, agent_runs, steering_insights, and errors (src/intel/SchemaManager.ts:150-172, 325-331). This is by design for local /learn fidelity — but it blocks any cross-machine sharing.

Recommended approach: keep raw locally + redacted EXPORT path.

┌─────────────────────────────────────────────────┐
│  Local Intel DB (raw, unredacted)               │
│  ─ Full fidelity for /learn, /insights, etc.    │
└───────────────────┬─────────────────────────────┘
                    │  /team export-intel (explicit)
                    ▼
┌─────────────────────────────────────────────────┐
│  Redacted Export (JSONL files)                   │
│  ─ PiiRedactor applied to ALL text fields       │
│  ─ Written to meta-repo `intel/` or local file  │
│  ─ Machine/author/team provenance attached      │
└─────────────────────────────────────────────────┘

Alternative (rejected): Redact in place. This would degrade /learn fidelity and break getRecentTaskForSkill's replay accuracy. The dual-path approach preserves local utility while ensuring only safe data leaves the machine.

6.2 Provenance columns ​

Add to exported records (not to the local schema — exports are standalone):

ts
interface ExportProvenance {
  machineId: string;      // sha256(hostname + os.userInfo().username)[:12]
  authorId?: string;      // optional git author email (hashed)
  teamId: string;         // from fleet-meta.toml [meta].name
  exportedAt: number;     // epoch ms
  fleetVersion: string;   // agents-fleet version
}

Provenance enables merge/dedup across team members' exports.

6.3 Metrics-layer file export ​

Export SAFE (non-PII) fields as append-only JSONL:

jsonl
{"type":"agent_run","agentType":"coder","durationMs":45000,"tokensIn":1200,"tokensOut":8500,"toolUseCount":12,"status":"completed","skillName":"api-review","model":"claude-sonnet-4-20250514","dagShape":"linear","provenance":{"machineId":"a1b2c3","teamId":"acme"}}
{"type":"session_summary","taskCount":5,"completedCount":4,"failedCount":1,"totalTokensIn":15000,"totalTokensOut":42000,"provenance":{"machineId":"a1b2c3","teamId":"acme"}}

Fields deliberately excluded: prompt, task_subject, error_message, cwd, worktree_path, branch_name, commit_sha.

Written to meta-repo/intel/metrics/<machineId>-<date>.jsonl.

For teams that want to share redacted prompts/outcomes (e.g., for training):

  • Requires explicit AGENTS_FLEET_INTEL_SHARE_CONTENT=1 env flag.
  • Requires meta-repo owner consent in fleet-meta.toml:
    toml
    [intel.sharing]
    contentLayer = true      # repo owner permits content sharing
  • Both gates must be true; either alone is insufficient.
  • All text passes through PiiRedactor before export.

6.5 Merge / aggregation tool ​

/team merge-intel — folds multiple members' JSONL exports into aggregate views:

  • Dedup by provenance + timestamp.
  • Aggregate metrics (team-wide success rates, token budgets, model performance).
  • Produce a intel/aggregate/team-summary.json committed to the meta-repo.

7. Proposed Design — Part C: Team Shadow & Training (phased) ​

7.1 Shared task suites ​

Distribute experiment task suites via the meta-repo:

meta-repo/intel/suites/
├── core-coding.suite.json
├── api-review.suite.json
└── ...

Format: matches ExperimentStore's TaskSuiteRecord + CaseRecord schema (src/intel/experiment/). On sync, suites are imported into the local ExperimentStore (idempotent by suite_id).

7.2 Pooled eval results ​

After a local experiment run, results can be exported:

meta-repo/intel/eval-results/<machineId>-<runId>.jsonl

Each line is a TrialRecord with provenance. Team members can view aggregate pass rates across the team for a given variant.

7.3 Quorum-before-promote gate ​

A new configuration in fleet-meta.toml:

toml
[shadow]
quorumThreshold = 3            # N members must confirm improvement
quorumWindow = "7d"            # within this time window
autoPromoteOnQuorum = false    # advisory only; manual `/promote` still required

Flow:

  1. Member A's shadow evolution produces a candidate and wins locally.
  2. A exports the result to intel/eval-results/.
  3. Members B and C run the same suite against the candidate (shared via intel/suites/) and export results.
  4. /team promote-check <shadowId> reports quorum status.
  5. If autoPromoteOnQuorum = true AND quorum met, the promotion PR is auto-opened via /team push.

7.4 Training-data export ​

On top of the redacted content layer (§6.4):

  • /team export-training generates JSONL in OpenAI fine-tune format:
    jsonl
    {"messages":[{"role":"system","content":"..."},{"role":"user","content":"<redacted prompt>"},{"role":"assistant","content":"<redacted output>"}]}
  • Only from labeled_outcomes rows with outcome = 'success' and dod_all_passed = 1.
  • Written to meta-repo/intel/training/<date>.jsonl.

8. Security & Privacy ​

Threat model ​

#ThreatMitigationResidual risk
T1Malicious artifact in meta-repo (prompt injection via role/skill)TOFU trust gate + private repo + ArtifactValidator + same sandboxing as project tierInsider threat within the org; mitigated by PR review on meta-repo
T2IP leakage via shared intelMetrics-only by default; content-layer requires double opt-in + PiiRedactorRedaction is heuristic; novel PII patterns may leak. Recommend: human spot-check of first export.
T3Secret exposure in exported JSONLPiiRedactor strips env-var patterns, tokens, keys, pathsSame as T2 — heuristic. Recommend: pre-commit hook secret scanner on meta-repo.
T4Cross-org data leakageMeta-repo is org-private; team.toml URL is per-repo; trust is TOFU-scoped to URLMisconfigured meta-repo visibility. Recommend: GitHub repo visibility audit.
T5Stale/diverged artifacts causing failuresfleet.lock sha256 verification; /team status drift detectionManual resolution required on divergence.
T6Denial-of-service via large meta-repoShallow clone (--depth 1); size limit check on syncUnusually large history (blob packing); recommend periodic GC.
T7Unauthorized writeback/team push creates a PR, not a direct push; branch protection on meta-repoRequires meta-repo branch protection rules configured by admin.

Recommendations ​

  • Meta-repo MUST be private with org-level access control.
  • Enable secret scanning and branch protection on the meta-repo.
  • First content-layer export should be human-reviewed before merge.
  • Periodically audit ~/.fleet/trusted-teams.toml for stale entries.

9. Phased Rollout ​

Increment 1: Team Tier + Pointer + Sync + Per-Member Branches + Extended Bundles ​

Scope:

  • fleet-meta.toml manifest + fleet.lock format.
  • .fleet/team.toml pointer + discovery (including [member].name).
  • SkillRegistry 4th tier ('team'), with two-pass loading (main + member branch overlay).
  • Per-member branch model: members/<name> isolation, selective fetch, writeback to own branch, promotion PR to main (§5.4a).
  • Sync engine (clone/pull on start, /team sync — fetches main + own branch only).
  • Trust gate (TOFU + --trust-team + env var).
  • Extended bundles (v3 manifest, standalone artifacts, context/ kind).
  • /team init, /team sync, /team push, /team promote, /team status commands.
  • No privacy risk — only fleet artifacts (markdown), no intel.

New files/modules:

  • src/teams/TeamSyncEngine.ts — clone, pull, drift detection, per-member branch fetch.
  • src/teams/TeamTrustGate.ts — TOFU + trust store.
  • src/teams/teamPointer.ts — parse .fleet/team.toml (incl. [member]).
  • src/commands/team.ts — /team command family.
  • Modify src/skills/SkillRegistry.ts — add 'team' tier with two-pass load.
  • src/skills/bundle.ts — BundleManifestV3 type.

Acceptance criteria:

  • [ ] SkillRegistry loads tiers: bundled < user < team(main) < team(members/name) < project.
  • [ ] Team tier is loaded from ~/.fleet/teams/<hash>/ clone of meta-repo URL.
  • [ ] .fleet/team.toml is parsed; missing/malformed = no team tier (warning).
  • [ ] [member].name determines which members/<name> branch is fetched.
  • [ ] Absent [member] = read-only consumer of main only (no branch fetch).
  • [ ] git fetch origin main members/<name> on sync — never fetches sibling branches.
  • [ ] git pull --ff-only on start; offline = use cached; first clone on fresh.
  • [ ] TOFU prompt on first use; stored in ~/.fleet/trusted-teams.toml.
  • [ ] --no-trust-team / AGENTS_FLEET_TRUST_TEAM=0 disables team tier.
  • [ ] /team sync manually triggers fetch + reports artifact diff.
  • [ ] /team push commits to members/<name> (no PR).
  • [ ] /team push --promote / /team promote <artifact> opens PR members/<name> → main.
  • [ ] /team status shows sync state, last sync, trust, drift count.
  • [ ] Extended bundle v3 imports standalone skills/roles/context.
  • [ ] Existing tests pass; new tests for tier ordering + trust gate + branch isolation.

Test plan:

  • Unit: TeamSyncEngine with mocked git commands (incl. per-member fetch).
  • Unit: TeamTrustGate TOFU flow.
  • Integration: SkillRegistry 5-pass tier ordering (team(main) + team(member) overrides user, project overrides all team).
  • Integration: bundle v3 import with context/ artifacts.
  • E2E: /team sync with a test git repo + member branch.
  • E2E: /team push + /team promote flow.

Increment 1.5: Federation / Tier-Chaining (org scale) ​

Scope:

  • fleet-meta.toml [upstream] pointer for squad → org tier-chaining (§5.8).
  • Recursive sync engine (depth-bounded, max 3 levels).
  • Org tier inserted into the load precedence: bundled < user < org(main) < squad(main) < squad(members/<name>) < project.
  • Two-stage promotion workflow (member → squad → org).

New files/modules:

  • src/teams/TeamSyncEngine.ts — upstream resolution + depth bound.
  • src/teams/teamPointer.ts — parse [upstream] in fleet-meta.toml.
  • src/commands/team.ts extensions — /team promote --to-org or equivalent.
  • Modify SkillRegistry — multi-level team tier loading.

Acceptance criteria:

  • [ ] [upstream] in fleet-meta.toml triggers org-tier fetch on sync.
  • [ ] Tier chain resolves recursively up to max depth 3.
  • [ ] Org tier artifacts are overrideable by squad tier.
  • [ ] /team promote --to-org opens PR from squad main → org main.
  • [ ] A client never clones the full org graph — only its own squad + org.

Test plan:

  • Unit: tier-chain resolution with mocked repos at 2 and 3 depth.
  • Integration: 3-tier load ordering (org < squad < project).
  • E2E: two-stage promotion PR flow.

Increment 2: Redaction-at-rest + Metrics Export + Provenance ​

Scope:

  • Redacted JSONL export path (/team export-intel).
  • Provenance attachment (machineId, teamId).
  • Metrics-layer export (safe fields only).
  • Write to meta-repo/intel/metrics/.

New files/modules:

  • src/intel/MetricsExporter.ts — safe-field JSONL writer.
  • src/intel/ExportProvenance.ts — provenance generation.
  • src/commands/team.ts extensions — /team export-intel.

Acceptance criteria:

  • [ ] /team export-intel produces JSONL with NO raw prompts/paths/secrets.
  • [ ] All text fields pass through PiiRedactor before export.
  • [ ] Provenance (machineId, teamId) is attached to every record.
  • [ ] Metrics JSONL is append-only in meta-repo/intel/metrics/.
  • [ ] fleet-meta.toml must have [intel.sharing] metricsLayer = true to enable export (consent gate).

Test plan:

  • Unit: MetricsExporter output contains no PII fields.
  • Unit: Provenance hashing is deterministic and non-reversible.
  • Integration: full export → verify JSONL schema + no raw content.

Increment 3: Merge + Shared Task Suites + Quorum Promotion ​

Scope:

  • /team merge-intel aggregation tool.
  • Shared task suites via meta-repo/intel/suites/.
  • Pooled eval-result export/import.
  • Quorum-before-promote advisory gate.
  • /team promote-check command.

New files/modules:

  • src/intel/IntelMerger.ts — dedup + aggregate.
  • src/teams/QuorumGate.ts — quorum threshold check.
  • src/commands/team.ts extensions — /team merge-intel, /team promote-check.
  • ExperimentStore extension — import shared suites on sync.

Acceptance criteria:

  • [ ] Shared suites sync from meta-repo into local ExperimentStore.
  • [ ] /team merge-intel deduplicates by provenance + timestamp.
  • [ ] Quorum gate correctly counts distinct machine confirmations.
  • [ ] /team promote-check reports pass/fail with member breakdown.
  • [ ] No promotion occurs without explicit user action (unless autoPromoteOnQuorum = true).

Test plan:

  • Unit: IntelMerger dedup logic with overlapping JSONL.
  • Unit: QuorumGate threshold math.
  • Integration: suite import on sync triggers ExperimentStore insert.

Increment 4: Opt-in Redacted Content + Training Export ​

Scope:

  • Content-layer opt-in (AGENTS_FLEET_INTEL_SHARE_CONTENT=1 + meta-repo consent).
  • Redacted prompt/outcome export from labeled_outcomes.
  • /team export-training in fine-tune JSONL format.
  • /team push flow for intel PRs.

New files/modules:

  • src/intel/TrainingExporter.ts — fine-tune JSONL writer.
  • src/teams/ContentConsentGate.ts — double opt-in check.
  • /team export-training command.

Acceptance criteria:

  • [ ] Content export requires BOTH env flag AND meta-repo [intel.sharing] contentLayer = true.
  • [ ] All exported text is redacted via PiiRedactor.
  • [ ] Training JSONL matches OpenAI fine-tune schema.
  • [ ] /team push opens a PR for intel contributions.

Test plan:

  • Unit: double-consent gate enforcement.
  • Unit: TrainingExporter output schema + redaction.
  • Integration: end-to-end export-training → verify no raw content.

10. Open Questions / Decisions ​

Q1: Discovery mechanism ​

Recommended (open for review): Explicit .fleet/team.toml committed in the code repo.

AlternativeTradeoff
Global ~/.fleet/teams.tomlNot discoverable per-project; doesn't travel.
Convention (<repo>-fleet-meta)Fragile; limits naming flexibility.
agency.toml extensionOverloads an existing config; coupling risk.

Q2: Sync direction ​

Recommended (decided): Read from main + own members/<name> branch; writeback targets the member's own branch (/team push). Promotion to main is via reviewed PR (/team promote). Never auto-push to main.

AlternativeTradeoff
Bidirectional auto-syncMerge conflicts; accidental IP sharing; complexity.
Read-only (no writeback)Simpler but blocks the team learning loop.
Direct push to main (no PR)Bypasses review; risky for shared config.
Ephemeral branches (fleet/<date>-<desc>)No persistent member workspace; no overlay in tier loading; extra branch churn.

Q3: Redaction-at-rest approach ​

Recommended (open for review): Keep raw locally for /learn fidelity; add a redacted EXPORT path. Only redacted data ever leaves the machine.

AlternativeTradeoff
Redact in place at write timeDegrades /learn + replay fidelity permanently.
Separate redacted table (materialized view)Storage overhead; sync complexity.
Encrypt at rest + decrypt on readDoesn't solve sharing (key management overhead).

Q4: Transport — git vs service ​

Recommended (open for review): Git meta-repo for v1. Service layer is a future increment when git's limitations bite (large JSONL, real-time sync, auth token management).

AlternativeTradeoff
Central REST service from day 1High build cost; deployment burden; latency.
S3/blob storageNo versioning; no diff; no PR workflow.
npm/registry packagesPackage-per-skill is heavyweight; no atomic multi-artifact.

Q5: First-build scope ​

Recommended (open for review): Ship Increment 1 first (team tier + pointer + sync + extended bundles). No privacy-sensitive data moves; value is immediate (shared config); validates the architecture before adding intel layers.

AlternativeTradeoff
Ship Inc 1+2 togetherLarger blast radius; redaction work delays config sharing.
Skip to Inc 3 (suites)Requires Inc 2 (provenance) as prereq; can't skip.

11. Alternatives Considered ​

11a. Git submodule / subtree of .fleet/ ​

Pros: Native git; no new tooling; always in sync with code repo. Cons: Submodule UX is notoriously poor (detached HEAD, nested clone, missed git submodule update). Subtree pollutes commit history. Both tightly couple fleet config versioning to code repo release cadence. Neither supports multi-repo consumption of the same config source cleanly.

11b. npm-published skill packages ​

Pros: Leverages existing package infrastructure; semver versioning built-in. Cons: Requires a build step per skill/role change. Package-per-artifact is extremely heavy for simple markdown files. No atomic multi-artifact publish. node_modules pollution. Not ergonomic for non-Node teams.

11c. Central registry service ​

Pros: Real-time sync; auth delegation; rich APIs (search, versioning, star/fork). Hosted by fleet platform. Cons: Requires service deployment + ops; introduces latency + availability dependency; overkill for v1 when git provides adequate transport. Recommended as a v2+ evolution once git-based sharing validates the demand.

11d. Per-member namespace directories on main (Model A — rejected) ​

An alternative isolation model where each member's experimental artifacts live in a namespace directory on main:

<team>-fleet-meta/
├── crews/             # team-blessed
├── skills/            # team-blessed
├── members/
│   ├── alice/
│   │   ├── skills/
│   │   └── roles/
│   ├── bob/
│   │   ├── skills/
│   │   └── roles/
│   └── ...
└── ...

Pros: Simple mental model; all artifacts visible in one tree; standard git merge workflow.

Cons (rejected for scale):

  • Every member clones ALL members' namespaces on sync — they all live on main. At 40–50 members per squad, this bloats every local clone with artifacts the member never uses.
  • Git shallow/sparse-checkout can partially mitigate, but adds fragile config and doesn't solve the fetch bandwidth problem (pack negotiation still transfers objects for the full main tree).
  • No isolation between members during experimentation — a bad artifact on main (even in a namespace dir) is immediately visible to all members on next sync.
  • Promotion is less clear (move from members/alice/skills/ to skills/?) vs. a PR-merge which is a first-class git operation.

Model B (per-member branches) avoids all of these: git fetch origin main members/<name> transfers only two refs; sibling branches are never fetched. See §5.4a.


12. Appendix ​

A. Schema sketches ​

.fleet/team.toml (code repo pointer) ​

toml
[source]
repo = "git@github.com:acme/acme-fleet-meta.git"
ref = "main"
path = "."

[member]
name = "alice"            # optional: own members/<name> branch

[sync]
autoSync = true
intervalMinutes = 0

fleet-meta.toml (meta-repo manifest) ​

toml
[meta]
name = "acme-backend-team"
version = "1"

[team]
description = "Backend squad fleet configuration"
members = ["alice", "bob"]

[sync]
defaultRef = "main"
autoSyncOnStart = true
syncIntervalMinutes = 0

[upstream]                               # optional: federation tier-chain (§5.8)
repo = "git@github.com:acme/org-fleet-meta.git"
ref = "main"

[intel.sharing]
metricsLayer = false
contentLayer = false

[shadow]
quorumThreshold = 3
quorumWindow = "7d"
autoPromoteOnQuorum = false

Team-tier load API ​

ts
// In SkillRegistry constructor opts:
interface SkillRegistryOpts {
  trustProjectGates?: boolean;
  trustProjectIntake?: boolean;
  trustProjectSkills?: boolean;
  trustTeam?: boolean;          // new
  teamDir?: string;             // new: resolved clone path (main checkout)
  teamMemberDir?: string;       // new: resolved clone path (members/<name> checkout)
}

// In reload():
reload(): void {
  // ...clear...
  this.loadTier(BUNDLED_DIR, 'bundled');
  this.loadTier(getUserDir(), 'user');
  if (this.trustTeam && this.teamDir) {
    this.loadTier(this.teamDir, 'team');            // main branch artifacts
    if (this.teamMemberDir) {
      this.loadTier(this.teamMemberDir, 'team');    // member branch overlay
    }
  }
  this.loadTier(getProjectDir(this.cwd), 'project');
  // ...gates, bundled crews...
}

New intel provenance columns (export-only, not in local schema) ​

ts
interface MetricsExportRecord {
  type: 'agent_run' | 'session_summary' | 'eval_run';
  provenance: ExportProvenance;
  // ... safe metric fields only
}

interface ExportProvenance {
  machineId: string;      // sha256(hostname + username)[:12]
  authorId?: string;      // sha256(git email)[:12]
  teamId: string;         // from fleet-meta.toml name
  exportedAt: number;
  fleetVersion: string;
}

B. Migration note for existing committed-.fleet/ repos ​

Teams that currently commit .fleet/ into their code repos can adopt the meta-repo pattern incrementally:

  1. Run /team init in the meta-repo to scaffold fleet-meta.toml.
  2. Copy crews/, skills/, roles/, workflows/ from <repo>/.fleet/ to the meta-repo.
  3. Add .fleet/team.toml to the code repo pointing to the meta-repo.
  4. Verify: agents-fleet loads artifacts from team tier.
  5. Remove duplicates from <repo>/.fleet/ (keep only repo-specific overrides).
  6. The project tier still works for repo-specific customization.

Backward compatibility: Repos without .fleet/team.toml are unaffected; the team tier is simply not loaded.


End of RFC.