instar 1.3.1248 → 1.3.1250

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 (32) hide show
  1. package/.claude/skills/autonomous/hooks/autonomous-stop-hook.sh +28 -8
  2. package/.claude/skills/autonomous/scripts/setup-autonomous.sh +39 -5
  3. package/dist/commands/server.d.ts.map +1 -1
  4. package/dist/commands/server.js +20 -0
  5. package/dist/commands/server.js.map +1 -1
  6. package/dist/core/JevSignalShadow.d.ts +98 -0
  7. package/dist/core/JevSignalShadow.d.ts.map +1 -0
  8. package/dist/core/JevSignalShadow.js +230 -0
  9. package/dist/core/JevSignalShadow.js.map +1 -0
  10. package/dist/core/MessagingToneGate.d.ts +10 -0
  11. package/dist/core/MessagingToneGate.d.ts.map +1 -1
  12. package/dist/core/MessagingToneGate.js +18 -0
  13. package/dist/core/MessagingToneGate.js.map +1 -1
  14. package/dist/core/PostUpdateMigrator.d.ts +6 -0
  15. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  16. package/dist/core/PostUpdateMigrator.js +83 -0
  17. package/dist/core/PostUpdateMigrator.js.map +1 -1
  18. package/dist/core/types.d.ts +18 -0
  19. package/dist/core/types.d.ts.map +1 -1
  20. package/dist/core/types.js.map +1 -1
  21. package/dist/data/standards-guard-index.json +1 -1
  22. package/dist/data/standards-guard-index.meta.json +2 -2
  23. package/dist/data/standards-registry.meta.json +1 -1
  24. package/package.json +1 -1
  25. package/scripts/jev-shadow-report.mjs +89 -0
  26. package/src/data/builtin-manifest.json +19 -19
  27. package/src/data/standards-guard-index.json +1 -1
  28. package/src/data/standards-guard-index.meta.json +2 -2
  29. package/src/data/standards-registry.meta.json +1 -1
  30. package/upgrades/{1.3.1248.md → 1.3.1250.md} +50 -0
  31. package/upgrades/side-effects/autonomous-auth-vault-resolve.md +180 -0
  32. package/upgrades/side-effects/jev-signal-shadow.md +138 -0
@@ -124,6 +124,26 @@ LEGACY_STATE=".instar/autonomous-state.local.md"
124
124
  MULTI_DIR=".instar/autonomous"
125
125
  LIVENESS_SECS="${INSTAR_AUTONOMOUS_LIVENESS_SECS:-120}"
126
126
 
