@indigoai-us/hq-cli 5.125.0 → 5.127.0

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.
Files changed (108) hide show
  1. package/CHANGELOG.md +329 -0
  2. package/assets/bot-workers/setup/skills/joining-a-team.md +125 -0
  3. package/assets/bot-workers/setup/skills/your-business.md +270 -0
  4. package/assets/bot-workers/setup/worker.yaml +189 -58
  5. package/assets/lanes-hooks/hq-lanes-drain.json +15 -0
  6. package/assets/lanes-hooks/hq-lanes-drain.mjs +254 -0
  7. package/assets/lanes-hooks/hq-lanes-drain.sh +21 -0
  8. package/assets/lanes-reconcile/hq-lanes-reconcile.service +11 -0
  9. package/assets/lanes-reconcile/hq-lanes-reconcile.timer +12 -0
  10. package/dist/command-catalog.generated.d.ts +643 -6
  11. package/dist/command-catalog.generated.js +836 -6
  12. package/dist/command-registration-plan.d.ts +7 -0
  13. package/dist/command-registration-plan.js +11 -1
  14. package/dist/commands/agents.d.ts +12 -0
  15. package/dist/commands/agents.js +46 -2
  16. package/dist/commands/bot.d.ts +10 -0
  17. package/dist/commands/bot.js +6 -0
  18. package/dist/commands/lanes.d.ts +114 -0
  19. package/dist/commands/lanes.js +2969 -0
  20. package/dist/commands/mesh.js +287 -24
  21. package/dist/commands/onboard-create-identity.d.ts +26 -0
  22. package/dist/commands/onboard-create-identity.js +23 -0
  23. package/dist/commands/onboard.js +13 -4
  24. package/dist/lib/bot/progress.d.ts +6 -0
  25. package/dist/lib/bot/progress.js +16 -0
  26. package/dist/lib/bot/runtime/grok.d.ts +30 -7
  27. package/dist/lib/bot/runtime/grok.js +86 -8
  28. package/dist/lib/bot/runtime/index.js +15 -8
  29. package/dist/lib/bot/runtime/messages-stream.d.ts +12 -3
  30. package/dist/lib/bot/runtime/messages-stream.js +49 -3
  31. package/dist/lib/lanes/accounts.d.ts +103 -0
  32. package/dist/lib/lanes/accounts.js +318 -0
  33. package/dist/lib/lanes/compaction.d.ts +96 -0
  34. package/dist/lib/lanes/compaction.js +197 -0
  35. package/dist/lib/lanes/config.d.ts +71 -0
  36. package/dist/lib/lanes/config.js +408 -0
  37. package/dist/lib/lanes/delivery.d.ts +151 -0
  38. package/dist/lib/lanes/delivery.js +354 -0
  39. package/dist/lib/lanes/dropbox.d.ts +96 -0
  40. package/dist/lib/lanes/dropbox.js +408 -0
  41. package/dist/lib/lanes/effort.d.ts +50 -0
  42. package/dist/lib/lanes/effort.js +109 -0
  43. package/dist/lib/lanes/errors.d.ts +39 -0
  44. package/dist/lib/lanes/errors.js +72 -0
  45. package/dist/lib/lanes/hooks-install.d.ts +81 -0
  46. package/dist/lib/lanes/hooks-install.js +326 -0
  47. package/dist/lib/lanes/hq-root.d.ts +19 -0
  48. package/dist/lib/lanes/hq-root.js +28 -0
  49. package/dist/lib/lanes/index.d.ts +49 -0
  50. package/dist/lib/lanes/index.js +27 -0
  51. package/dist/lib/lanes/liveness.d.ts +95 -0
  52. package/dist/lib/lanes/liveness.js +332 -0
  53. package/dist/lib/lanes/machine-identity.d.ts +34 -0
  54. package/dist/lib/lanes/machine-identity.js +92 -0
  55. package/dist/lib/lanes/mesh-events.d.ts +109 -0
  56. package/dist/lib/lanes/mesh-events.js +275 -0
  57. package/dist/lib/lanes/outpost-dispatch.d.ts +65 -0
  58. package/dist/lib/lanes/outpost-dispatch.js +90 -0
  59. package/dist/lib/lanes/questions.d.ts +75 -0
  60. package/dist/lib/lanes/questions.js +243 -0
  61. package/dist/lib/lanes/quota.d.ts +95 -0
  62. package/dist/lib/lanes/quota.js +320 -0
  63. package/dist/lib/lanes/reconcile-install.d.ts +69 -0
  64. package/dist/lib/lanes/reconcile-install.js +221 -0
  65. package/dist/lib/lanes/reconcile.d.ts +102 -0
  66. package/dist/lib/lanes/reconcile.js +985 -0
  67. package/dist/lib/lanes/registry.d.ts +116 -0
  68. package/dist/lib/lanes/registry.js +521 -0
  69. package/dist/lib/lanes/spawn.d.ts +274 -0
  70. package/dist/lib/lanes/spawn.js +1363 -0
  71. package/dist/lib/lanes/store.d.ts +68 -0
  72. package/dist/lib/lanes/store.js +745 -0
  73. package/dist/lib/lanes/throttle.d.ts +89 -0
  74. package/dist/lib/lanes/throttle.js +297 -0
  75. package/dist/lib/lanes/types.d.ts +535 -0
  76. package/dist/lib/lanes/types.js +350 -0
  77. package/dist/lib/lanes/watcher-main.d.ts +9 -0
  78. package/dist/lib/lanes/watcher-main.js +22 -0
  79. package/dist/lib/lanes/watcher.d.ts +216 -0
  80. package/dist/lib/lanes/watcher.js +859 -0
  81. package/dist/lib/mesh/api.d.ts +71 -7
  82. package/dist/lib/mesh/api.js +167 -28
  83. package/dist/lib/mesh/live/backfill-held.d.ts +18 -7
  84. package/dist/lib/mesh/live/backfill-held.js +66 -21
  85. package/dist/lib/mesh/live/daemon/config.d.ts +27 -0
  86. package/dist/lib/mesh/live/daemon/config.js +75 -0
  87. package/dist/lib/mesh/live/daemon/index.d.ts +4 -3
  88. package/dist/lib/mesh/live/daemon/index.js +3 -3
  89. package/dist/lib/mesh/live/daemon/install.d.ts +143 -1
  90. package/dist/lib/mesh/live/daemon/install.js +444 -2
  91. package/dist/lib/mesh/live/daemon/paths.d.ts +2 -0
  92. package/dist/lib/mesh/live/daemon/paths.js +2 -0
  93. package/dist/lib/mesh/live/daemon/run.d.ts +2 -0
  94. package/dist/lib/mesh/live/daemon/run.js +111 -54
  95. package/dist/lib/mesh/live/daemon/state.d.ts +2 -0
  96. package/dist/lib/mesh/live/daemon/transcript-watch.d.ts +3 -0
  97. package/dist/lib/mesh/live/daemon/transcript-watch.js +31 -8
  98. package/dist/lib/scan-packages/index.d.ts +2 -0
  99. package/dist/lib/scan-packages/index.js +18 -13
  100. package/dist/lib/work-context/config.d.ts +20 -0
  101. package/dist/lib/work-context/config.js +26 -5
  102. package/dist/lib/work-context/reconcile.js +28 -7
  103. package/dist/lib/work-context/state.d.ts +12 -0
  104. package/dist/lib/work-context/state.js +131 -3
  105. package/dist/lib/work-context/windows-acl.d.ts +123 -0
  106. package/dist/lib/work-context/windows-acl.js +425 -0
  107. package/dist/utils/pack-contributions.js +5 -4
  108. package/package.json +3 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,335 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [5.127.0] — 2026-09-22
