@agentshouse/kit 0.1.0-alpha.2 → 0.1.0-alpha.4

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/README.md CHANGED
@@ -10,7 +10,7 @@ On Linux `amd64` or `arm64` with a working Docker Engine, run the published,
10
10
  versioned bootstrap once:
11
11
 
12
12
  ```sh
13
- bash <(curl -fsSL https://github.com/agentshouse/kit/releases/download/v0.1.0-alpha.2/connect-linux.sh)
13
+ bash <(curl -fsSL https://github.com/agentshouse/kit/releases/download/v0.1.0-alpha.4/connect-linux.sh)
14
14
  ```
15
15
 
16
16
  The release asset pins one immutable multi-architecture image digest. It creates
@@ -1111,8 +1111,11 @@ It selects prefixes over the User root, materializes them into a named local
1111
1111
  directory, enumerates whole content and removals after the recorded positions,
1112
1112
  and submits a resolved exact-base change set the caller prepared. Kit does no
1113
1113
  local reconciliation. The mode shares no Working Copy manifest, never infers a
1114
- removal from a locally absent file, and writes authored mutations only for the
1115
- two Libraries and `ROOM.md`.
1114
+ removal from a locally absent file, and writes authored mutations only within
1115
+ House's declared write scopes: a selected Room's Library and, where granted,
1116
+ `ROOM.md`. `/private` selects the Private Room by its Room reference, records an independent Room
1117
+ position, and keeps its `agents/` cards and Room-specific private `AGENTS.md`
1118
+ beside `library/**`.
1116
1119
 
