@awebai/oats 0.29.2 → 0.29.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -45,7 +45,6 @@ import { assessCapturedSessionReadiness, querySelectedKernel } from "../lib/sess
45
45
  import { runCapturedNative } from "../lib/captured-native.mjs";
46
46
  import { CUSTODY_ATTACH_MIN, grantYamlCustodySocket, parseBindingJson } from "../lib/binding-wire.mjs";
47
47
  import { custodyPreflight } from "../lib/grant-custody.mjs";
48
- import { PERSONAL_ROOT_DEFERRED_WARNING, personalRootDeclared } from "../lib/personal-team.mjs";
49
48
  import { runtimeDeliveryFor, wakeRegistration } from "../lib/wake-receive.mjs";
50
49
 
51
50
  /** Run a command as ARGV — never a shell string. Team ids, aliases, instance
@@ -498,7 +497,7 @@ function globalGrantSpawn() {
498
497
  const teamWarnings = [];
499
498
  const unmappedPrimary = !team ? unmappedPrimaryRow() : undefined;
500
499
  if (!team) team = activeTeamAt(custody);
501
- if (unmappedPrimary && team) teamWarnings.push(`oats-aweb: team-unmapped — workspace label ${unmappedPrimary.label} is not mapped; using personal team ${team}`);
500
+ if (unmappedPrimary && team) teamWarnings.push(`oats-aweb: team-unmapped — workspace label ${unmappedPrimary.label} is not mapped; using the default team ${team}`);
502
501
  if (!team) fatal("identity.mode \"global\" requires settings.oats.aweb.team or an active team at the resident custody root before minting a grant");
503
502
  const grantHome = join(home, ".aweb-identity");
504
503
  if (existsSync(grantHome)) fatal(`${grantHome} already exists; refusing to overwrite an existing aweb session grant home`);
@@ -758,9 +757,9 @@ function validateJoinLabels(labels, { action = "join" } = {}) {
758
757
  const eligible = eligibleTeams();
759
758
  const byLabel = new Map(eligible.map((t) => [t.label, t]));
760
759
  for (const label of labels) {
761
- if (action === "leave" && label === "personal") {
762
- const error = new Error(`E_TEAM_PERSONAL: ${label} is the personal team and cannot be left`);
763
- error.code = "E_TEAM_PERSONAL";
760
+ if (action === "leave" && label === "default") {
761
+ const error = new Error(`E_TEAM_DEFAULT: ${label} is the workspace's default team and cannot be left`);
762
+ error.code = "E_TEAM_DEFAULT";
764
763
  throw error;
765
764
  }
766
765
  if (!LABEL_RE.test(label) || !byLabel.has(label)) {
@@ -801,14 +800,19 @@ function readCapabilityMeta() {
801
800
  if (process.env.OATS_META) { try { return withProviderTeams(JSON.parse(process.env.OATS_META || "{}")); } catch { return withProviderTeams({}); } }
802
801
  try { return withProviderTeams(JSON.parse(readFileSync(join(home, "instance.json"), "utf8")).capabilityMeta?.["oats.aweb"] || {}); } catch { return withProviderTeams({}); }
803
802
  }
803
+ function defaultTeamSource(meta = {}) {
804
+ const recorded = meta.defaultTeam?.source;
805
+ if (recorded === "setting" || recorded === "root") return recorded;
806
+ return payloadTeam().team ? "setting" : "root";
807
+ }
804
808
  function teamsDocument(meta = readCapabilityMeta()) {
805
809
  const teams = parseOatsTeams();
806
810
  const joined = joinedTeamsOf(meta);
807
811
  const joinedLabels = new Set(joined.map((j) => j.label));
808
812
  const primary = primaryTeamLabel();
809
- const personalTeam = meta.personal?.team || meta.team || meta.identity?.team || payloadTeam().team || null;
813
+ const defaultTeam = meta.defaultTeam?.team || meta.team || meta.identity?.team || payloadTeam().team || null;
810
814
  return {
811
- personal: { team: personalTeam, ...(meta.personal?.source ? { source: meta.personal.source } : {}) },
815
+ defaultTeam: { team: defaultTeam, source: defaultTeamSource(meta) },
812
816
  primary,
813
817
  eligible: teams.filter((t) => t.mapped && t.team).map((t) => ({ label: t.label, team: t.team, joined: joinedLabels.has(t.label) })),
814
818
  joined: joined.map((j) => ({ label: j.label, team: j.team, identityHome: j.identityHome, receive: j.receive || "poll", since: j.since })),
@@ -888,7 +892,7 @@ function parseHomeCommandArgs(argv = process.argv.slice(3)) {
888
892
  }
889
893
  function outputTeamsDocument(doc, json) {
890
894
  if (json) { console.log(JSON.stringify(doc)); return; }
891
- console.log(`personal: ${doc.personal.team || "unknown"}`);
895
+ console.log(`default team: ${doc.defaultTeam.team || "unknown"}`);
892
896
  for (const row of doc.eligible) console.log(`${row.joined ? "joined" : "eligible"}: ${row.label} (${row.team})`);
893
897
  for (const label of doc.unmapped) console.log(`unmapped: ${label}`);
894
898
  }
@@ -934,9 +938,7 @@ function runTeamsCommand(kind) {
934
938
 
935
939
  /** The primary identity's team and the root that mints it, exactly as 1.14.2:
936
940
  * the config's `team:` (id, then name) wins, else the root's active team.
937
- * Per-workspace personal-team enrollment is deferred to 1.16, so this makes no
938
- * `aw auth` or `aw team ensure` call and a declared roots.personal is ignored
939
- * with a warning. Exits through fatal() on refusal. */
941
+ * Exits through fatal() on refusal. */
940
942
  function resolvePrimaryTeam() {
941
943
  const warnings = [];
942
944
  const root = awebRoot();
@@ -945,7 +947,7 @@ function resolvePrimaryTeam() {
945
947
  const source = team ? "setting" : "root";
946
948
  const unmappedPrimary = !team ? unmappedPrimaryRow() : undefined;
947
949
  if (!team) team = JSON.parse(run(["aw", "team", "list", "--json"], root)).active_team;
948
- if (unmappedPrimary && team) warnings.push(`oats-aweb: team-unmapped — workspace label ${unmappedPrimary.label} is not mapped; using personal team ${team}`);
950
+ if (unmappedPrimary && team) warnings.push(`oats-aweb: team-unmapped — workspace label ${unmappedPrimary.label} is not mapped; using the default team ${team}`);
949
951
  if (!team) fatal(`cannot determine target team, so no identity could be minted — ${teamConfigRemedy()}, or activate a team at the aweb root`);
950
952
  // A bare team name (no namespace) resolves against the root's memberships.
951
953
  if (!team.includes(":")) {
@@ -955,7 +957,6 @@ function resolvePrimaryTeam() {
955
957
  else if (match.length > 1) fatal(`team name "${team}" is ambiguous at ${root}: ${match.join(", ")}, so no identity could be minted — ${teamConfigRemedy()}`);
956
958
  else fatal(`no membership matching team "${team}" at ${root}, so no identity could be minted — join or create it first (aweb-team-membership skill), or ${teamConfigRemedy()}`);
957
959
  }
958
- if (personalRootDeclared(settings)) warnings.push(`oats-aweb: personal-root-deferred — ${PERSONAL_ROOT_DEFERRED_WARNING}`);
959
960
  return { team, root, source, warnings };
960
961
  }
961
962
 
@@ -1110,19 +1111,19 @@ if (event === "launch") {
1110
1111
  const deliveryBrief = deliveryMode === "session"
1111
1112
  ? ` Notification delivery: external (AWEB_DELIVERY=session): the host wake broker (aw wake) is registered for this home and nudges you when mail or chat arrives; the native aweb channel is not running. If you have waited long with nothing arriving, check \`aw mail inbox\` and \`aw chat pending\` yourself at task boundaries.`
1112
1113
  : "";
1113
- let meta = { team: joined.team_id, alias, delivery: deliveryMode, personal: { team: joined.team_id, source: primary.source }, ...(process.env.OATS_RUNTIME ? { runtime: process.env.OATS_RUNTIME } : {}), identity: identityMeta({ mode: "local", alias, team: joined.team_id }) };
1114
+ let meta = { team: joined.team_id, alias, delivery: deliveryMode, defaultTeam: { team: joined.team_id, source: primary.source }, ...(process.env.OATS_RUNTIME ? { runtime: process.env.OATS_RUNTIME } : {}), identity: identityMeta({ mode: "local", alias, team: joined.team_id }) };
1114
1115
  const joinFloorProblem = joinRows.length ? joinedTeamsAwFloorProblem() : undefined;
1115
1116
  if (joinFloorProblem) warnings.push(`oats-aweb: ${joinFloorProblem}`);
1116
1117
  else for (const row of joinRows) { const result = mintJoinedTeam(row, meta); meta = result.meta; spawnMeta = meta; writeProviderTeamsState(meta); if (result.warning) warnings.push(`oats-aweb: ${result.warning}`); }
1117
1118
  if (joinedTeamsOf(meta).length) { const synced = syncWakeReceive(meta); meta = synced.meta; for (const w of synced.warnings) warnings.push(`oats-aweb: ${w}`); }
1118
1119
  writeProviderTeamsState(meta);
1119
- const personalBrief = meta.personal.source === "setting" ? "the team this deployment configured for you" : "your personal team (the messaging root's active team)";
1120
+ const defaultTeamBrief = meta.defaultTeam.source === "setting" ? "the team this deployment configured for you" : "the workspace's default team (the messaging root's active team)";
1120
1121
  const joinedNow = joinedTeamsOf(meta);
1121
1122
  const joinedBrief = joinedNow.length ? ` Joined teams: ${joinedNow.map((j) => `${j.label} (${j.team}, receive ${j.receive}, send with \`aw --identity-home ${j.identityHome} mail|chat ...\`)`).join("; ")}.` : "";
1122
1123
  out({
1123
1124
  meta,
1124
1125
  env,
1125
- brief: `Comms: you have an aweb identity — alias "${alias}" on team ${joined.team_id}, ${personalBrief}.${mismatch}${deliveryBrief}${joinedBrief} Load the oats-aweb skill before messaging: \`oats aweb teams --json\` shows your teams, \`oats aweb roster\` who you can reach. Coordination stays in your deployment's task layer.`,
1126
+ brief: `Comms: you have an aweb identity — alias "${alias}" on team ${joined.team_id}, ${defaultTeamBrief}.${mismatch}${deliveryBrief}${joinedBrief} Load the oats-aweb skill before messaging: \`oats aweb teams --json\` shows your teams, \`oats aweb roster\` who you can reach. Coordination stays in your deployment's task layer.`,
1126
1127
  ...(launch ? { launch } : {}),
1127
1128
  ...(joined.team_id !== team ? { warning: `oats-aweb: team mismatch — joined ${joined.team_id}, expected ${team}` } : warnings.length ? { warning: warnings.join(" | ") } : channelWarning ? { warning: channelWarning } : {}),
1128
1129
  });