6
+
7
+ ### Added
8
+
9
+ - Every composed lane brief and every resume turn carries a foreground-only
10
+ rule after the standing authorization: run every command, test suite and
11
+ check in the foreground and wait for it; a turn that ends before the envelope
12
+ is written is classified interrupted.
13
+ - The spec §4 envelope repair turn now runs for grok as well. A provider with
14
+ no session resume gets one fresh single-turn invocation on the same account
15
+ carrying the schema, the parser error and the raw failed output. The lane
16
+ records `envelope_repair.mode` as `resume` (claude, codex) or `fresh_turn`
17
+ (grok) and `hq lanes show` prints it as `envelope_repair_mode`.
18
+ - Lane records now reject omissions of required `hq-lane.v1` fields, and lane
19
+ mutations enforce the durable field-writer ownership map at the store boundary.
20
+ The map grants `reconcile` the quota fields it writes during dead-host
21
+ recovery, the outpost pickup account bind carries the `spawn` writer, and
22
+ `terminal_details` and `outpost_command_id` are typed and owned. The writer
23
+ argument is a required writer name; the function-form call that skipped the
24
+ ownership check is gone. The updater receives a deep clone and the check
25
+ compares against the pre-update snapshot, so mutating the argument in place
26
+ cannot bypass ownership.
27
+ - Answer notes reach a resumed lane: `answered-questions.json` carries the
28
+ operator's `--notes` text read from the lane's own body store, and the resume
29
+ prompt renders each answer as its choice followed by the notes.
30
+ - Every lane brief and every resume turn carries a standing authorization
31
+ paragraph: the brief authorises completing every item it lists, and a
32
+ `decision: ask` envelope is only for a decision the brief does not settle.
33
+ - A question whose options are only continue and stop is recorded with
34
+ `question_kind: "continue"` and `hq lanes questions list` prints it with
35
+ `flag: "continue-loop"`. Nothing answers it automatically.
36
+ - `hq lanes list` reports `senior_lost: true` for a running lane whose senior
37
+ session is absent, ended, or lost, without mutating the lane.
38
+ - `hq lanes questions answer --freeform <text>` answers a question that offered
39
+ options with free text and records `answer_kind: freeform`.
40
+ - `hq lanes resume <lane-id> [--text <message>]` resumes an `interrupted`,
41
+ `done` or `blocked` lane on its recorded provider session and records
42
+ `resumed_from`. Codex lanes record their session id at spawn and resume with
43
+ `codex exec resume`, so `hq lanes message` and the envelope repair turn now
44
+ work for exited Codex lanes as they do for Claude.
45
+ - Lanes now report to the work mesh from the watcher, not only at create. A
46
+ lane that finishes posts a completion event and moves its story to review;
47
+ one that stops to ask posts the question ids; one that is blocked posts the
48
+ reason. While a lane is working, the watcher posts a progress event when it
49
+ sees a new tool call or new output, at most once per five minutes per lane
50
+ (`providers.<provider>.progress_event_min_interval_ms` in
51
+ `personal/lanes/config.json`), and never for silence. The watcher signs in
52
+ the same way the session hooks do and never opens a browser; when it cannot
53
+ reach the mesh it writes `mesh_event_failed` to the lane's watcher log and
54
+ the lane's state is unchanged. On the wire, lane events use the mesh's
55
+ existing activity, question, and note kinds, because the server rejects
56
+ unknown kinds.
57
+ - A lane whose final output is not a valid envelope gets one repair turn: the
58
+ same session is resumed with the schema, the parser error, and the raw text,
59
+ and asked for the corrected JSON only. If that also fails the lane is
60
+ `failed` with reason `envelope_invalid`, and `envelope_repair` on the record
61
+ carries both errors. Codex and Grok lanes cannot be resumed after exit, so
62
+ they still fail on the first parse error; the record says why no repair ran.
63
+ - A worker with `verification.approval_required` or `human_checkpoints` now
64
+ briefs its lane to stop at each checkpoint with a `decision: ask` envelope
65
+ naming the checkpoint. The resume prompt after the answer carries the answer
66
+ inline as well as naming the answers file.
67
+ - `hq lanes ask` retries delivery three times, waiting 5 s then 15 s, when the
68
+ CLI is being replaced under it. On final failure it writes
69
+ `ask_delivery_failed.json` and returns `ask_delivery_failed`; the lane's
70
+ state is never changed.
71
+ - You can hand a piece of work off to run on its own, and it keeps going after
72
+ you close the window. If it hits something only you can decide, it stops and
73
+ asks instead of guessing, and picks up again the moment you answer — you no
74
+ longer have to sit and watch it. If it goes quiet for twenty minutes, you are
75
+ told. Work sent to a second machine that would have landed back on the one
76
+ that asked is stopped before it starts.
77
+ - `hq lanes create --model` records the model on the lane and passes the
78
+ provider's own flag (`--model` for Claude, `-m` for Codex and Grok).
79
+ Account and provider `model` keys in `personal/lanes/config.json` are
80
+ defaults; `--model` wins. An empty `--model` is refused.
81
+ - Lane envelopes may include `story_complete` and `story_complete_reason`.
82
+ `story_complete true` requires `story_status done`; `false` forbids it.
83
+ Both are copied onto the lane record when an envelope is ingested.
84
+ - `hq lanes create --effort <level>` sets reasoning effort per provider
85
+ (`--effort` for Claude, `-c model_reasoning_effort` for Codex,
86
+ `--reasoning-effort` for Grok), validated against each provider's own set.
87
+ `effort` on an account or provider in `personal/lanes/config.json` is the
88
+ default; with nothing set, an Opus or Fable model runs at `low`.
89
+ - A resumed Claude lane whose last message is older than `compact_after_ms`
90
+ (default one hour) is compacted with `/compact` before the resume, and the
91
+ lane records the outcome and the before/after context size. `hq lanes
92
+ message --no-compact` skips it once. `accounts list` and `show` report
93
+ model, effort and the last compaction.
94
+ - `--worker` resolves workers from `core/workers`, `personal/workers`,
95
+ `companies/<co>/workers`, and packages mounted by `hq core scan-packages`.
96
+ A worker id present in two trees is refused; a pack worker that is declared
97
+ but not mounted is `package_workers_unmounted`.
98
+ - A provider 429 is recorded per account and model in
99
+ `personal/lanes/quota.json` (`account_quota_exhausted` with the reset time,
100
+ or `account_model_unavailable` when a model needs credits). The balancer
101
+ skips only what cannot run and never rewrites the operator's `enabled`.
102
+ - `hq mesh story` accepts `--assignee <uid|me|none>` with or without `--status`.
103
+ `me` uses the authenticated person or agent and refuses the synthetic session
104
+ identity. `none` clears the assignee. The command does not send an actor.
105
+ - `hq mesh project set <projectId> --company <slug>` now reads and merges the
106
+ current Board view before replacing it, so a name or description update keeps
107
+ existing stories and repository bindings. It accepts repository bindings from
108
+ PRD `metadata.repos`, `--repos-json`, or repeatable `--repo <path[@branch]>`.
109
+ `hq mesh project register <projectId> --company <slug>` registers the Board's
110
+ deterministic project channel and genesis thread without raw API calls.
111
+ - A work-context session-state lock or directory creation failure is reported
112
+ as not tracking (exit 3) instead of an uncaught filesystem error.
113
+ - The Work Mesh daemon now distinguishes an explicit device-default membership
114
+ revocation from malformed or unavailable membership lookups. Temporary
115
+ failures preserve attribution and retry later; explicit denials clear only
116
+ the unchanged device-default binding through the shared session-state lock,
117
+ so concurrent rebinds are preserved. Transcript-start discovery also leaves
118
+ unavailable lookups unstarted and retries with bounded backoff.
119
+
120
+ ### Fixed
121
+
122
+ - `hq agents status` no longer tells you to sign in to a brain that is already
123
+ signed in. A device pairing file can outlive the sign-in it started, so the
124
+ box sign-in probe now decides whether the prompt is shown. Grok and Codex
125
+ prompts are matched to their own brain slot; a Claude prompt has no slot and
126
+ is unaffected.
127
+ - Lane watcher mesh calls now time out, progress events only follow new
128
+ activity, and a persisted progress timestamp prevents duplicate events after
129
+ a watcher restart. Invalid-envelope repair is limited to one attempt even
130
+ when the repair writes a different envelope filename.
131
+ - Completion mesh delivery attempts the thread event and story review update
132
+ independently. Repair prompts cap inlined malformed JSON while retaining the
133
+ raw envelope path.
134
+
135
+ - `hq lanes reconcile install --enable` now enables the systemd user timer; the
136
+ generated unit uses `KillMode=process` so admitted lanes survive the pass, and
137
+ its PATH carries the directories of the resolved provider binaries. A provider
138
+ binary missing from PATH at spawn leaves the lane `queued` with
139
+ `provider_binary_missing` instead of failing it.
140
+ - A provider binary missing from PATH re-queues a lane only on admission. An
141
+ answered-question or operator-message resume keeps the lane's recorded state
142
+ and returns `provider_binary_missing` with the searched PATH, so the next
143
+ reconcile resumes the recorded session instead of starting a fresh run and
144
+ the operator message is not lost.
145
+ - `hq lanes reconcile install` succeeds on a box with only one provider
146
+ installed. The unit PATH carries the providers that resolve; the result lists
147
+ `providers_resolved`, `providers_unresolved`, and a `warnings` line per
148
+ missing provider. It refuses with `provider_binary_unresolved` only when no
149
+ enabled provider resolves.
150
+ - `hq lanes questions answer` treats a whitespace-only `--freeform` as absent,
151
+ so `--choice` is validated against the options and recorded as an option
152
+ answer instead of an empty freeform answer.
153
+ - A synced question conflict sidecar whose `answer_history` is not an array is
154
+ skipped like any other unreadable sidecar instead of failing every read of
155
+ the question.
156
+ - `hq lanes resume` now keeps terminal lanes terminal when account binding
157
+ fails, records project or story attribution without requiring `--text`, and
158
+ rejects a concurrent resume that has already become running. Blocked mesh
159
+ notes use the accepted `audit` note kind and include their reason in text so
160
+ the server preserves the marker.
161
+
162
+ - `hq agents list` shows an agent whose removal is under way as `removing`
163
+ rather than the runtime status it had before the removal started. An agent
164
+ that never finished setting up and is then removed used to keep reading
165
+ `provisioning` until the teardown completed, so a removal that stalled
166
+ looked like a removal that was never accepted. A finished teardown reads
167
+ `removed`; every other agent is unchanged.
168
+ - `hq lanes accounts list` treats Claude as logged in when
169
+ `.credentials.json` exists. Missing Claude credentials are reported as
170
+ unknown, not logged out. Codex and Grok still use `auth.json`.
171
+ - With no `--account`, a lane is assigned the least-loaded enabled
172
+ logged-in account rather than `default_account`.
173
+ - A lane watcher now writes a JSON line to `logs/watcher.out` for each
174
+ decision that changes what it believes: a liveness transition, a silence
175
+ deadline, an envelope appearing, the exit classification, and the
176
+ terminal record write. `hq lanes logs` reports each stream's path, size
177
+ in bytes, and lines, so an empty log file is distinguishable from a
178
+ missing lane. `watcher.out` is capped at 256 KiB by dropping the oldest
179
+ complete lines. `hq lanes message` refuses a lane that will never read
180
+ the drop box (`awaiting_input`, `blocked`, and every terminal state) and
181
+ still accepts a queued lane. After the HQ root is resolved, `hq lanes`
182
+ chdirs into it; relative `--brief-file` and `--payload-file` paths still
183
+ resolve against the caller's original directory.
184
+ - `hq lanes` no longer treats a git worktree's `.claude` folder as the HQ
185
+ root, and it honours `$HQ_ROOT` the same way the watcher and reconcile
186
+ timer already did. Listing or creating a lane from a worktree talks to
187
+ the real store, or fails out loud — it does not return an empty success
188
+ against a directory nothing else reads.
189
+ - Creating a lane with `--outpost` now pushes it through `hq outposts exec`
190
+ instead of leaving a queued row that no machine will pick up. If the
191
+ Outpost is unreachable, the lane is failed, not queued.
192
+ - A lane that finishes by asking a question now actually queues that question,
193
+ so someone can answer it and the lane can continue. Stopping a lane now
194
+ stops the process, not only the record. The drain hook that delivers
195
+ mid-run answers is installed into the account home instead of sitting unused
196
+ in the package. The periodic reconcile timer now names this HQ tree, so it
197
+ does not wander into `$HOME/.claude`. A live lane heartbeats from its
198
+ watcher; a dead watcher is started again; a reused PID is not treated as
199
+ the worker still running; a malformed drop-box line no longer wedges every
200
+ tool call.
201
+ - `hq mesh start` now resolves its claimant from the token that authenticates
202
+ the request before considering a same-identity cache entry. This prevents an
203
+ agent from claiming work as a cached human and stops locally before creating
204
+ a thread when no authenticated claimant can be established.
205
+
206
+ - `hq mesh context backfill-held` no longer reports `reconciled: 0` when
207
+ `--dry-run` predicts non-zero reconcilable sessions. The check that decides
208
+ whether reconcile produced a durable company binding now recognises a
209
+ persisted `companySlug` as sufficient — the daemon resolves the uid on its
210
+ next retry — instead of requiring `companyUid`, which is absent when the
211
+ reconciler runs without a network membership call. Sessions that have no
212
+ company evidence at all now appear in a separate `noEvidence` counter so
213
+ operators can tell them apart from sessions that were genuinely reconciled
214
+ as slug-only bindings.
215
+
216
+ ## [5.126.0] — 2026-09-21
217
+
218
+ ### Fixed
219
+
220
+ - `hq mesh start` works for people again. It was sending your email address as
221
+ the claimant, and the server compares that to your person id, so every human
222
+ start failed with "claimedBy must match the authenticated author" and left
223
+ the thread unclaimed. Claims now carry your resolved person id (bots keep
224
+ their agent id).
225
+
226
+ ### Changed
227
+
228
+ - On Windows, the mesh daemon's Scheduled Task now names the HQ root it was
229
+ installed for right in the task command (`mesh daemon run --hq-root <path>`)
230
+ instead of relying on a remembered list of roots. Install only wraps the
231
+ daemon in `conhost.exe --headless` when the machine is new enough to support
232
+ it (Windows 10 1809 or later) and says which mode it chose. `hq mesh daemon
233
+ status` now reports when the task's last start failed, and reminds you that
234
+ the task only runs while you are logged on. macOS and Linux are unchanged.
235
+
236
+ - `hq mesh daemon install` no longer mistakes a code repo for your HQ. It
237
+ accepts `--hq-root <path>`, otherwise uses `HQ_ROOT`, otherwise walks up
238
+ from the current folder to the nearest real HQ tree (one with
239
+ `companies/manifest.yaml` and `core/`, `.claude/`, or `personal/`). A folder
240
+ that only has `.claude/` does not count. If nothing qualifies, install stops
241
+ and tells you to pass `--hq-root` instead of recording the wrong root. The
242
+ install confirmation now leads with the root it chose and how, and `hq mesh
243
+ daemon status` prints the root the task actually carries and warns when that
244
+ folder has since moved or been deleted.
245
+
246
+ - The setup bot now recognises when you have joined a company that someone
247
+ else already built. Instead of asking what kind of business you own and
248
+ offering to connect apps your team connected months ago, it shows you what
249
+ is already there in real names and counts, answers one real question from
250
+ your company's own memory, asks what you do there, and offers only what is
251
+ missing for you. Things only an owner can do now name the owner instead of
252
+ failing.
253
+
254
+ - The setup bot asks which tools you actually use and connects each one
255
+ however that tool needs it, after recommending the few things a business
256
+ like yours should set up. It no longer works from a fixed list of apps.
257
+
258
+ - Setup no longer asks for your name when you are already signed in, and no
259
+ longer offers to skip itself.
260
+
261
+ ### Fixed
262
+
263
+ - The desktop grok bot talks to grok 0.2.56 again. That CLI dropped
264
+ `--output-format streaming-messages-json` (only `plain`, `json`, and
265
+ `streaming-json` remain). The bot now reads the value from `grok --help`
266
+ once and caches it, retries with `streaming-json` if grok rejects the old
267
+ flag, and concatenates `streaming-json` text deltas for the reply instead
268
+ of treating them as Anthropic Messages events.
269
+
270
+ - `hq core scan-packages` writes pack-mount symlinks relative to the host
271
+ directory, so they survive a tree moving between machines. A leftover
272
+ absolute link from another host, or an absolute link that still points at
273
+ this pack's payload, is rewritten to the relative form on the next scan; a
274
+ correct relative link is left alone.
275
+
276
+ - Work Mesh reconcile now owns company attribution explicitly on the acked
277
+ path for every register where `resolvedCompany.uid` is set, not only fully
278
+ bound sessions. Previously the non-bound acked path had no reconcile-owned
279
+ attribution write and relied on an incidental side effect of
280
+ `writeAckedRegisterState` → `writeAcknowledgedRegisterBinding`; that side
281
+ effect already wrote `companyUid`/`companySlug` for ops carrying a uid, so
282
+ the tenant was not dropped in practice, but any future acked path that
283
+ preceded or skipped that call would silently lose it. The fix makes
284
+ attribution explicit: a company-only ack is projected as `needs_project`
285
+ with its tenant intact, the write reflects the true classification, and no
286
+ `projectId`, `taskId`, or binding episode is fabricated on partial paths.
287
+ Note: a company resolved by slug only (no uid) is still not attributed on
288
+ either path.
289
+
290
+ - The setup bot no longer posts the same question twice when a turn takes a
291
+ while: a question asked in an interim update is held back if the final
292
+ answer repeats it.
293
+
294
+ - On Windows, the work-context config safety check now inspects the file's
295
+ Windows ACL instead of POSIX mode bits, so `hq mesh context reconcile` no
296
+ longer refuses every run with "unsafe permissions 666" and session state and
297
+ register operations are written again. The config file and its directory must
298
+ be writable only by the current user, SYSTEM, and Administrators; any other
299
+ principal with write access is rejected, matched by SID so localized account
300
+ names do not matter, and named in the error. When the ACL cannot be read
301
+ at all (icacls missing, non-NTFS volume), the check follows a documented
302
+ reduced-guarantee path: it prints one diagnostic that the config is
303
+ unprotected on this platform and continues rather than blocking. macOS and
304
+ Linux behaviour is unchanged.
305
+
306
+ ### Added
307
+
308
+ - `hq mesh daemon install` now works on Windows. It registers a per-user
309
+ Scheduled Task (`ai.getindigo.hq-mesh-daemon`) that starts the mesh daemon at
310
+ logon, hidden, with no execution time limit and a restart-on-failure policy,
311
+ and starts it right away. `hq mesh daemon status` reports whether the task is
312
+ registered and running, `hq mesh daemon uninstall` ends and removes it, and a
313
+ CLI update restarts it like the macOS and Linux services. Before this the
314
+ three commands answered "No service manager integration on this platform",
315
+ so the session-event spool never drained on Windows. The task definition is
316
+ written as XML under `~/.hq/work-mesh/daemon/` and registered with
317
+ `schtasks.exe`; no new dependencies. macOS and Linux behaviour is unchanged.
318
+
319
+ - `hq bot list --json` reports `busy` and `busySince` for each bot on this
320
+ computer, and `hq bot status` shows an `answering:` line. Apps use this to
321
+ keep a "thinking" indicator up for a whole turn, rather than ending it the
322
+ moment the bot posts a progress note.
323
+
324
+ - Library layer for `hq lanes` (`src/lib/lanes/`): lane/question record store
325
+ with compare-and-set writes, provider-account resolution, CPU/memory throttle,
326
+ session liveness from the work-mesh spool, and path-keyed worker tenancy.
327
+
328
+ - `hq lanes` command surface: create/list/show/message/reparent/logs/stop,
329
+ non-blocking ask, questions list/show/answer/escalate/cancel, accounts
330
+ list/login/enable/disable, and sessions list/show. Create admits against
331
+ provider caps, the bounded queue, and the host throttle, then leaves the
332
+ lane queued — process spawn is an explicit not-implemented seam.
333
+
5
334
  ## [5.125.0] — 2026-09-20
