instar 1.3.438 → 1.3.440

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 (74) hide show
  1. package/.claude/skills/autonomous/SKILL.md +24 -6
  2. package/dist/commands/server.d.ts.map +1 -1
  3. package/dist/commands/server.js +31 -0
  4. package/dist/commands/server.js.map +1 -1
  5. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  6. package/dist/core/PostUpdateMigrator.js +20 -10
  7. package/dist/core/PostUpdateMigrator.js.map +1 -1
  8. package/dist/core/types.d.ts +8 -0
  9. package/dist/core/types.d.ts.map +1 -1
  10. package/dist/core/types.js.map +1 -1
  11. package/dist/messaging/slack/SlackAdapter.d.ts +13 -0
  12. package/dist/messaging/slack/SlackAdapter.d.ts.map +1 -1
  13. package/dist/messaging/slack/SlackAdapter.js +23 -0
  14. package/dist/messaging/slack/SlackAdapter.js.map +1 -1
  15. package/dist/messaging/slack/types.d.ts +11 -0
  16. package/dist/messaging/slack/types.d.ts.map +1 -1
  17. package/dist/messaging/slack/types.js.map +1 -1
  18. package/dist/permissions/AnomalyScorer.d.ts +54 -0
  19. package/dist/permissions/AnomalyScorer.d.ts.map +1 -0
  20. package/dist/permissions/AnomalyScorer.js +68 -0
  21. package/dist/permissions/AnomalyScorer.js.map +1 -0
  22. package/dist/permissions/IntentClassifier.d.ts +33 -0
  23. package/dist/permissions/IntentClassifier.d.ts.map +1 -0
  24. package/dist/permissions/IntentClassifier.js +88 -0
  25. package/dist/permissions/IntentClassifier.js.map +1 -0
  26. package/dist/permissions/PermissionDecisionLedger.d.ts +42 -0
  27. package/dist/permissions/PermissionDecisionLedger.d.ts.map +1 -0
  28. package/dist/permissions/PermissionDecisionLedger.js +61 -0
  29. package/dist/permissions/PermissionDecisionLedger.js.map +1 -0
  30. package/dist/permissions/RolePolicy.d.ts +34 -0
  31. package/dist/permissions/RolePolicy.d.ts.map +1 -0
  32. package/dist/permissions/RolePolicy.js +60 -0
  33. package/dist/permissions/RolePolicy.js.map +1 -0
  34. package/dist/permissions/SlackPermissionGate.d.ts +62 -0
  35. package/dist/permissions/SlackPermissionGate.d.ts.map +1 -0
  36. package/dist/permissions/SlackPermissionGate.js +117 -0
  37. package/dist/permissions/SlackPermissionGate.js.map +1 -0
  38. package/dist/permissions/SlackPermissionObserver.d.ts +37 -0
  39. package/dist/permissions/SlackPermissionObserver.d.ts.map +1 -0
  40. package/dist/permissions/SlackPermissionObserver.js +39 -0
  41. package/dist/permissions/SlackPermissionObserver.js.map +1 -0
  42. package/dist/permissions/SlackPrincipalResolver.d.ts +39 -0
  43. package/dist/permissions/SlackPrincipalResolver.d.ts.map +1 -0
  44. package/dist/permissions/SlackPrincipalResolver.js +60 -0
  45. package/dist/permissions/SlackPrincipalResolver.js.map +1 -0
  46. package/dist/permissions/index.d.ts +13 -0
  47. package/dist/permissions/index.d.ts.map +1 -0
  48. package/dist/permissions/index.js +13 -0
  49. package/dist/permissions/index.js.map +1 -0
  50. package/dist/permissions/testing/SlackScenarioHarness.d.ts +35 -0
  51. package/dist/permissions/testing/SlackScenarioHarness.d.ts.map +1 -0
  52. package/dist/permissions/testing/SlackScenarioHarness.js +130 -0
  53. package/dist/permissions/testing/SlackScenarioHarness.js.map +1 -0
  54. package/dist/permissions/types.d.ts +108 -0
  55. package/dist/permissions/types.d.ts.map +1 -0
  56. package/dist/permissions/types.js +21 -0
  57. package/dist/permissions/types.js.map +1 -0
  58. package/dist/server/CapabilityIndex.d.ts.map +1 -1
  59. package/dist/server/CapabilityIndex.js +1 -0
  60. package/dist/server/CapabilityIndex.js.map +1 -1
  61. package/dist/server/routes.d.ts.map +1 -1
  62. package/dist/server/routes.js +44 -0
  63. package/dist/server/routes.js.map +1 -1
  64. package/dist/users/UserManager.d.ts +9 -0
  65. package/dist/users/UserManager.d.ts.map +1 -1
  66. package/dist/users/UserManager.js +21 -0
  67. package/dist/users/UserManager.js.map +1 -1
  68. package/package.json +1 -1
  69. package/src/data/builtin-manifest.json +64 -64
  70. package/src/data/state-coherence-registry.json +12 -0
  71. package/upgrades/1.3.439.md +23 -0
  72. package/upgrades/1.3.440.md +25 -0
  73. package/upgrades/side-effects/autonomous-setup-race-hardening.md +56 -0
  74. package/upgrades/side-effects/slack-org-permission-gate.md +80 -0