@@ -1206,7 +1207,7 @@ if (event === "launch") {
1206
1207
  // alias = instance name, so the team's member roster lists live instances
1207
1208
  // wherever they run (plus human members). Local liveness comes from
1208
1209
  // `oats status` in the deployment; this is the network view.
1209
- // Default: this instance's personal team, listed from the root that minted
1210
+ // Default: this instance's default team, listed from the root that minted
1210
1211
  // it. `--label <label>` lists an eligible (joined or not) workspace team from
1211
1212
  // the host root that holds it.
1212
1213
  const argv = process.argv.slice(3);
@@ -1220,7 +1221,7 @@ if (event === "launch") {
1220
1221
  team = row.team; root = awebRootForTeam(team);
1221
1222
  if (!root) { console.error(`oats aweb roster: ${awebRootProblem(rootSettingCandidate(team))}, so the roster of ${label} cannot be read from this host`); process.exit(1); }
1222
1223
  } else {
1223
- team = meta.personal?.team || meta.identity?.team || meta.team || process.env.OATS_TEAM_ID;
1224
+ team = meta.defaultTeam?.team || meta.identity?.team || meta.team || process.env.OATS_TEAM_ID;
1224
1225
  root = awebRoot();
1225
1226
  if (!root) { console.error(`oats aweb roster: ${awebRootProblem(rootSettingCandidate())}`); process.exit(1); }
1226
1227
  if (!team) team = JSON.parse(run(["aw", "team", "list", "--json"], root)).active_team;
@@ -1,9 +1,9 @@
1
1
  ## Messaging: aweb
2
2
 
3
3
  Your messaging layer is **aweb**. Your identity's alias is your instance name,
4
- and it lives in the personal team of the person you work for (the `Comms:`
5
- line of your TASK.md names it). Wider workspace teams are joined explicitly,
6
- each with its own identity home.
4
+ and it lives in the workspace's default team (the `Comms:` line of your TASK.md
5
+ names it). Wider workspace teams are joined explicitly, each with its own
6
+ identity home.
7
7
 
8
8
  **Load the `oats-aweb` skill before your first `aw mail`/`aw chat` of a session,
9
9
  whenever an aweb wake or channel event arrives, and whenever messaging or a
@@ -14,7 +14,7 @@ memory; if a flag looks wrong run `aw <command> --help`.
14
14
  Quick crib (run from your instance home, never from `./work`):
15
15
 
16
16
  ```bash
17
- oats aweb teams --json # personal, eligible, joined teams
17
+ oats aweb teams --json # defaultTeam, eligible, joined teams
18
18
  oats aweb roster # who you can reach
19
19
  aw mail inbox # UNREAD mail only (--show-all: history)
20
20
  aw mail send --to <alias> --subject "..." --body-file <f> # recipient needs --to
@@ -4,7 +4,6 @@ import { isAbsolute, join, resolve } from 'node:path';
4
4
  import { TextDecoder } from 'node:util';
5
5
  import { assessCapturedSessionReadiness } from './session-readiness.mjs';
6
6
  import { custodyPreflight } from './grant-custody.mjs';
7
- import { PERSONAL_ROOT_DEFERRED_WARNING, personalRootDeclared } from './personal-team.mjs';
8
7
  import { joinedReceiveModes } from './wake-receive.mjs';
9
8
  import {
10
9
  MESSAGING_CONTRACT,
@@ -220,9 +219,8 @@ function readinessDetails(settings,{deployment,env=process.env}={}) {
220
219
  const initialTeam=typeof settings.team==='string' && settings.team.trim()?settings.team.trim():undefined;
221
220
  const candidate=rootCandidate(settings,initialTeam,{deployment,env}),team=teamFromSettings(settings,candidate,{env}),problems=[],warnings=[];
222
221
  if(!candidate.root || !isAbsolute(candidate.root) || !existsSync(join(resolve(candidate.root),'.aw'))) problems.push({code:'needs-configuration',message:`no messaging root at ${candidate.root?resolve(candidate.root):process.cwd()}: run oats aweb setup there or set ${candidate.key}`});
223
- const unmapped=unmappedPrimary(env);if(unmapped&&team)warnings.push({code:'team-unmapped',message:`workspace label ${unmapped.label} is not mapped; using personal team ${team}`});
222
+ const unmapped=unmappedPrimary(env);if(unmapped&&team)warnings.push({code:'team-unmapped',message:`workspace label ${unmapped.label} is not mapped; using the default team ${team}`});
224
223
  if(!team) problems.push({code:'needs-configuration',message:'no team: set settings.oats.aweb.team or keep an active team at the aweb root'});
225
- if(personalRootDeclared(settings)) warnings.push({code:'personal-root-deferred',message:PERSONAL_ROOT_DEFERRED_WARNING});
226
224
  return {team,candidate,warnings,result:checkProblems(problems) || {status:'ready',problems:[]}};
227
225
  }
228
226
  function readinessFromSettings(settings,options) {return readinessDetails(settings,options).result;}
@@ -30,7 +30,7 @@ export function wakeRegistration({home, primaryIdentityHome, delivery, runtime,
30
30
  if (!rt || !joined.length) return null;
31
31
  const receive = joined.map((j) => ({identity_home: j.identityHome, label: j.label, event_classes: JOINED_EVENT_CLASSES}));
32
32
  const doc = rt === 'external-session'
33
- ? {home, delivery: 'session', runtime_delivery: rt, identity_home: primaryIdentityHome, receive_identities: [{identity_home: primaryIdentityHome, label: 'personal', controls: true}, ...receive]}
33
+ ? {home, delivery: 'session', runtime_delivery: rt, identity_home: primaryIdentityHome, receive_identities: [{identity_home: primaryIdentityHome, label: 'default', controls: true}, ...receive]}
34
34
  : {home, delivery: rt, runtime_delivery: rt, primary_identity_home: primaryIdentityHome, receive_identities: receive};
35
35
  if (backend) doc.backend = backend;
36
36
  return doc;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "capability": "oats.aweb",
3
3
  "command": "aweb",
4
- "version": "1.15.0",
4
+ "version": "1.16.0",
5
5
  "compatibility": {
6
6
  "oats": ">=0.26.0"
7
7
  },
@@ -142,7 +142,7 @@
142
142
  "description": "channel: the native aweb channel packages wake the instance (default). session: delivery is external (AWEB_DELIVERY=session), no channel flag; the host wake broker registers the instance once it exists."
143
143
  },
144
144
  "team": {
145
- "description": "Target aweb team id for the primary personal identity lifecycle. In workspace v2 spawns this payload value wins over OATS_TEAM_ID; if both are set and differ the hook warns and uses this setting. Unset means the aweb root's active team."
145
+ "description": "Target aweb team id for the primary identity lifecycle. In workspace v2 spawns this payload value wins over OATS_TEAM_ID; if both are set and differ the hook warns and uses this setting. Unset means the aweb root's active team."
146
146
  },
147
147
  "root": {
148
148
  "hostOnly": true,
@@ -150,7 +150,7 @@
150
150
  },
151
151
  "roots": {
152
152
  "hostOnly": true,
153
- "description": "Host-owned map of aweb team id to absolute directory whose .aw is that team's minting root, for deployments that mint into several teams. Put this only in oats-local.yaml settings.oats.aweb.roots. The key \"personal\" is reserved for per-workspace personal-team enrollment (oats.aweb 1.16); 1.15 ignores it with a readiness warning."
153
+ "description": "Host-owned map of aweb team id to absolute directory whose .aw is that team's minting root, for deployments that mint into several teams. Put this only in oats-local.yaml settings.oats.aweb.roots. Keys are team ids only."
154
154
  },
155
155
  "identity": {
156
156
  "default": {
@@ -16,7 +16,7 @@ Vendored trees:
16
16
  - `aweb-identity/`
17
17
 
18
18
  Not vendored: `oats-aweb/` is this package's own OATS playbook (identity,
19
- personal and joined teams, roster, delivery and wakes, etiquette,
19
+ default and joined teams, roster, delivery and wakes, etiquette,
20
20
  troubleshooting). Every `aw` invocation it and the vendored skills cite is
21
21
  checked against a real published aw by `test/oats-aweb-1-15.test.mjs`.
22
22
 
@@ -23,12 +23,12 @@ retire cleanup, readiness, and Desktop operations consistent.
23
23
  Use the provider commands from the instance home (or with `--home <path>`):
24
24
 
25
25
  ```bash
26
- oats aweb teams --json # personal, eligible, joined, unmapped
26
+ oats aweb teams --json # defaultTeam, eligible, joined, unmapped
27
27
  oats aweb join --labels <label>[,<label>] # join eligible workspace labels
28
28
  oats aweb leave --labels <label>[,<label>] # leave joined wider-team labels
29
29
  ```
30
30
 
31
- - The personal team cannot be left; attempting it is `E_TEAM_PERSONAL`.
31
+ - The workspace's default team cannot be left; attempting it with label `default` is `E_TEAM_DEFAULT`.
32
32
  - A label that is not eligible for this soul/workspace is `E_TEAM_NOT_ELIGIBLE`.
33
33
  - Joined wider teams use a local identity home such as
34
34
  `<home>/.aweb-identity-<label>`. Joined teams require aw >= 1.36.12. The
@@ -62,15 +62,15 @@ aw id cert show
62
62
 
63
63
  Interpret common states:
64
64
 
65
- - `teams.personal.team` is the primary identity's team, wired to the harness:
66
- the aweb root's active team (`personal.source: root`) or a deployment-pinned
67
- team (`setting`). A team per workspace arrives in oats.aweb 1.16.
65
+ - `teams.defaultTeam.team` is the primary identity's team, wired to the harness:
66
+ the aweb root's active team (`defaultTeam.source: root`) or a deployment-pinned
67
+ team (`setting`).
68
68
  - `eligible[]` are labels this soul/workspace may explicitly join; the primary
69
69
  label may appear here and is joinable/leavable like any other wider team.
70
70
  - `joined[]` are provider-created wider-team memberships; each has an
71
71
  `identityHome`, `since`, and `receive` (`native` or `poll`).
72
72
  - `unmapped[]` labels are present on the soul but not mapped by the workspace.
73
- An unmapped primary falls back to the personal/root active team with a
73
+ An unmapped primary falls back to the default/root active team with a
74
74
  `team-unmapped` warning; it is not a spawn blocker.
75
75
  - `teams-unverified` on launch means the kernel supplied recorded/unknown team
76
76
  data, so the provider kept memberships instead of leaving anything.
@@ -81,9 +81,9 @@ Interpret common states:
81
81
  `default:oats.aweb.ai`).
82
82
  - **Team certificate**: a signed membership statement for an identity; stored in
83
83
  `.aw/team-certs/` for native identities.
84
- - **Personal team**: the default team for the instance's primary identity: the
85
- aweb root's active team, or `settings.oats.aweb.team` when the deployment
86
- pins one. Per-workspace personal-team enrollment arrives in oats.aweb 1.16.
84
+ - **Default team**: the workspace default team for the instance's primary identity:
85
+ the aweb root's active team, or `settings.oats.aweb.team` when the deployment
86
+ pins one.
87
87
  - **Joined team**: an explicit wider team joined through `oats aweb join`, with a
88
88
  separate local identity home.
89
89
 
@@ -13,7 +13,7 @@ These layers can combine in multiple ways. Do not assume one from another. The c
13
13
 
14
14
  Fully Hosted means aweb operates namespace and team authority for hosted domains such as `*.aweb.ai`. It can mint hosted team certificates and provide simple onboarding. This is the simple default for most users.
15
15
 
16
- Hosted OAuth/MCP flows provision custodial addressed/global identities, personal team membership, and harness credentials before a local CLI workspace exists. Team API-key CLI bootstrap is different: it creates a local self-custodial CLI workspace in a hosted team. In OAuth/MCP flows, use CLI checks for diagnosis only when a local workspace is actually involved; do not force BYOT setup.
16
+ Hosted OAuth/MCP flows provision custodial addressed/global identities, default team membership, and harness credentials before a local CLI workspace exists. Team API-key CLI bootstrap is different: it creates a local self-custodial CLI workspace in a hosted team. In OAuth/MCP flows, use CLI checks for diagnosis only when a local workspace is actually involved; do not force BYOT setup.
17
17
 
18
18
  ## BYOT
19
19
 
@@ -23,16 +23,16 @@ joined team, put `--identity-home <identityHome>` before the subcommand.
23
23
  | Fact | Where to read it |
24
24
  |---|---|
25
25
  | Your alias | your instance name; the `Comms:` line of `TASK.md`; `aw whoami` |
26
- | Your personal team | `oats aweb teams --json` → `personal.team` (`personal.source`) |
26
+ | Your default team | `oats aweb teams --json` → `defaultTeam.team` (`defaultTeam.source`) |
27
27
  | Teams you may join | `oats aweb teams --json` → `eligible[]` |
28
28
  | Teams you have joined | `oats aweb teams --json` → `joined[]` (each with `identityHome`, `receive`) |
29
29
  | How mail reaches you | the `Comms:` line of `TASK.md` (see section 4) |
30
30
 
31
- - **Personal team.** Your primary identity lives in the personal team of the
32
- person you work for: the aweb root's active team (`personal.source: root`),
33
- or the team the deployment pinned (`source: setting`). Everyone this
34
- deployment spawns into that team is there with you. (A separate team per
35
- workspace arrives in oats.aweb 1.16.)
31
+ - **Default team.** Your primary identity lives in the workspace's default team:
32
+ the aweb root's active team (`defaultTeam.source: root`), or the team the
33
+ deployment pinned (`defaultTeam.source: setting`). `defaultTeam.source` is
34
+ always present and is only `root` or `setting`. Everyone this deployment
35
+ spawns into that team is there with you.
36
36
  - **Joined teams.** A wider team the workspace defines, joined explicitly. Each
37
37
  gives you a **separate identity** with the same alias in that team, kept
38
38
  under `<home>/.aweb-identity-<label>`. You act as that team only with
@@ -42,7 +42,7 @@ joined team, put `--identity-home <identityHome>` before the subcommand.
42
42
  ## 2. Find who to talk to
43
43
 
44
44
  ```bash
45
- oats aweb roster # your personal team's members (instances + humans), across machines
45
+ oats aweb roster # your default team's members (instances + humans), across machines
46
46
  oats aweb roster --label <label> # an eligible workspace team's members
47
47
  oats status # live OATS instances on this machine
48
48
  ```
@@ -52,7 +52,7 @@ oats status # live OATS instances on this machine
52
52
  - Outside your team use a full address, `namespace/alias` (`--to-address`), only
53
53
  when you were given one.
54
54
  - A name that is not on the roster of the team you send from will not resolve:
55
- pick the identity (personal or joined) whose team holds the recipient.
55
+ pick the identity (default-team or joined) whose team holds the recipient.
56
56
 
57
57
  ## 3. Send, reply, chat
58
58
 
@@ -126,7 +126,7 @@ mail (`--show-all`).
126
126
  ## 5. Teams: join and leave
127
127
 
128
128
  ```bash
129
- oats aweb teams --json # {personal, primary, eligible, joined, unmapped}
129
+ oats aweb teams --json # {defaultTeam, primary, eligible, joined, unmapped}
130
130
  oats aweb join --labels <label>[,<label>]
131
131
  oats aweb leave --labels <label>[,<label>]
132
132
  ```
@@ -134,7 +134,7 @@ oats aweb leave --labels <label>[,<label>]
134
134
  - Join only when your human, coordinator or task asks you to work with that
135
135
  team. Joining mints a new identity for you in that team.
136
136
  - You may join only `eligible[]` labels; anything else is `E_TEAM_NOT_ELIGIBLE`.
137
- - Your personal team cannot be left (`E_TEAM_PERSONAL`).
137
+ - The workspace's default team cannot be left (`E_TEAM_DEFAULT` when the label is `default`).
138
138
  - When the workspace stops mapping a team, your next session start leaves it.
139
139
  - Do not run native `aw team join|switch|leave|invite` for your identities; the
140
140
  provider keeps homes, broker registration and retire cleanup consistent.
@@ -165,7 +165,7 @@ Check your own state first:
165
165
  ```bash
166
166
  aw whoami # identity you act as here
167
167
  aw workspace status # connection of the primary identity
168
- oats aweb teams --json # personal/joined teams and receive modes
168
+ oats aweb teams --json # defaultTeam/joined teams and receive modes
169
169
  oats readiness --home "$PWD" --json # the provider's readiness answer for this home
170
170
  ```
171
171
 
@@ -173,8 +173,7 @@ oats readiness --home "$PWD" --json # the provider's readiness answer for this
173
173
 
174
174
  | Code | Meaning | Who fixes it |
175
175
  |---|---|---|
176
- | `personal-root-deferred` | the host set `settings.oats.aweb.roots.personal`; 1.15 ignores it (per-workspace enrollment arrives in 1.16) | nobody; the host may remove the setting |
177
- | `team-unmapped` | your soul's primary label is not mapped by the workspace; you are in the personal team | workspace owner, if a shared team was meant |
176
+ | `team-unmapped` | your soul's primary label is not mapped by the workspace; you are in the default team | workspace owner, if a shared team was meant |
178
177
  | `joined-team-receive` | a joined team receives live through the broker (informational) | nobody |
179
178
  | `joined-team-poll-only` | a joined team does not wake you; the message says why | poll that team at task boundaries; human may start the wake daemon |
180
179
  | `wake-daemon-not-running` / `-outdated` / `-version-unknown` | host wake broker is down or older than 1.36.5 | human: upgrade aw, restart the host wake daemon |
@@ -185,7 +184,7 @@ oats readiness --home "$PWD" --json # the provider's readiness answer for this
185
184
 
186
185
  - `E_TEAM_NOT_ELIGIBLE` — the label is not one of your eligible teams; the
187
186
  message lists them. Check the spelling against `oats aweb teams --json`.
188
- - `E_TEAM_PERSONAL` — the personal team cannot be left.
187
+ - `E_TEAM_DEFAULT` — the workspace's default team cannot be left.
189
188
  - `E_TEAM_GLOBAL_MODE` — this home acts as a resident identity through a
190
189
  session grant; joined teams need local identities. Report it.
191
190
  - `E_TEAM_AW_FLOOR` — the host `aw` is too old: joined teams need aw >= 1.36.12.
@@ -216,13 +216,12 @@ team: [engineering, reviewers]
216
216
 
217
217
  - `OATS_TEAM_LABEL` is the primary label. The merged messaging payload takes
218
218
  **no** label's `byTeam` entry, the primary's included (teams amendment K), so
219
- `OATS_TEAM_ID` (the payload's `team`) is the personal team a host, soul or
220
- spawn set; empty means the provider's default.
219
+ `OATS_TEAM_ID` (the payload's `team`) is the default team a host, soul or spawn set; empty means the provider's default.
221
220
  - Every label is an **eligible team**: the kernel hands the messaging provider
222
221
  `teams`, one `{ label, team, mapped, payload }` per label in order. `payload`
223
222
  is `workspace.messaging` ⊕ `byTeam[<label>]` when the workspace maps the
224
223
  label (`team` is then its team id), else the base alone with `mapped: false`
225
- and `team: null`. A soul with no label gets `[]` (personal only).
224
+ and `team: null`. A soul with no label gets `[]` (the workspace's default team only).
226
225
  - `teams` travels **beside** a provider's settings, never inside them:
227
226
  `OATS_TEAMS` (the JSON), `OATS_TEAM_LABELS` (comma-joined) and
228
227
  `OATS_TEAMS_SOURCE` in the environment of every hook, home command and
@@ -518,7 +517,7 @@ passed as arguments; no shell is involved.
518
517
  - `OATS_CLI_BIN`;
519
518
  - `OATS_WORKSPACE` (the deployment);
520
519
  - the team variables `OATS_TEAM_ID` (the messaging payload's `team`: the
521
- personal team if one is set; empty = the provider's default),
520
+ workspace's default team if one is set; empty = the provider's default),
522
521
  `OATS_TEAM_SCOPE`, `OATS_TEAM_LABEL`, `OATS_TEAM_NAME`,
523
522
  `OATS_TEAM_LABELS`, `OATS_TEAMS`, `OATS_TEAMS_SOURCE`, `OATS_WORKSPACE_NAME` and
524
523
  `OATS_WORKSPACE_KEY`;
@@ -1,5 +1,7 @@
1
1
  # Desktop Phase F — the Desktop is built FOR workspace model v2
2
2
 
3
+ > **Vocabulary (2026-09-26):** there is no "personal team". Read it below as **the workspace's default team**. See the AMENDMENT at the top of [the teams contract](2026-09-25-teams-contract.md). This document is a record and keeps its original wording.
4
+
3
5
  **Status**: boundary for the Desktop engineer, issued 2026-09-24 by the lead under
4
6
  the human's direction: *"the desktop should not just adapt to the new version,
5
7
  it should be natively built for it."* Supersedes the Phase 3 parity plan's
@@ -1,5 +1,7 @@
1
1
  # Phase D — the OATS project runs on the architecture it offers (plan)
2
2
 
3
+ > **Vocabulary (2026-09-26):** there is no "personal team". Read it below as **the workspace's default team**. See the AMENDMENT at the top of [the teams contract](2026-09-25-teams-contract.md). This document is a record and keeps its original wording.
4
+
3
5
  **Status**: plan, 2026-09-24, lead. Decisions 18–22 of the workspace model, the
4
6
  five-soul roster and its 2026-09-24 amendment, the human's sequencing
5
7
  ("knowledge centralisation first"; "do not retire live souls until their
@@ -7,6 +7,31 @@ This document is the kernel half; the provider half (oats.aweb) is the
7
7
  messaging lane's. Co-lead review (9a18a381): agreed, with three additions,
8
8
  folded in below.
9
9
 
10
+ ## AMENDMENT 2026-09-26 (Juan, a total blocker): there is no "personal team"
11
+
12
+ There is **no "personal team" concept**, in aweb or in OATS. **A workspace has its
13
+ DEFAULT TEAM** (the team for the workspace key in its owner's namespace);
14
+ agents can join other teams. Nothing is "personal". Everywhere below, read
15
+ "personal team" as **"the workspace's default team"** (short: "default team").
16
+ The rename is applied everywhere, with no compatibility aliases:
17
+
18
+ - **Prose:** docs, skills, injects, READMEs, release notes (from 0.29.3 on), the
19
+ knowledge base. Past release notes and append-only logs stay as history.
20
+ - **Wire names (the oats.aweb 1.16.0 release; the co-lead's lane):**
21
+ - the teams operation's JSON field `personal` → `defaultTeam` (`{team, source}`);
22
+ - `E_TEAM_PERSONAL` → `E_TEAM_DEFAULT` (leaving the workspace's default team);
23
+ - the broker receive label `personal` → `default`;
24
+ - `settings.oats.aweb.roots.personal` is removed (enrollment is 1.16+ and uses
25
+ the enrolled-root model);
26
+ - readiness codes/messages lose "personal".
27
+ - **aweb** renames its `personal-workspace` endpoints, auth scope, CLI help and
28
+ flags, and binding file likewise (aweb's lane).
29
+ - **The kernel** carries no wire name with "personal" (only prose/comments,
30
+ renamed). The Desktop reads `defaultTeam`.
31
+
32
+ The model below is otherwise unchanged: the default team only, by default;
33
+ joining is explicit; only the soul's labels that the workspace maps.
34
+
10
35
  ## The model (human, 2026-09-25)
11
36
 
12
37
  - **Default: the personal team only.** Every instance is in its person's
@@ -143,11 +168,18 @@ folded in below.
143
168
  7. **Explicit join, spawn choice, Desktop.**
144
169
  - The join/leave/list verbs are the provider's (oats.aweb 1.14.0), run
145
170
  inside a home or with `--home <abs>`, all idempotent, all with `--json`:
146
- - `oats aweb teams` answers
147
- `{ personal: {team}, primary, eligible: [{label, team, joined}], joined: [{label, team, since, identityHome, receive}], unmapped: [label], at }`, where `receive` is `native` or `poll`;
171
+ - `oats aweb teams` answers (oats.aweb ≥1.16.0 names; see the AMENDMENT at the top)
172
+ `{ defaultTeam: {team, source}, primary, eligible: [{label, team, joined}], joined: [{label, team, since, identityHome, receive}], unmapped: [label], at }`, where `receive` is `native` or `poll`, and `source` is always `setting` (the team a setting named) or `root` (the messaging root's active team);
148
173
  - `oats aweb join <label>[,<label>]` and
149
- `oats aweb leave <label>[,<label>]` answer the same document. The
150
- personal team can't be left (`E_TEAM_PERSONAL`).
174
+ `oats aweb leave <label>[,<label>]` answer the same document **plus**
175
+ `actions: [{action: "join"|"leave", label, released?, receipt?}]`,
176
+ one row per label acted on, in order (since oats.aweb 1.15.0; added
177
+ here 2026-09-26 after the Desktop's real-provider capture found it).
178
+ `released` is the provider's word for what a leave did (e.g.
179
+ `released`); `receipt` is opaque provider evidence (alias release),
180
+ for logs, never shown as UI. A consumer accepts `actions` on
181
+ join/leave answers only, and repaints from the document itself.
182
+ The workspace's default team can't be left (`E_TEAM_DEFAULT`).
151
183
  - The same verbs are declared as home-context operations
152
184
  `messaging:teams|join|leave`, so the Desktop uses `oats operation run`
153
185
  and needs no new kernel surface.
@@ -90,7 +90,7 @@ An unconfirmed member contributes **nothing**: its souls and capabilities are in
90
90
  - A soul has one team or several (the first is its **primary**). A repo can set a default team for its souls.
91
91
  - A team label can **add default capabilities** for its souls (e.g. every `engineering` soul gets the release tooling).
92
92
  - A team label **never** restricts, gates or changes trust. It's organisation, plus optional defaults.
93
- - For **messaging**, each label a soul carries is a team it's *eligible* to join. By default an instance is only in its person's **personal team**, and joining others is an explicit choice, at spawn or later.
93
+ - For **messaging**, each label a soul carries is a team it's *eligible* to join. By default an instance is only in the workspace's **default team**, and joining others is an explicit choice, at spawn or later.
94
94
 
95
95
  ---
96
96
 
@@ -136,7 +136,7 @@ Plus one **default capability** almost every soul has: **`oats.core`**, which te
136
136
  ### 5.2 Messaging, specifically
137
137
 
138
138
  - Each instance gets a messaging **identity** (its address).
139
- - By default it's in the person's **personal team**. It can **join** other eligible teams (from its labels) at spawn or later, and **leave** them. The personal team can't be left.
139
+ - By default it's in the workspace's **default team**. It can **join** other eligible teams (from its labels) at spawn or later, and **leave** them. The default team can't be left.
140
140
  - Joined teams currently **check mail between tasks**; live delivery for joined teams is **(planned)**.
141
141
  - A stopped agent can be **woken** by a message.
142
142
 
@@ -196,7 +196,7 @@ When the workspace moves on (a member pushes, a package version is bumped), exis
196
196
  2. **Who are my agents?** Souls (what roles exist, grouped by team/repo) and instances (what's running, their hierarchy, their state).
197
197
  3. **What is this agent made of, and why?** Its composition, with each capability's source and reason (workspace/team/soul), its core capabilities, harness and work mode.
198
198
  4. **Where does it work?** Its work mode, branch, and repo; its Git state and pull requests.
199
- 5. **Who can it talk to?** Its messaging identity, its personal team, eligible teams, joined teams.
199
+ 5. **Who can it talk to?** Its messaging identity, the workspace's default team, eligible teams, joined teams.
200
200
  6. **What does it know?** Its knowledge nodes (owned/read). **(planned)** A live browser of them.
201
201
  7. **Is anything wrong?** Unconfirmed members, missing clones, team conflicts, drift, readiness problems, each with the plain cause and the fix.
202
202
 
@@ -231,7 +231,7 @@ When the workspace moves on (a member pushes, a package version is bumped), exis
231
231
  - **Official catalog**: the reviewed list of official packages and versions.
232
232
  - **Lock**: the exact commit + fingerprint of each package, per deployment.
233
233
  - **Team (label)**: an organising label; supplies defaults and eligible messaging teams.
234
- - **Personal team**: the messaging team every instance is in by default.
234
+ - **Default team**: the workspace's messaging team, which every instance is in by default.
235
235
  - **Harness**: what runs the agent session (Claude, Codex, Pi).
236
236
  - **Work mode**: where an instance works (worktree, checkout, attached, directory, workspace).
237
237
  - **Drift**: an instance built from an older state than the workspace's current one.
@@ -69,7 +69,7 @@ this policy does not invent new catalog or manifest fields.
69
69
  `oats.aweb`, `oats.authoring`, `oats.jira`, `oats.linear`, `oats.dev`,
70
70
  `oats.knowledge-theory`, `oats.core` and `oats.setup`. `oats.okf-harvest` and
71
71
  `oats.okf-maintenance` select the `oats.okf` package (4.0.0).
72
- - **`oats.framework` 1.3.0** is listed at tag `oats-framework/v1.3.0` in
72
+ - **`oats.framework` 1.3.1** is listed at tag `oats-framework/v1.3.1` in
73
73
  `awebai/oats`, payload root `oats-package`. The `oats.core`, `oats.setup` and
74
74
  `oats.knowledge-theory` aliases select that distribution; package identity is
75
75
  distinct from capability identity. Core supplies operation/soul guidance;
package/docs/packages.md CHANGED
@@ -74,9 +74,9 @@ members:
74
74
  - git:github.com/acme/agents
75
75
  - git:github.com/acme/platform
76
76
  packages:
77
- oats.framework: v1.3.0
77
+ oats.framework: v1.3.1
78
78
  oats.okf: v4.0.0
79
- oats.aweb: v1.15.0
79
+ oats.aweb: v1.16.0
80
80
  teams:
81
81
  global: { description: Org-wide }
82
82
  engineering: { description: Platform }
@@ -344,8 +344,8 @@ A soul that names one of the package's capabilities with
344
344
  }
345
345
  ```
346
346
 
347
- `ref` carries the tag convention: a workspace's `oats.framework: v1.3.0`
348
- resolves to tag `oats-framework/v1.3.0`. Resolving through the catalog never
347
+ `ref` carries the tag convention: a workspace's `oats.framework: v1.3.1`
348
+ resolves to tag `oats-framework/v1.3.1`. Resolving through the catalog never
349
349
  advances a lock by itself — `oats sync` does, and
350
350
  says so.
351
351
 
@@ -0,0 +1,53 @@
1
+ # OATS 0.29.3
2
+
3
+ ## Changed
4
+
5
+ - **There is no "personal team"; a workspace has its default team.** The
6
+ vocabulary follows the teams contract's amendment of 2026-09-26: a workspace
7
+ has its **default team** (the team for the workspace key in its owner's
8
+ namespace), and agents may join other teams. The model is unchanged:
9
+ - an instance is in the workspace's default team only, by default;
10
+ - joining an eligible team is an explicit act;
11
+ - `OATS_TEAMS` is `[]` for a soul with no label.
12
+
13
+ The kernel's docs, comments and the `unmapped-team-label` warning use the
14
+ new words. The warning now reads "… fall back to the workspace's default team
15
+ for it". The oats.framework skills (oats.core 2.1.1, oats.setup 2.1.2,
16
+ oats.framework 1.3.1) teach the same model. The kernel carries no wire name
17
+ with "personal", and there are no compatibility aliases.
18
+ - **The messaging provider uses the same words** (oats.aweb 1.16.0, below).
19
+
20
+ ## oats.aweb 1.16.0 (catalog pin and bundled mirror)
21
+
22
+ - **The catalog and this repo's workspace pin `oats.aweb` to `v1.16.0`, and
23
+ the bundled `capabilities/oats-aweb` is the tag's tree.** It renames the
24
+ provider's wire names to the default-team vocabulary:
25
+ - the teams operation's `personal` field becomes `defaultTeam`
26
+ (`{ team, source }`, where `source` is `setting` or `root`);
27
+ - `E_TEAM_PERSONAL` becomes `E_TEAM_DEFAULT`;
28
+ - the broker receive label `personal` becomes `default`;
29
+ - `settings.oats.aweb.roots.personal` is removed: `roots` keys are team ids
30
+ only, and the `personal-root-deferred` warning is gone.
31
+
32
+ There are no aliases: a reader of the old names must move to the new ones,
33
+ as the Desktop does in this release. A home spawned under 1.15 still resolves
34
+ its default team from its recorded team. Per-workspace default-team
35
+ enrollment is still deferred.
36
+
37
+ ## oats.framework 1.3.1 (catalog pin)
38
+
39
+ - **The catalog and this repo's workspace pin `oats.framework` to
40
+ `oats-framework/v1.3.1`.** Its only change is the default-team vocabulary
41
+ above, in `oats.core` 2.1.1 and `oats.setup` 2.1.2. A deployment on
42
+ `oats.framework: v1.3.0` keeps working, and moving the pin to `v1.3.1` picks
43
+ up the new skill text.
44
+
45
+ ## Desktop
46
+
47
+ - **"Default team" everywhere** (#252). The teams panel reads oats.aweb 1.16's
48
+ `defaultTeam` and says where the team comes from: the workspace or host
49
+ setting, or the messaging root's active team. The spawn dialog, the soul
50
+ inspector and the teams panel say "Default team" in place of "Personal".
51
+ A 1.15 `personal` document no longer decodes, so this Desktop needs the
52
+ oats.aweb 1.16.0 pin.
53
+ - The Desktop still accepts OATS CLIs `>=0.25.8 <0.30.0`.
@@ -59,7 +59,7 @@ members: # repo refs, NO @revision (E_WORKSPAC
59
59
  - git:github.com/acme/tools # a member that ALSO publishes a package (see below)
60
60
 
61
61
  packages: # the ONLY versioned things
62
- oats.framework: v1.3.0 # bare version → resolves through the official catalog
62
+ oats.framework: v1.3.1 # bare version → resolves through the official catalog
63
63
  oats.okf: v4.0.0
64
64
  acme.tools: git:github.com/acme/tools@v0.4.0 # outside the catalog → git:<repo>@<tag|OID>; still a package
65
65
 
@@ -399,7 +399,7 @@ keys, with `byTeam` stripped) ⊕ soul slot payload ⊕ `local.settings[cap]`
399
399
  **No `byTeam[<label>]` is merged into it, the primary's included** (teams