6
335
 
7
336
  ### Fixed
@@ -0,0 +1,125 @@
1
+ ---
2
+ name: joining-a-team
3
+ title: Joining a team
4
+ description: Set up someone who installed HQ into a company that already exists, by showing them what they just inherited and adding what is missing for them.
5
+ ---
6
+
7
+ # Joining a team
8
+
9
+ Most people who install HQ from here on are not founders. They are the fourth
10
+ person at a company that already has channels, connected apps, meetings,
11
+ knowledge and bots. Their setup is not "build an HQ". It is "here is the HQ you
12
+ just walked into, and here is what I will add for you."
13
+
14
+ Getting this wrong is what makes setup feel generic: asking a new account
15
+ manager what kind of business they own, or offering to connect a note taker
16
+ their company connected months ago.
17
+
18
+ ## 1. Work out that this is an existing company, before you ask anything
19
+
20
+ Their companies come from the "Owner context" block at the top of their
21
+ message. Never use your own `hq` membership for this; that describes you, the
22
+ bot.
23
+
24
+ When the block names a company, look at how much is already in it. Quiet
25
+ reads, one message of output for them at the end, never a transcript of the
26
+ looking:
27
+
28
+ - People: `hq members list` (and `hq people list`) for the company.
29
+ - Conversations: `hq channels`.
30
+ - Apps the company already connected: `hq integrations list`.
31
+ - Bots already working there: `hq agents list`, and `hq bot list --remote`.
32
+ - What the shared memory holds: the company folder under `companies/<slug>/`
33
+ (knowledge, projects, people), `hq meetings list --limit 5`,
34
+ `hq signals list --limit 10`, and `hq search "<a word from their work>"`.
35
+
36
+ Then decide which of these you are in:
37
+
38
+ - **A company with things in it** (more than one person, or any connected app,
39
+ bot, meeting or knowledge). This skill is the whole middle of their setup.
40
+ - **A company that is empty** (they were invited, but nothing has been set up
41
+ yet). Treat it as a founder's setup that happens to have a company already:
42
+ do not create one, and follow `skills/your-business.md` as written.
43
+ - **No company.** This skill does not apply. Go back to
44
+ `skills/first-company.md`.
45
+
46
+ If the owner-context check failed, say you could not check right now. Never
47
+ treat an unreadable check as "you are alone".
48
+
49
+ ## 2. Give them the tour, grounded in what is actually there
50
+
51
+ One short message. Real names and counts from the reads above, never a
52
+ description of HQ as a product:
53
+
54
+ > You're in **Northwind** with Sara, Ali and two others. The team has Slack,
55
+ > Fireflies and Linear connected, 40 meetings recorded, and two bots already
56
+ > running: one that writes the weekly update, one that watches support.
57
+
58
+ Then prove it, in the same breath, with one real answer only their company's
59
+ HQ could give. Pull it yourself and show the answer, not the method:
60
+
61
+ > From last week: the team decided to push the pricing change to November and
62
+ > to keep the legacy plan for existing customers.
63
+
64
+ That single line is what makes the product land. A person who reads it
65
+ understands the shared context layer without being told about it.
66
+
67
+ Then say what it means for them, in their words: everything the team has
68
+ connected is already theirs, every bot they talk to starts from it, and
69
+ anything they add lands for the whole team the same way.
70
+
71
+ Never invent any of this. If a category is empty, say so plainly and make it
72
+ the first thing you offer to fix.
73
+
74
+ ## 3. Ask about them, not about the business
75
+
76
+ You already know the business. Confirm it in half a sentence rather than
77
+ asking. What you do not know is where they fit, so ask that, one question, in
78
+ plain words:
79
+
80
+ > What do you do at Northwind, day to day?
81
+
82
+ Their answer decides everything you offer next. Write it into their profile
83
+ the way step 5 of the walkthrough describes, so every other bot knows it too.
84
+
85
+ If they seem more interested in understanding HQ than in configuring it, let
86
+ that be the session: walk them through what is in their HQ, answer questions,
87
+ and offer the additions at the end. Familiarity is a legitimate outcome of
88
+ setup for a joiner.
89
+
90
+ ## 4. Offer what is missing for them, not for the company
91
+
92
+ Check what exists before offering anything, and say plainly what they already
93
+ have rather than offering it again:
94
+
95
+ > Fireflies is already connected, so your meetings are in here from today.
96
+
97
+ Then offer only the gaps, three at most, each with a reason tied to what they
98
+ just told you:
99
+
100
+ - **Their own tools on this Mac**: the coding tool they use, signed in.
101
+ - **Apps the company has not connected**, or that are personal to them: their
102
+ own calendar and inbox, the board they personally live in.
103
+ - **A home for their own work**: their projects or their clients, alongside
104
+ the company's.
105
+ - **Their first bot**, aimed at their job rather than the company's: what they
106
+ do every morning that a bot could do first.
107
+
108
+ ## 5. Things only an owner can do
109
+
110
+ Inviting people, company-wide credentials and some company files may not be
111
+ theirs to change. When they ask for one, do not attempt it and fail. Say who
112
+ can do it, by name, from the members list, and offer to send that person the
113
+ request from them:
114
+
115
+ > Sara owns Northwind, so the invite has to come from her. Want me to message
116
+ > her and ask?
117
+
118
+ If a read is refused, say so in one line, name the person who can grant it,
119
+ and move on. Never retry, and never guess at what the file said.
120
+
121
+ ## 6. Finish
122
+
123
+ Close the way the walkthrough closes, with their version of it: what they
124
+ inherited, what you added today, and the one thing worth trying tomorrow. If
125
+ they have a bot now, hand them over to it.