1117
1120
  ```sh
1118
1121
  kit sync bootstrap ./replica \
@@ -1179,7 +1182,7 @@ for a batch that reaches it.
1179
1182
 
1180
1183
  ## Attachments
1181
1184
 
1182
- Upload one local file as an attachment to a Room or to your private tree. Name
1185
+ Upload one local file as an attachment to a Room or to your Private Room. Name
1183
1186
  the place explicitly. Kit sends the descriptor and the selected bytes; it does
1184
1187
  not scan a directory, convert a URL, or attach sibling files, credentials, or
1185
1188
  absolute paths.
@@ -1583,7 +1586,7 @@ prepared model definitions survive a later content-mount refusal or unmount.
1583
1586
 
1584
1587
  The atomic text mount includes a report with pending transfer rows. Kit then
1585
1588
  uploads each downloaded file once as an attachment to the mount's Room or
1586
- private tree, independently retrieves and compares the saved bytes, and only
1589
+ Private Room, independently retrieves and compares the saved bytes, and only
1587
1590
  after that proof succeeds rewrites every link to it, in every referring
1588
1591
  document, to its attachment reference, such as `at_1x.q`. The reference is an
1589
1592
  identity House resolves, not an HTTP download URL. A link's query and fragment
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentshouse/kit",
3
- "version": "0.1.0-alpha.2",
3
+ "version": "0.1.0-alpha.4",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
package/src/contract.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { CLAUDE_PASTED_CODE, CODEX_DEVICE_CODE, GROK_DEVICE_CODE } from "./agent-logins.js";
2
2
 
3
- export const KIT_CONTRACT_VERSION = "2026-09-26-house-agent-kinds";
3
+ export const KIT_CONTRACT_VERSION = "2026-09-27-private-room-scope";
4
4
  export const KIT_CAPTURE_BATCH_MAX = 100;
5
5
  export const COMMAND_INPUT_MAX_BYTES = 4 * 1024;
6
6
  export const AUTHORIZATION_OUTPUT_MAX_BYTES = 4 * 1024;
@@ -288,7 +288,7 @@ export const KIT_DOOR_DISCOVER_PATH = "/kit/door/discover";
288
288
  export const KIT_DOOR_BOOTSTRAP_PATH = "/kit/door/bootstrap";
289
289
  export const KIT_DOOR_ENUMERATE_PATH = "/kit/door/enumerate";
290
290
  export const KIT_DOOR_BATCH_PATH = "/kit/door/batch";
291
- export const EXPLICIT_SYNC_VERSION = "explicit-sync/1";
291
+ export const EXPLICIT_SYNC_VERSION = "explicit-sync/2";
292
292
  export const KIT_DOOR_UNMOUNT_PATH = "/kit/door/unmount";
293
293
 
294
294
  export const MIGRATOR_CONTRACT = "kit-migrator/1";
package/src/mount.js CHANGED
@@ -107,10 +107,11 @@ function discoveryOf(value) {
107
107
 
108
108
  function authorityFor(discovery, target) {
109
109
  const found = discovery.authorities.find((entry) =>
110
- target.kind === "private" ? entry.kind === "private" : entry.room_handle === target.handle,
110
+ entry.kind === "room" && entry.room_handle === target.handle,
111
111
  );
112
112
  if (found === undefined) refuse("kit_mount_authority_unknown", target.root);
113
113
  if (
114
+ typeof found.room_ref !== "string" ||
114
115
  !Array.isArray(found.protected_paths) ||
115
116
  found.operations === null ||
116
117
  typeof found.operations !== "object" ||
@@ -119,8 +120,8 @@ function authorityFor(discovery, target) {
119
120
  refuse("kit_mount_rejected", "discover");
120
121
  }
121
122
  return {
122
- kind: found.kind,
123
- authority: found.kind === "private" ? "private" : found.room_ref,
123
+ kind: "room",
124
+ authority: found.room_ref,
124
125
  path: target.root,
125
126
  protected_paths: found.protected_paths,
126
127
  operations: found.operations,
package/src/sync-state.js CHANGED
@@ -26,6 +26,9 @@ function syncFile(directory, key, kind = "") {
26
26
  function recordedAuthority(authority) {
27
27
  const operations = authority?.operations;
28
28
  return (
29
+ authority?.kind === "room" &&
30
+ typeof authority.authority === "string" &&
31
+ typeof authority.path === "string" &&
29
32
  typeof authority?.log_epoch === "string" &&
30
33
  operations !== null &&
31
34
  typeof operations === "object" &&
@@ -43,6 +46,7 @@ export async function readReplicaState(directory, replica) {
43
46
  }
44
47
  const state = await readNote(syncFile(directory, replicaKey(canonical)), null);
45
48
  if (state === null) return null;
49
+ if (state.version !== EXPLICIT_SYNC_VERSION) return null;
46
50
  if (!Array.isArray(state.authorities) || !state.authorities.every(recordedAuthority)) return null;
47
51
  return state;
48
52
  }
package/src/sync.js CHANGED
@@ -105,9 +105,6 @@ async function bootstrapBundle(session, prefixes, signal) {
105
105
  }
106
106
 
107
107
  function matchedDiscovery(discovery, scope) {
108
- if (scope.manifest?.scope === "private") {
109
- return discovery.authorities.find((entry) => entry.kind === "private");
110
- }
111
108
  return discovery.authorities.find(
112
109
  (entry) => entry.kind === "room" && entry.room_ref === scope.manifest?.anchor,
113
110
  );
@@ -173,11 +170,17 @@ function operationsOf(value) {
173
170
  function authorityRecord(scope, discovery, files) {
174
171
  const found = matchedDiscovery(discovery, scope);
175
172
  const operations = found === undefined ? null : operationsOf(found.operations);
176
- if (found === undefined || !stringList(found.protected_paths) || operations === null) {
173
+ if (
174
+ scope.manifest?.scope !== "room" ||
175
+ typeof scope.manifest.anchor !== "string" ||
176
+ found === undefined ||
177
+ !stringList(found.protected_paths) ||
178
+ operations === null
179
+ ) {
177
180
  throw new KitRefusal("kit_bootstrap_rejected");
178
181
  }
179
182
  return {
180
- kind: scope.manifest.scope === "private" ? "private" : "room",
183
+ kind: "room",
181
184
  authority: scope.manifest.anchor,
182
185
  room_handle: scope.manifest.room_handle,
183
186
  path: scope.manifest.path,
@@ -192,9 +195,10 @@ function authorityRecord(scope, discovery, files) {
192
195
  async function materialize(options, discovery, bundle, signal, previous = null) {
193
196
  const authorities = [];
194
197
  for (const scope of bundle.scopes) {
198
+ const record = authorityRecord(scope, discovery, []);
195
199
  const held = previous?.authorities.find((entry) => entry.authority === scope.manifest?.anchor);
196
200
  const files = await replaceScope(options.replica, held, scope, signal);
197
- authorities.push(authorityRecord(scope, discovery, files));
201
+ authorities.push({ ...record, files });
198
202
  }
199
203
  const state = {
200
204
  version: EXPLICIT_SYNC_VERSION,
@@ -409,6 +413,7 @@ export async function bootstrap(options, dependencies = {}) {
409
413
  const canonical = await canonicalReplica(options.replica);
410
414
  const existing = await readReplicaState(options.directory, canonical);
411
415
  if (existing !== null) throw new KitRefusal("kit_sync_already_bootstrapped", canonical);
416
+ await clearPending(options.directory, canonical);
412
417
  return withSession(options, dependencies, async (session, signal) => {
413
418
  const discovery = discoveryOf(
414
419
  await door(session, KIT_DOOR_DISCOVER_PATH, { prefixes: options.prefixes }, signal),