400
400
  amendment K): each label's `base ⊕ byTeam[label]` reaches the provider only as
401
401
  that label's entry in `OATS_TEAMS` (the preview's `teams`). So `settings.team`
402
- (and `OATS_TEAM_ID`) is the personal team if the host, the soul or the spawn
402
+ (and `OATS_TEAM_ID`) is the workspace's default team if the host, the soul or the spawn
403
403
  set one; empty means the provider's own default. The provider's own `binding` contract
404
404
  (`normalize → bind → check`) runs over the merged payload exactly as before.
405
405
  Two teams, two messaging identities, one workspace:
@@ -420,7 +420,7 @@ one. A label under `byTeam` that is not declared in `teams:` is
420
420
  act.** `spawn --preview` shows the merged `settings.<cap>` and the `teams`, so
421
421
  the delivery is verifiable, and `instance.json` records both. With oats.aweb
422
422
  1.13.1 (which reads `team` from its settings and ignores `OATS_TEAMS`) the
423
- primary identity therefore mints into the personal team: the `.aw` root's
423
+ primary identity therefore mints into the workspace's default team: the `.aw` root's
424
424
  active team, or the one the host set. What the payload does not change is
425
425
  **where the `.aw` root is found**: the hook still searches
426
426
  bounded candidates, first hit wins — the instance home, the Git repository