@@ -75,7 +75,20 @@ if json.dumps(hooks) != before:
75
75
 
76
76
  **2b. Write the state file DIRECTLY** (do NOT shell out to bash — the session ID env var is only available inside Claude Code):
77
77
 
78
- Use the **Write tool** to create `.instar/autonomous-state.local.md` with this content:
78
+ Use the **Write tool** to create the **per-topic** state file `.instar/autonomous/<topicId>.local.md`,
79
+ where `<topicId>` is the `report_topic` value you set below (the Telegram topic id you already know
80
+ in-context). For example, if `report_topic` is `19437`, write `.instar/autonomous/19437.local.md`.
81
+
82
+ **WHY PER-TOPIC (setup-race hardening):** the stop hook reads this per-topic file **directly**
83
+ (`.instar/autonomous/<topicId>.local.md`) — it is the canonical state path, keyed on topic so
84
+ multiple topics run concurrent autonomous jobs without collision. Writing the per-topic path here
85
+ closes a boot-window race: two autonomous sessions starting near-simultaneously must NOT both write
86
+ the single legacy file `.instar/autonomous-state.local.md` (the hook still migrates that legacy file
87
+ for in-flight older jobs, but new jobs write the per-topic file from the start so there is nothing to
88
+ collide on). If you somehow have no `report_topic`, fall back to `.instar/autonomous-state.local.md`
89
+ (one-at-a-time, back-compat only).
90
+
91
+ Write this content:
79
92
 
80
93
  ```markdown
81
94
  ---
@@ -197,17 +210,20 @@ The stop hook detects the promise and allows exit.
197
210
  The user can always stop autonomous mode:
198
211
 
199
212
  1. **Via messaging**: Send "stop everything" or "emergency stop" — the MessageSentinel intercepts
200
- 2. **Via file**: `touch .instar/autonomous-emergency-stop` — the stop hook checks for this
201
- 3. **Via cancel**: `/cancel-autonomous` removes the state file
213
+ 2. **Via file**: `touch .instar/autonomous-emergency-stop` — the stop hook checks for this (this flag is
214
+ global, so it halts EVERY topic's autonomous job at once)
215
+ 3. **Via cancel**: `/cancel-autonomous` — removes this topic's state file
202
216
 
203
217
  The stop hook checks for emergency stop on EVERY iteration. User safety is never compromised.
204
218
 
205
219
  ### /cancel-autonomous
206
220
 
207
- To manually cancel:
221
+ To manually cancel THIS topic's job, remove its per-topic state file (substitute the topic id):
208
222
  ```bash
