@team-agent/installer 0.5.41 → 0.5.42

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.
package/Cargo.lock CHANGED
@@ -575,7 +575,7 @@ dependencies = [
575
575
 
576
576
  [[package]]
577
577
  name = "team-agent"
578
- version = "0.5.41"
578
+ version = "0.5.42"
579
579
  dependencies = [
580
580
  "anyhow",
581
581
  "chrono",
package/Cargo.toml CHANGED
@@ -9,7 +9,7 @@ members = ["crates/team-agent", "crates/win-conpty-phase0", "crates/conpty-trans
9
9
 
10
10
  [workspace.package]
11
11
  edition = "2021"
12
- version = "0.5.41"
12
+ version = "0.5.42"
13
13
  license = "AGPL-3.0"
14
14
  rust-version = "1.95"
15
15
 
@@ -424,7 +424,25 @@ impl Coordinator {
424
424
  let saved = match &self.save_hook {
425
425
  Some(hook) => hook(&self.workspace, &state),
426
426
  None => {
427
- crate::state::projection::save_team_scoped_state(self.workspace.as_path(), &state)
427
+ // 0.5.42 S1b (s1b-writer-cluster-locate.md §3.2 /
428
+ // §4.4): the daemon tick's single terminal save
429
+ // routes through `StateRepository` with the
430
+ // `CoordinatorTick` intent. Repository dispatch is
431
+ // byte-identical to the old `save_team_scoped_state`
432
+ // helper (see `state/repository.rs:CoordinatorTick =>
433
+ // helper_write_team_scoped`), so persist/merge/lock/
434
+ // atomic-rename semantics and degraded-mapping stay
435
+ // unchanged. No cached repository, no extra load, no
436
+ // retry — the caller still owns the `Value` and
437
+ // failure still returns `TickReport{PersistenceDegraded}`
438
+ // via the `saved.is_err()` branch below.
439
+ let team_key = crate::state::projection::team_state_key(&state);
440
+ crate::state::repository::StateRepository::new(self.workspace.as_path()).save(
441
+ crate::state::repository::StateWriteIntent::CoordinatorTick {
442
+ team_key: team_key.as_str(),
443
+ },
444
+ &state,
445
+ )
428
446
  }
429
447
  };
430
448
  if saved.is_err() {
@@ -1750,7 +1750,25 @@ fn state_owner(state: &Value) -> Option<TeamOwner> {
1750
1750
  /// name for 0.5.x call-site stability. The B0 legacy snapshot is
1751
1751
  /// diagnostic-only via `lifecycle::save_team_runtime_snapshot`.
1752
1752
  pub fn write_lease_dual_state(workspace: &Path, state: &Value) -> Result<(), LeaderError> {
1753
- crate::state::persist::save_runtime_state(workspace, state)?;
1753
+ // 0.5.42 S1b (s1b-writer-cluster-locate.md §4.4): terminal root
1754
+ // save routes through `StateRepository` with the `ClaimLeader`
1755
+ // intent. Dispatch is byte-identical to the old
1756
+ // `save_runtime_state` helper (see
1757
+ // `state/repository.rs:ClaimLeader => helper_write_root`), so the
1758
+ // full lease writer cluster (attach_leader / attach_app_server /
1759
+ // attach_leader_to_state / claim_lease_no_incident_with_target /
1760
+ // rediscover) keeps its persist/merge/CAS/readback semantics.
1761
+ // Public signature/error mapping preserved for caller stability.
1762
+ // Repository does NOT compute owner_epoch, re-run convergence,
1763
+ // emit ownership events, or acquire a second lease lock — the
1764
+ // caller still owns all of that.
1765
+ let team_key = canonical_owner_write_key(state);
1766
+ crate::state::repository::StateRepository::new(workspace).save(
1767
+ crate::state::repository::StateWriteIntent::ClaimLeader {
1768
+ team_key: team_key.as_str(),
1769
+ },
1770
+ state,
1771
+ )?;
1754
1772
  Ok(())
1755
1773
  }
1756
1774
 
@@ -1838,7 +1856,16 @@ fn save_claim_team_scoped_state(workspace: &Path, state: &Value, target_key: &st
1838
1856
  writes_endpoint_convergence,
1839
1857
  );
1840
1858
  merged.insert("teams".to_string(), Value::Object(teams));
1841
- crate::state::persist::save_runtime_state(workspace, &Value::Object(merged))?;
1859
+ // 0.5.42 S1b (s1b-writer-cluster-locate.md §4.4): only the
1860
+ // terminal save routes through `StateRepository`; the entire
1861
+ // load/merge/compact block above stays in place — repository is a
1862
+ // writer facade, not a projection assembler.
1863
+ crate::state::repository::StateRepository::new(workspace).save(
1864
+ crate::state::repository::StateWriteIntent::ClaimLeader {
1865
+ team_key: target_key,
1866
+ },
1867
+ &Value::Object(merged),
1868
+ )?;
1842
1869
  Ok(())
1843
1870
  }
1844
1871
 
@@ -1,17 +1,32 @@
1
- //! S1a StateRepository facade.
1
+ //! StateRepository facade.
2
2
  //!
3
- //! Ref: `.team/artifacts/s1a-state-repository-design.md`
3
+ //! Ref:
4
+ //! - `.team/artifacts/s1a-state-repository-design.md` (skeleton)
5
+ //! - `.team/artifacts/s1b-writer-cluster-locate.md` (0.5.42 first
6
+ //! writer-cluster migration: `CoordinatorTick` + `ClaimLeader`)
4
7
  //!
5
- //! S1a is a **skeleton + governance** slice. `StateRepository` is a thin write
6
- //! facade that dispatches every write to the existing helper family without
7
- //! changing helper behavior, merge policy, or on-disk layout. The value it adds
8
- //! is that every write now carries a `StateWriteIntent`, so S1b can migrate
9
- //! writer clusters one semantic at a time.
8
+ //! `StateRepository` is a thin write facade that dispatches every write
9
+ //! to the existing helper family without changing helper behavior,
10
+ //! merge policy, or on-disk layout. The value it adds is that every
11
+ //! write now carries a `StateWriteIntent`, so writer clusters migrate
12
+ //! one semantic at a time.
10
13
  //!
11
- //! Non-goals in S1a (see design section 11): no schema rewrite, no path
12
- //! layout change, no writer migration, no helper deletion. Every existing
13
- //! caller keeps calling the raw helpers behind the S1a allowlist; only new
14
- //! direct callsites are governed.
14
+ //! 0.5.42 status: first real consumers are the daemon `Coordinator::
15
+ //! tick` production save (`CoordinatorTick`) and the lease/claim
16
+ //! writer cluster's two terminal saves (`ClaimLeader`)
17
+ //! `write_lease_dual_state` + `save_claim_team_scoped_state`.
18
+ //! Post-S1b, the direct-save allowlist drops from 73 to 70; the three
19
+ //! migrated sites have no allowlist row and every future direct save
20
+ //! must either enter through `StateRepository` or claim an explicit
21
+ //! new allowlist row (fail-closed).
22
+ //!
23
+ //! Non-goals kept from S1a (design §11) + reasserted by
24
+ //! s1b-writer-cluster-locate.md §7: no schema rewrite, no path layout
25
+ //! change, no helper deletion, no epoch computation in the repository,
26
+ //! no retry / reload / event emission, no reinterpretation of
27
+ //! `owner_epoch` / `topology_convergence` / readback proof — the
28
+ //! caller still owns the whole `Value`, and repository dispatches to
29
+ //! the same existing persist helper the direct edge used to hit.
15
30
 
16
31
  #![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
17
32
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@team-agent/installer",
3
- "version": "0.5.41",
3
+ "version": "0.5.42",
4
4
  "description": "npx installer for Team Agent",
5
5
  "keywords": [
6
6
  "codex",
@@ -20,9 +20,9 @@
20
20
  "team-agent-installer": "npm/install.mjs"
21
21
  },
22
22
  "optionalDependencies": {
23
- "@team-agent/cli-darwin-arm64": "0.5.41",
24
- "@team-agent/cli-darwin-x64": "0.5.41",
25
- "@team-agent/cli-linux-x64": "0.5.41"
23
+ "@team-agent/cli-darwin-arm64": "0.5.42",
24
+ "@team-agent/cli-darwin-x64": "0.5.42",
25
+ "@team-agent/cli-linux-x64": "0.5.42"
26
26
  },
27
27
  "scripts": {
28
28
  "postinstall": "node npm/bincheck.mjs",