patchwork-os 1.2.0-beta.2.canary.711 → 1.2.0-beta.2.canary.713

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.
@@ -41,6 +41,20 @@ export interface Roster {
41
41
  * decision, the first is the absence of one.
42
42
  */
43
43
  implicit: boolean;
44
+ /**
45
+ * True when a roster file EXISTS and could not be understood — unparseable,
46
+ * the wrong shape, or holding no entry that parses.
47
+ *
48
+ * This is the opposite of `implicit` and must never be confused with it. An
49
+ * absent file means nobody has made a membership decision here, and the
50
+ * one-person default is right. An unreadable file means a decision EXISTS
51
+ * and we cannot read it, so the safe answer is nobody — otherwise breaking
52
+ * the file is a way to become the owner.
53
+ *
54
+ * `members` is empty in this state, so `resolvePrincipal` yields `null` and
55
+ * `principalCan` grants nothing.
56
+ */
57
+ unreadable: boolean;
44
58
  /** Entries that failed to parse, by index, so the operator can be told. */
45
59
  dropped: number[];
46
60
  }
@@ -45,7 +45,21 @@ export function implicitOwner() {
45
45
  };
46
46
  }
47
47
  function implicitRoster() {
48
- return { members: [implicitOwner()], implicit: true, dropped: [] };
48
+ return {
49
+ members: [implicitOwner()],
50
+ implicit: true,
51
+ unreadable: false,
52
+ dropped: [],
53
+ };
54
+ }
55
+ /**
56
+ * A roster file we found and could not read. Deliberately NOT `implicitRoster`:
57
+ * see `Roster.unreadable`. `dropped` carries the entry indices when we got far
58
+ * enough to have any, so the operator can be told what was lost rather than
59
+ * only that something was.
60
+ */
61
+ function unreadableRoster(dropped = []) {
62
+ return { members: [], implicit: false, unreadable: true, dropped };
49
63
  }
50
64
  /** Default location: `~/.patchwork/members.json`, honouring `PATCHWORK_HOME`. */
51
65
  export function defaultRosterPath() {
@@ -70,12 +84,15 @@ export function defaultRosterPath() {
70
84
  export function loadRoster(path = defaultRosterPath()) {
71
85
  if (!existsSync(path))
72
86
  return implicitRoster();
87
+ // Every `return` below this line is `unreadableRoster`, never
88
+ // `implicitRoster`. The file exists, so a membership decision was made here;
89
+ // failing to read it must not answer with an owner who can do everything.
73
90
  let parsed;
74
91
  try {
75
92
  parsed = JSON.parse(readFileSync(path, "utf8"));
76
93
  }
77
94
  catch {
78
- return implicitRoster();
95
+ return unreadableRoster();
79
96
  }
80
97
  const raw = Array.isArray(parsed)
81
98
  ? parsed
@@ -83,7 +100,7 @@ export function loadRoster(path = defaultRosterPath()) {
83
100
  ? parsed.members
84
101
  : null;
85
102
  if (!raw)
86
- return implicitRoster();
103
+ return unreadableRoster();
87
104
  const members = [];
88
105
  const dropped = [];
89
106
  const seen = new Set();
@@ -98,9 +115,12 @@ export function loadRoster(path = defaultRosterPath()) {
98
115
  seen.add(m.id);
99
116
  members.push(m);
100
117
  }
118
+ // A file whose every entry was dropped is unreadable, not one-person: the
119
+ // operator listed members and we understood none of them. `dropped` is
120
+ // carried through so the report says which.
101
121
  if (members.length === 0)
102
- return implicitRoster();
103
- return { members, implicit: false, dropped };
122
+ return unreadableRoster(dropped);
123
+ return { members, implicit: false, unreadable: false, dropped };
104
124
  }
105
125
  /**
106
126
  * One-line summary of a loaded roster, for the startup log.
@@ -114,6 +134,18 @@ export function describeRoster(roster) {
114
134
  if (roster.implicit) {
115
135
  return "no members.json — running as a single implicit owner";
116
136
  }
137
+ // Loud, and deliberately not phrased as a degraded-but-fine state. Without
138
+ // this branch the line below reports "roster loaded: 0 people", which reads
139
+ // like an empty workspace rather than an unreadable file — and this string is
140
+ // the startup log an operator actually sees.
141
+ if (roster.unreadable) {
142
+ const where = roster.dropped.length > 0
143
+ ? ` — every entry REJECTED at position ${roster.dropped.join(", ")}`
144
+ : "";
145
+ return (`members.json EXISTS but could not be read${where}. ` +
146
+ "Nobody is identified in this workspace until it is fixed; this is NOT " +
147
+ "the single-owner default, which applies only when the file is absent.");
148
+ }
117
149
  const humans = roster.members.filter((m) => m.kind === "human").length;
118
150
  const workers = roster.members.length - humans;
119
151
  const parts = [`${humans} ${humans === 1 ? "person" : "people"}`];
@@ -1 +1 @@
1
- {"version":3,"file":"roster.js","sourceRoot":"","sources":["../../src/identity/roster.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"roster.js","sourceRoot":"","sources":["../../src/identity/roster.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "patchwork-os",
3
- "version": "1.2.0-beta.2.canary.711",
3
+ "version": "1.2.0-beta.2.canary.713",
4
4
  "description": "Your personal AI runtime, local-first. Patchwork OS gives any AI model a consistent set of tools, YAML recipes, a delegation policy with approval queue, and a durable trace memory — all on your machine, all under your policy.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",