209
- rm -f .instar/autonomous-state.local.md
223
+ rm -f .instar/autonomous/<topicId>.local.md
210
224
  ```
225
+ (Older one-at-a-time jobs may still live at the legacy `.instar/autonomous-state.local.md` — remove
226
+ that instead if the per-topic file is absent.)
211
227
 
212
228
  ---
213
229
 
@@ -259,7 +275,9 @@ Feeling tired (as an AI) and deferring. **You don't get tired. The hook knows th
259
275
 
260
276
  The stop hook is at `.claude/skills/autonomous/hooks/autonomous-stop-hook.sh`.
261
277
 
262
- It reads state from `.instar/autonomous-state.local.md` and:
278
+ It reads state from the per-topic file `.instar/autonomous/<topicId>.local.md` (resolving the topic
279
+ from the tmux session), and migrates the legacy single file `.instar/autonomous-state.local.md` into
280
+ the per-topic path on first run for any in-flight older job. It then:
263
281
  - Blocks exit if tasks are incomplete
264
282
  - Feeds the task list + goal back as the next prompt
265
283
  - Increments the iteration counter
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAS3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AAuBjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAiG7D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AA6JtD,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA05BD,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,eAAe,EACzB,cAAc,EAAE,cAAc,EAC9B,YAAY,CAAC,EAAE,YAAY,EAC3B,WAAW,CAAC,EAAE,WAAW,EACzB,WAAW,CAAC,EAAE,WAAW,EACzB,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,EAGvE,UAAU,CAAC,EAAE,MAAM,OAAO,8BAA8B,EAAE,WAAW,GAAG,IAAI,EAK5E,qBAAqB,CAAC,EAAE,MAAM,OAAO,gCAAgC,EAAE,kBAAkB,GAAG,IAAI,GAC/F,IAAI,CAyUN;AA2lBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA4mUtE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD5E"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAS3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AAuBjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAiG7D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AA6JtD,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA05BD,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,eAAe,EACzB,cAAc,EAAE,cAAc,EAC9B,YAAY,CAAC,EAAE,YAAY,EAC3B,WAAW,CAAC,EAAE,WAAW,EACzB,WAAW,CAAC,EAAE,WAAW,EACzB,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,EAGvE,UAAU,CAAC,EAAE,MAAM,OAAO,8BAA8B,EAAE,WAAW,GAAG,IAAI,EAK5E,qBAAqB,CAAC,EAAE,MAAM,OAAO,gCAAgC,EAAE,kBAAkB,GAAG,IAAI,GAC/F,IAAI,CAyUN;AA2lBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAmpUtE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD5E"}
@@ -4213,6 +4213,37 @@ export async function startServer(options) {
4213
4213
  try {
4214
4214
  const { SlackAdapter } = await import('../messaging/slack/index.js');
4215
4215
  slackAdapter = new SlackAdapter(slackConfig.config, config.stateDir);
4216
+ // ── Slack org permission gate (Slice 0) — DARK by default ──────────
4217
+ // Attached only when `permissionGate.observeOnly` (or `.enforce`) is set in
4218
+ // the Slack config. Observe-only logs what the gate WOULD decide for every
4219
+ // authorized message and never blocks. See docs/specs/SLACK-ORG-INTEGRATION-SPEC.md.
4220
+ try {
4221
+ const slackCfg = slackConfig.config;
4222
+ const pgCfg = slackCfg.permissionGate;
4223
+ if (pgCfg && (pgCfg.observeOnly || pgCfg.enforce)) {
4224
+ const { SlackPermissionObserver, SlackPrincipalResolver, SlackPermissionGate, PermissionDecisionLedger, RolePolicy, HeuristicIntentClassifier, HeuristicAnomalyScorer, } = await import('../permissions/index.js');
4225
+ // Own UserManager instance for verified-principal resolution (the
4226
+ // Telegram-block userManager is out of scope here). Reads users.json.
4227
+ const slackUserManager = new UserManager(config.stateDir, config.users);
4228
+ const observer = new SlackPermissionObserver({
4229
+ resolver: new SlackPrincipalResolver({
4230
+ resolveFromSlackUserId: (id) => slackUserManager.resolveFromSlackUserId(id),
4231
+ }),
4232
+ gate: new SlackPermissionGate({
4233
+ rolePolicy: new RolePolicy(),
4234
+ classifier: new HeuristicIntentClassifier(),
4235
+ anomalyScorer: new HeuristicAnomalyScorer(),
4236
+ }),
4237
+ ledger: new PermissionDecisionLedger(config.stateDir),
4238
+ enforce: pgCfg.enforce === true,
4239
+ });
4240
+ slackAdapter.setPermissionObserver(observer);
4241
+ console.log(`[slack] permission gate attached (${pgCfg.enforce ? 'ENFORCE' : 'observe-only'})`);
4242
+ }
4243
+ }
4244
+ catch (e) {
4245
+ console.warn('[slack] permission gate wiring skipped:', e.message);
4246
+ }
4216
4247
  // Wire message handler — inject Slack messages into sessions
4217
4248
  slackAdapter.onMessage(async (message) => {
4218
4249
  const channelId = message.channel.identifier;