127
+ # ── VAULT_AUTH_RESOLVE — the server bearer token, vault-aware. config.json's
128
+ # authToken becomes a SecretMigrator placeholder ({"secret": true}) once an
129
+ # agent's secrets move to the encrypted vault; the old inline reads then printed
130
+ # the literal placeholder and every server call 403'd — on an admission-enforcing
131
+ # install the run registered nothing and sat "preparing" forever (the 2026-09-19
132
+ # silent no-start). Prefer a real string from config; otherwise read the vault
133
+ # via the hardened secret-get script (value to stdout only, never logged).
134
+ resolve_auth_token() {
135
+ local t
136
+ t=$(python3 -c "import json
137
+ try:
138
+ v=json.load(open('.instar/config.json')).get('authToken','')
139
+ print(v if isinstance(v,str) else '')
140
+ except Exception: print('')" 2>/dev/null || echo "")
141
+ if [[ -n "$t" ]]; then printf '%s' "$t"; return 0; fi
142
+ if [[ -f .instar/scripts/secret-get.mjs ]]; then
143
+ node .instar/scripts/secret-get.mjs authToken 2>/dev/null || true
144
+ fi
145
+ }
146
+
127
147
  # The sole shell adapter for bounded task continuation. The TypeScript store and
128
148
  # authenticated decision route remain the mutation/decision authority.
129
149
  continuation_decision() {
@@ -132,7 +152,7 @@ continuation_decision() {
132
152
  [[ -n "$MY_TOPIC" ]] || return 0
133
153
  local port auth agent_id decision reason
134
154
  port=$(python3 -c "import json;print(json.load(open('.instar/config.json')).get('port',4040))" 2>/dev/null || echo 4040)
135
- auth=$(python3 -c "import json;print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null || echo "")
155
+ auth=$(resolve_auth_token)
136
156
  agent_id=$(python3 -c "import json;c=json.load(open('.instar/config.json'));print(c.get('projectName') or c.get('agentName') or 'local-stop-hook')" 2>/dev/null | tr -d '\r\n' || echo "local-stop-hook")
137
157
  [[ -n "$agent_id" ]] || agent_id="local-stop-hook"
138
158
  decision=$(jq -nc --arg topicId "$MY_TOPIC" --arg sessionId "$HOOK_SESSION" '{topicId:$topicId,sessionId:$sessionId}' \
@@ -471,7 +491,7 @@ run_end_call() {
471
491
  fi
472
492
  local re_port re_auth
473
493
  re_port=$(python3 -c "import json;print(json.load(open('.instar/config.json')).get('port',4040))" 2>/dev/null || echo 4040)
474
- re_auth=$(python3 -c "import json;print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null || echo "")
494
+ re_auth=$(resolve_auth_token)
475
495
  jq -nc --arg r "$reason" --arg id "${RUN_ID:-}" --argjson met "$re_met" --argjson terminal "$terminal" \
476
496
  --argjson configured "$re_configured" --arg outcome "$re_outcome" --arg exit "$re_exit" \
477
497
  '{reason:$r,met:$met,terminal:$terminal,realcheck:(if $configured then ({configured:true,outcome:$outcome} + (if $exit != "" then {exitCode:($exit|tonumber)} else {} end)) else {configured:false} end)} + (if $id != "" then {runId:$id} else {} end)' 2>/dev/null \
@@ -570,7 +590,7 @@ if [[ "$GOAL_MODE" == "native" ]]; then
570
590
  native_goal_clear() {
571
591
  local port auth
572
592
  port=$(python3 -c "import json;print(json.load(open('.instar/config.json')).get('port',4040))" 2>/dev/null || echo 4040)
573
- auth=$(python3 -c "import json;print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null || echo "")
593
+ auth=$(resolve_auth_token)
574
594
  jq -nc --arg t "$REPORT_TOPIC" '{topicId:$t}' \
575
595
  | curl -s -m 10 -H "Authorization: Bearer $auth" -H 'Content-Type: application/json' \
576
596
  --data-binary @- "http://localhost:${port}/autonomous/native-goal/clear" >/dev/null 2>&1 || true
@@ -825,7 +845,7 @@ cd_raise_attention_item() {
825
845
  fi
826
846
  local at_port at_auth at_id at_summary
827
847
  at_port=$(python3 -c "import json;print(json.load(open('.instar/config.json')).get('port',4040))" 2>/dev/null || echo 4040)
828
- at_auth=$(python3 -c "import json;print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null || echo "")
848
+ at_auth=$(resolve_auth_token)
829
849
  # One item per run (id keyed on topic+started_at): a re-fire within the same run
830
850
  # reuses the id so the attention store de-dups rather than piling up items.
831
851
  at_id="autonomous-hard-blocker-${REPORT_TOPIC:-none}-$(printf '%s' "${STARTED_AT:-}" | tr -cd '0-9')"
@@ -918,7 +938,7 @@ p13_stop_allowed() {
918
938
  fi
919
939
  [[ -z "$p13_tail" ]] && return 0
920
940
  p13_port=$(python3 -c "import json;print(json.load(open('.instar/config.json')).get('port',4040))" 2>/dev/null || echo 4040)
921
- p13_auth=$(python3 -c "import json;print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null || echo "")
941
+ p13_auth=$(resolve_auth_token)
922
942
  if [[ "$CD_ENABLED" == "1" ]]; then
923
943
  local sig; sig=$(build_signals_json "$stop_kind" "false")
924
944
  p13_payload=$(jq -nc --arg t "$p13_tail" --argjson sig "$sig" '{transcriptTail:$t, signals:$sig}')
@@ -1037,7 +1057,7 @@ realcheck_raise_attention() {
1037
1057
  fi
1038
1058
  local at_port at_auth at_id
1039
1059
  at_port=$(python3 -c "import json;print(json.load(open('.instar/config.json')).get('port',4040))" 2>/dev/null || echo 4040)
1040
- at_auth=$(python3 -c "import json;print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null || echo "")
1060
+ at_auth=$(resolve_auth_token)
1041
1061
  at_id="autonomous-realcheck-stuck-${REPORT_TOPIC:-none}-$(printf '%s' "${STARTED_AT:-}" | tr -cd '0-9')"
1042
1062
  jq -nc \
1043
1063
  --arg id "$at_id" \
@@ -1222,7 +1242,7 @@ run_verification() {
1222
1242
  # authToken literal + a generic Bearer token.
1223
1243
  local rc_leak=0 rc_auth_val
1224
1244
  if [[ "$(hb_leak_hit "$rc_utf8")" == "1" ]]; then rc_leak=1; fi
1225
- rc_auth_val=$(python3 -c "import json;print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null || echo "")
1245
+ rc_auth_val=$(resolve_auth_token)
1226
1246
  if [[ $rc_leak -eq 0 ]] && [[ -n "$rc_auth_val" ]] && printf '%s' "$rc_utf8" | grep -qF "$rc_auth_val" 2>/dev/null; then rc_leak=1; fi
1227
1247
  if [[ $rc_leak -eq 0 ]] && printf '%s' "$rc_utf8" | grep -qE 'Bearer [A-Za-z0-9._-]{20,}' 2>/dev/null; then rc_leak=1; fi
1228
1248
  if [[ $rc_leak -eq 1 ]]; then
@@ -1458,7 +1478,7 @@ if [[ "${CD_BLOCK_TERMINAL:-}" != "true" ]] && [[ -n "$COMPLETION_CONDITION" ]]
1458
1478
  | jq -r '.message.content | map(select(.type=="text")) | map(.text) | join("\n")' 2>/dev/null \
1459
1479
  | tail -c 8000 || echo "")
1460
1480
  EVAL_PORT=$(python3 -c "import json;print(json.load(open('.instar/config.json')).get('port',4040))" 2>/dev/null || echo 4040)
1461
- EVAL_AUTH=$(python3 -c "import json;print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null || echo "")
1481
+ EVAL_AUTH=$(resolve_auth_token)
1462
1482
  # SCOPE_ACCRETION — echo topicId/runId/sessionId so the server resolves the
1463
1483
  # run against its OWN registration record (R35 arming; R36 registered-
1464
1484
  # condition authority; §6 runId pair check). Empty fields are omitted.
@@ -6,6 +6,26 @@
6
6
 
7
7
  set -euo pipefail
8
8
 
9
+ # ── VAULT_AUTH_RESOLVE — the server bearer token, vault-aware. config.json's
10
+ # authToken becomes a SecretMigrator placeholder ({"secret": true}) once an
11
+ # agent's secrets move to the encrypted vault; the old inline reads then printed
12
+ # the literal placeholder and every server call 403'd — on an admission-enforcing
13
+ # install the run registered nothing and sat "preparing" forever (the 2026-09-19
14
+ # silent no-start). Prefer a real string from config; otherwise read the vault
15
+ # via the hardened secret-get script (value to stdout only, never logged).
16
+ resolve_auth_token() {
17
+ local t
18
+ t=$(python3 -c "import json
19
+ try:
20
+ v=json.load(open('.instar/config.json')).get('authToken','')
21
+ print(v if isinstance(v,str) else '')
22
+ except Exception: print('')" 2>/dev/null || echo "")
23
+ if [[ -n "$t" ]]; then printf '%s' "$t"; return 0; fi
24
+ if [[ -f .instar/scripts/secret-get.mjs ]]; then
25
+ node .instar/scripts/secret-get.mjs authToken 2>/dev/null || true
26
+ fi
27
+ }
28
+
9
29
  # Parse arguments
10
30
  GOAL=""
11
31
  DURATION="4h"
@@ -137,7 +157,7 @@ HARD_BLOCKER_NONCE=$(openssl rand -hex 8 2>/dev/null || head -c 16 /dev/urandom
137
157
  # holds. Starting/restarting THIS topic's own job is always allowed.
138
158
  if [[ -n "$REPORT_TOPIC" ]]; then
139
159
  PORT=$(python3 -c "import json;print(json.load(open('.instar/config.json')).get('port',4040))" 2>/dev/null || echo 4040)
140
- AUTH=$(python3 -c "import json;print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null || echo "")
160
+ AUTH=$(resolve_auth_token)
141
161
  CAN_START=$(curl -s -m 3 -H "Authorization: Bearer $AUTH" "http://localhost:${PORT}/autonomous/can-start?priority=medium" 2>/dev/null || echo "")
142
162
  ALLOWED=$(printf '%s' "$CAN_START" | python3 -c "import sys,json
143
163
  try: print(json.load(sys.stdin).get('allowed'))
@@ -154,7 +174,12 @@ except Exception: print('')" 2>/dev/null || echo "")
154
174
  fi
155
175
  if [[ "$ALLOWED" == "unknown" ]] && [[ "$ALREADY_RUNNING" != "true" ]]; then
156
176
  MAX_CONCURRENT=$(python3 -c "import json;print((json.load(open('.instar/config.json')).get('autonomousSessions') or {}).get('maxConcurrent',5))" 2>/dev/null || echo 5)
157
- COUNT=$(ls .instar/autonomous/*.local.md 2>/dev/null | grep -cv "/${REPORT_TOPIC}\.local\.md$")
177
+ # VAULT_AUTH_RESOLVE: grep -c exits 1 on zero matches, and under
178
+ # `set -euo pipefail` that killed the WHOLE setup silently (exit 1, no
179
+ # output) whenever this fallback ran (server unreachable → allowed
180
+ # "unknown") and no OTHER topic had a state file — a silent no-start.
181
+ # `|| true` keeps grep's "0" output.
182
+ COUNT=$(ls .instar/autonomous/*.local.md 2>/dev/null | grep -cv "/${REPORT_TOPIC}\.local\.md$") || true
158
183
  COUNT=${COUNT:-0}
159
184
  if [[ "$COUNT" =~ ^[0-9]+$ ]] && [[ "$MAX_CONCURRENT" =~ ^[0-9]+$ ]] && [[ $COUNT -ge $MAX_CONCURRENT ]]; then
160
185
  echo "❌ Autonomous start refused: concurrency cap reached ($COUNT/$MAX_CONCURRENT) [server unreachable; local check]." >&2
@@ -225,7 +250,7 @@ else
225
250
  fi
226
251
  if [[ -n "$REPORT_TOPIC" ]]; then
227
252
  REG_PORT=$(python3 -c "import json;print(json.load(open('.instar/config.json')).get('port',4040))" 2>/dev/null || echo 4040)
228
- REG_AUTH=$(python3 -c "import json;print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null || echo "")
253
+ REG_AUTH=$(resolve_auth_token)
229
254
  # Comma-separated → JSON array (empty string → []).
230
255
  REG_DECLARED=$(printf '%s' "$DECLARED_DELIVERABLES" | python3 -c "import sys,json
231
256
  print(json.dumps([p.strip() for p in sys.stdin.read().split(',') if p.strip()]))" 2>/dev/null || echo '[]')
@@ -238,8 +263,10 @@ print(json.dumps([p.strip() for p in sys.stdin.read().split(',') if p.strip()]))
238
263
  '{topicId:$t,condition:$c,workDir:$w,declaredDeliverables:$d,startedAt:$s}
239
264
  + (if $e != "" then {endAt:$e} else {} end)
240
265
  + (if $sid != "" then {sessionId:$sid} else {} end)' 2>/dev/null \
241
- | curl -s -m 8 -H "Authorization: Bearer $REG_AUTH" -H 'Content-Type: application/json' \
266
+ | curl -s -m 8 -w '\n%{http_code}' -H "Authorization: Bearer $REG_AUTH" -H 'Content-Type: application/json' \
242
267
  --data-binary @- "http://localhost:${REG_PORT}/autonomous/register" 2>/dev/null || echo "")
268
+ REG_CODE=$(printf '%s' "$REG_RESP" | tail -n 1)
269
+ REG_RESP=$(printf '%s' "$REG_RESP" | sed '$d')
243
270
  RUN_ID=$(printf '%s' "$REG_RESP" | python3 -c "import sys,json
244
271
  try: print(json.load(sys.stdin).get('runId',''))
245
272
  except Exception: print('')" 2>/dev/null || echo "")
@@ -252,6 +279,13 @@ except Exception: print('')" 2>/dev/null || echo "")
252
279
  fi
253
280
  if [[ -n "$RUN_ID" ]]; then
254
281
  echo " Scope-accretion: run registered server-side (runId $RUN_ID)"
282
+ elif [[ "$REG_CODE" == "401" || "$REG_CODE" == "403" ]]; then
283
+ echo " ERROR: run registration REFUSED (HTTP $REG_CODE) — the server rejected the bearer token." >&2
284
+ echo " The token lives in the encrypted vault on migrated agents; this script resolves it via resolve_auth_token()." >&2
285
+ if [[ "$RUN_STATUS" == "preparing" ]]; then
286
+ echo " ABORTING SETUP: this install requires server admission before a run can arm; an unregistered run would sit 'preparing' forever (the silent no-start this guard closes)." >&2
287
+ exit 1
288
+ fi
255
289
  else
256
290
  echo " Scope-accretion: server registration unavailable — accretion gate degrades honestly (run still bounded by duration)"
257
291
  fi
@@ -345,7 +379,7 @@ if [[ -n "$COMPLETION_CONDITION" ]] && [[ -n "$REPORT_TOPIC" ]]; then
345
379
  fi
346
380
  if [[ "$NATIVE_GOAL_OK" == "true" ]]; then
347
381
  NG_PORT=$(python3 -c "import json;print(json.load(open('.instar/config.json')).get('port',4040))" 2>/dev/null || echo 4040)
348
- NG_AUTH=$(python3 -c "import json;print(json.load(open('.instar/config.json')).get('authToken',''))" 2>/dev/null || echo "")
382
+ NG_AUTH=$(resolve_auth_token)
349
383
  jq -nc --arg t "$REPORT_TOPIC" --arg c "$COMPLETION_CONDITION" '{topicId:$t,condition:$c}' \
350
384
  | curl -s -m 8 -H "Authorization: Bearer $NG_AUTH" -H 'Content-Type: application/json' \
351
385
  --data-binary @- "http://localhost:${NG_PORT}/autonomous/native-goal/set" >/dev/null 2>&1 \
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAsGA,OAAO,EAAE,cAAc,EAAwD,MAAM,2BAA2B,CAAC;AAUjH,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AA4BjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAmI7D,OAAO,KAAK,EAAW,oBAAoB,EAAe,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACjG,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAiFtD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC1C,OAAO,CAUT;AA0ID,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAoDD,+EAA+E;AAC/E,wBAAgB,qCAAqC,CACnD,SAAS,EAAE,IAAI,CAAC,OAAO,2BAA2B,EAAE,cAAc,EAAE,QAAQ,CAAC,GAAG,IAAI,EACpF,OAAO,EAAE,MAAM,GACd,IAAI,CAEN;AAsrDD;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,oBAAoB,GAAG,IAAI,GACxC;IACD,YAAY,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IAC3C,QAAQ,EAAE,MAAM,CAAC;CAClB,CAqBA;AAED,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,EAKhG,mBAAmB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,EAQrD,oBAAoB,CAAC,EAAE,MAAM;IAC3B,YAAY,EAAE,OAAO,kBAAkB,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACrE,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IAC3C,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,IAAI,GACP,IAAI,CA8yBN;AAgmBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA4tvBtE;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"}
@@ -17178,6 +17178,26 @@ export async function startServer(options) {
17178
17178
  return resolveToneGateOperatorConfig(live && typeof live === 'object' ? { ...config, toneGate: live } : config);
17179
17179
  });
17180
17180
  console.log(pc.green(' Messaging tone gate: active (Haiku via shared IntelligenceProvider)'));
17181
+ // Jev signal-layer shadow (dark by default; spec
17182
+ // docs/specs/jev-signal-layer-shadow.md). Always constructed so the live
17183
+ // config can switch it on without a restart; it is inert unless enabled,
17184
+ // inside its soak window, and a vault key exists.
17185
+ try {
17186
+ const { buildJevSignalShadow } = await import('../core/JevSignalShadow.js');
17187
+ const { getFeatureMetricsRecorder } = await import('../core/CircuitBreakingIntelligenceProvider.js');
17188
+ const { SecretStore } = await import('../core/SecretStore.js');
17189
+ const shadow = buildJevSignalShadow({
17190
+ readLiveIntelligence: () => liveConfig.get('intelligence', undefined),
17191
+ bootBlock: config.intelligence?.jevSignalShadow,
17192
+ readSecret: (name) => new SecretStore({ stateDir: config.stateDir, forceFileKey: config.secrets?.forceFileKey }).get(name),
17193
+ stateDir: config.stateDir,
17194
+ metrics: { record: (r) => getFeatureMetricsRecorder()?.record(r) },
17195
+ });
17196
+ messagingToneGate.setSignalShadow(shadow);
17197
+ }
17198
+ catch (err) {
17199
+ console.log(pc.yellow(` Jev signal shadow: not constructed (${err?.message ?? 'unknown'})`));
17200
+ }
17181
17201
  }
17182
17202
  else {
17183
17203
  console.log(pc.yellow(' Messaging tone gate: inactive (no IntelligenceProvider available)'));