package/lib/core.mjs CHANGED
@@ -1485,17 +1485,17 @@ export function instanceSoulDir(home, meta = undefined) {
1485
1485
  /** The team facts a lifecycle hook receives (workspace model only, lead decision
1486
1486
  * c3-7): the team SCOPE is the deployment directory, the team ID is the messaging
1487
1487
  * slot's merged payload `team` (workspace base ⊕ soul ⊕ host ⊕ spawn; no byTeam entry
1488
- * is merged since teams amendment K): the personal team if one is set; empty = the
1488
+ * is merged since teams amendment K): the workspace's default team if one is set; empty = the
1489
1489
  * provider's default (for oats.aweb, the root's active team). The provider also gets
1490
1490
  * the soul's primary team LABEL and the workspace's name and canonical key, so it can
1491
- * derive a per-person, per-workspace personal team; each label's mapped payload is in
1491
+ * derive the workspace's default team; each label's mapped payload is in
1492
1492
  * OATS_TEAMS.
1493
1493
  * OATS_TEAM_NAME (the 0.25 `team:` block's name) is always empty, so an ambient
1494
1494
  * value never reaches a hook. Human decision 2026-09-24 (messaging default).
1495
1495
  *
1496
1496
  * Teams contract 2026-09-25 (decision 4): `resolved.teams` is the ELIGIBLE teams,
1497
1497
  * `[{ label, team, mapped, payload }]` in soul order. OATS_TEAM_LABELS is their
1498
- * labels comma-joined and OATS_TEAMS their JSON (`[]` = no label: personal only).
1498
+ * labels comma-joined and OATS_TEAMS their JSON (`[]` = no label: the workspace's default team only).
1499
1499
  * Both are empty when the teams are not known (a home spawned before 0.26.0 whose
1500
1500
  * workspace cannot be read now) — empty means "unknown", never "none".
1501
1501
  * OATS_TEAMS_SOURCE says where the list came from: `live` (the workspace read now,
package/lib/resolve.mjs CHANGED
@@ -346,7 +346,7 @@ export function teamLabelsOf(soulEntry) {
346
346
  * `{ label, team, mapped, payload }`. `payload` is workspace.messaging's base ⊕ byTeam[label] when the
347
347
  * workspace maps the label, else the base alone with `mapped: false`; `team` is the payload's team id
348
348
  * when mapped (null otherwise). Kernel-owned and delivered BESIDE a provider's settings, never inside
349
- * them; joining any of them is the messaging provider's explicit act. No label → [] ("personal only").
349
+ * them; joining any of them is the messaging provider's explicit act. No label → [] (the workspace's default team only).
350
350
  * Pure: resolveSoul validates every carried label's entry (reserved byTeam, hostOnly keys) first.
351
351
  */
352
352
  export function teamsOf(workspace, labels) {
@@ -731,7 +731,7 @@ export async function resolveSoul(discovery, soulEntry, { local = null, lock = n
731
731
  // Decision 23 as amended by K (teams contract, co-lead ruling): the provider's settings are
732
732
  // base ⊕ soul ⊕ host ⊕ spawn. No byTeam[<label>] is merged, the primary's included: each
733
733
  // label's base ⊕ byTeam[label] is delivered only in its `teams` entry (teamsOf → OATS_TEAMS),
734
- // so settings.team is the personal team a host, soul or spawn set. `byTeam` never reaches the
734
+ // so settings.team is the default team a host, soul or spawn set. `byTeam` never reaches the
735
735
  // provider, and the primary team's own payload may still not nest one.
736
736
  const { byTeam, ...base } = workspace.messaging;
737
737
  committed(base, "/messaging", { kind: "workspace", at: "oats-workspace.yaml#/messaging" });
package/lib/workspace.mjs CHANGED
@@ -753,8 +753,8 @@ export function workspaceWarnings(workspace, members, externalRows, packageSouls
753
753
 
754
754
  /** Teams contract decision 5: a soul label the workspace declares in `teams:` but does not map in
755
755
  * `messaging.byTeam` is a WARNING, not a problem — the label stays eligible-but-unmapped and the
756
- * messaging provider falls back to the personal team for it. (An undeclared label is E_TEAM_UNKNOWN.)
757
- * ONE warning per unmapped label, naming its souls (a personal-only workspace would otherwise print
756
+ * messaging provider falls back to the workspace's default team for it. (An undeclared label is E_TEAM_UNKNOWN.)
757
+ * ONE warning per unmapped label, naming its souls (a workspace on its default team alone would otherwise print
758
758
  * a line per soul): { code, label, souls, paths, message }, sorted by label. */
759
759
  const byCodepointOrder = (a, b) => (a < b ? -1 : a > b ? 1 : 0);
760
760
  function unmappedLabelWarnings(workspace, members, externalRows, teams) {
@@ -774,7 +774,7 @@ function unmappedLabelWarnings(workspace, members, externalRows, teams) {
774
774
  const order = names.map((n, i) => i).sort((x, y) => byCodepointOrder(names[x], names[y]) || byCodepointOrder(paths[x], paths[y]));
775
775
  const sorted = order.map((i) => names[i]);
776
776
  return { code: "unmapped-team-label", label, souls: sorted, paths: order.map((i) => paths[i]),
777
- message: `team ${show(label)} has no messaging.byTeam entry; its souls (${sorted.join(", ")}) fall back to the personal team for it` };
777
+ message: `team ${show(label)} has no messaging.byTeam entry; its souls (${sorted.join(", ")}) fall back to the workspace's default team for it` };
778
778
  });
779
779
  }
780
780
 
@@ -8,7 +8,7 @@
8
8
  },
9
9
  "oats.aweb": {
10
10
  "url": "https://github.com/awebai/oats-aweb.git",
11
- "ref": "v1.15.0",
11
+ "ref": "v1.16.0",
12
12
  "path": "oats-package"
13
13
  },
14
14
  "oats.jira": {
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "oats.framework": {
35
35
  "url": "https://github.com/awebai/oats.git",
36
- "ref": "oats-framework/v1.3.0",
36
+ "ref": "oats-framework/v1.3.1",
37
37
  "path": "oats-package"
38
38
  }
39
39
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@awebai/oats",
3
- "version": "0.29.2",
3
+ "version": "0.29.3",
4
4
  "description": "OATS (Open Agent Team Specification) — durable souls, disposable instances, targetable capability packages, and the runtime-neutral oats CLI/kernel.",
5
5
  "keywords": [
6
6
  "agents",
@@ -1,19 +0,0 @@
1
- // Per-workspace personal team: deferred to oats.aweb 1.16.
2
- //
3
- // A host's `aw auth` login is one file per OS user, and `aw auth status` does not
4
- // name the account, so enrolling a workspace's personal team from that login could
5
- // mint it (and every instance) into whichever account logged in last. 1.16 brings
6
- // a per-deployment credential location and an expected owner. Until then oats.aweb
7
- // makes no `aw auth` or `aw team ensure` call on any path, the primary team
8
- // resolves as in 1.14.2 (settings.team, else the root's active team), and a
9
- // declared settings.oats.aweb.roots.personal is ignored with a readiness warning.
10
-
11
- export const PERSONAL_ROOT_KEY = 'settings.oats.aweb.roots.personal';
12
- export const PERSONAL_ROOT_DEFERRED_WARNING = `${PERSONAL_ROOT_KEY} is ignored: per-workspace personal-team enrollment arrives in oats.aweb 1.16; the primary team is settings.oats.aweb.team, else the aweb root's active team`;
13
-
14
- const obj = (v) => v !== null && typeof v === 'object' && !Array.isArray(v);
15
-
16
- /** True when the host declared roots.personal (any value): 1.15 ignores it and says so. */
17
- export function personalRootDeclared(settings) {
18
- return obj(settings?.roots) && Object.hasOwn(settings.roots, 'personal');
19
- }