@evident-ai/runner-cdk 3.4.1-dev.51df4de → 3.4.1-dev.ab61560

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.
@@ -1,14 +1,11 @@
1
1
  #!/usr/bin/env bash
2
2
  #
3
3
  # Re-dial with the identity /run left behind. There is no step that could fetch
4
- # a fresh runner key, so the one from /run is what resumes. Also restarts the
5
- # session-DB replicator /suspend stopped before the snapshot (#812 WI-4):
6
- # litestream does not survive a suspend/resume freeze on this design (Q2)
7
- # /suspend stops it and /resume starts a fresh one, the same pattern already
8
- # proven for the tunnel. The interval credential sync loop (#1868 WI-3) is the
9
- # same story one function over: /suspend stops it too, so a resumed VM that
10
- # never restarted it here would never sync credentials again for the rest of
11
- # its life.
4
+ # a fresh runner key, so the one from /run is what resumes. The CLI delegated by
5
+ # start_tunnel owns the session-DB replicator's post-resume start. The interval
6
+ # credential sync loop (#1868 WI-3) stays here because /suspend stops it too, so
7
+ # a resumed VM that never restarted it here would never sync credentials again
8
+ # for the rest of its life.
12
9
  set -euo pipefail
13
10
 
14
11
  # shellcheck source=./common.sh
@@ -42,13 +39,18 @@ fi
42
39
  read -r runner_key
43
40
  } <"${CONTEXT_FILE}"
44
41
 
42
+ # Restore the id so the resumed CLI can self-report and acknowledge any
43
+ # outstanding recycle request (#1906). Older images may not have this file.
44
+ if [ -s "${MICROVM_ID_FILE}" ]; then
45
+ MICROVM_ID="$(cat "${MICROVM_ID_FILE}")"
46
+ export MICROVM_ID
47
+ fi
48
+
45
49
  # Tolerant, never fatal: a resume that fails costs the user their whole
46
50
  # session, so a broken durable-state config degrades to "no session-DB
47
- # restart" rather than a failed resume (the same Q3 reasoning /run's
48
- # session-DB step follows). start_litestream's own guards (disabled/marker/
49
- # already-running) handle the rest — this needs no logic of its own.
51
+ # replication" rather than a failed resume. The CLI's own guards handle the
52
+ # rest this needs no logic of its own.
50
53
  load_state_config || warn "could not resolve durable-state config; the session DB will not resume replicating"
51
- start_litestream
52
54
  start_credential_sync
53
55
 
54
56
  # Diagnostic-only, unlike /run's gate: a failed resume costs the user their
@@ -52,24 +52,20 @@ regenerate_machine_id
52
52
  # reads it, and left behind for the hooks that flush back to the same prefix.
53
53
  printf '%s\n' "${state_prefix}" >"${STATE_PREFIX_FILE}"
54
54
 
55
- # 3 — start reading the litestream binary NOW so that read overlaps step 4,
56
- # which needs a different binary (node), instead of landing inside step 5, which
57
- # start_opencode has to wait for. Backgrounded and never waited on. Same for the
58
- # aws CLI: step 4's runner-secret fetch is its first-ever invocation in this
59
- # VM's life, and #1997 measured that cold first touch alone blowing the whole
60
- # credential-restore deadline.
55
+ # 3 — start reading the litestream and aws CLI binaries NOW. The reads run in
56
+ # the background and overlap the CLI's own node startup and auth round trip,
57
+ # keeping their cold first touches off the path to the first credential fetch.
61
58
  prewarm_litestream
62
59
  prewarm_aws_cli
63
60
 
64
- # 4 — credential stores, restored before anything that reads them starts. Fatal
65
- # only if persistence itself is unavailable (an unset bucket/prefix, or a broken
66
- # synchroniser bundle) — a VM with no model credentials yet still boots.
67
- restore_credentials
61
+ # 4 — export the durable-state config before anything that reads it. Fatal,
62
+ # because the CLI and the teardown hooks must agree on this runner's state prefix.
63
+ load_state_config || exit 1
68
64
 
69
65
  # 5 — does the runner key in this payload actually authenticate against
70
- # Evident? Checked here, before opencode or the tunnel spend any of this boot's
71
- # SIGTERM budget on a key that cannot work, and before anything has started
72
- # that cleanup would need to tear down. Fatal ONLY on contrary evidence
66
+ # Evident? Checked here, before the tunnel spends any of this boot's time on a key
67
+ # that cannot work, and before anything has started that cleanup would need to
68
+ # tear down. Fatal ONLY on contrary evidence
73
69
  # (check_runner_key's own contract, common.sh): a key the API actively rejects
74
70
  # cannot work regardless, and failing here costs ~5s against the ~10 minutes a
75
71
  # runner that can never connect would otherwise burn before the lifecycle cron
@@ -77,49 +73,18 @@ restore_credentials
77
73
  # it warns and this VM still boots.
78
74
  check_runner_key "${runner_key}" "${api_url}" || exit 1
79
75
 
80
- # 6 — the OpenCode session DB (#812 WI-2), restored before opencode opens it —
81
- # the only place this can happen. Bare, like restore_credentials above:
82
- # restore_session_db never returns non-zero (Q3 — nothing about the session
83
- # DB may ever fail /run), so there is deliberately no `||` here to catch.
84
- restore_session_db
85
- log "session DB restore done ${SECONDS}s into the hook"
86
-
87
- # 7 — integrity-check the restored DB (#1868 WI-4), after the config file
88
- # exists (verify_session_db reads it) and before anything opens the DB —
89
- # the only window in which that's true. The ONE step in this sequence that
90
- # can still fail /run past the runner-key gate: a 34 means the corrupt DB's
91
- # separation/disposal could not be proven safe (see verify_session_db's own
92
- # comment for why that's a deliberate exception to "nothing about the
93
- # session DB may ever fail /run").
94
- verify_session_db || exit 1
95
-
96
- # 8 — apply the overlay before OpenCode resolves its project configuration.
97
- apply_runner_opencode_config
98
-
99
- # 9 — configure git after credentials are restored and before agent shells start.
100
- configure_github_access
101
-
102
- # 10 — opencode. Started here, not at build time: a warm process in the shared
103
- # snapshot would carry its installation id and database into every VM. Not
104
- # waited on: a slow opencode boot is not a reason to fail /run (the tunnel CLI
105
- # auto-starts opencode when it finds none healthy,
106
- # apps/cli/src/commands/ensure-opencode.ts, and the api-worker lifecycle cron
107
- # reclaims a runner that never comes online).
108
- start_opencode
109
-
110
- # 11 — begin replicating the session DB (#812 WI-3), now that opencode has
111
- # opened it and before any work can arrive over the tunnel. Bare, like
112
- # restore_session_db above: start_litestream never returns non-zero (every
113
- # guard inside it is its own `return 0`), so there is nothing here for
114
- # `set -e` to abort on.
115
- start_litestream
116
-
117
- # 11a — the interval credential sync (#1868 WI-3), matching ECS's own
118
- # post-litestream position. Bare for the same reason: every guard inside
119
- # start_credential_sync is its own `return 0`.
76
+ # 6 — the interval credential sync (#1868 WI-3). It stays before the context file
77
+ # is written. Bare: every guard inside start_credential_sync is its own `return 0`.
120
78
  start_credential_sync
121
79
 
122
- # 12 — the first per-VM identity on the wire. The subshell's umask makes the file
80
+ # 7preserve the VM id across suspend/resume. The runtime always supplies it
81
+ # for a /run hook, and the subshell keeps the persisted value protected.
82
+ (
83
+ umask 077
84
+ printf '%s\n' "${MICROVM_ID}" >"${MICROVM_ID_FILE}"
85
+ )
86
+
87
+ # 8 — the first per-VM identity on the wire. The subshell's umask makes the file
123
88
  # unreadable to anyone else from the moment it exists, before the key is in it.
124
89
  (
125
90
  umask 077
@@ -131,6 +96,6 @@ start_credential_sync
131
96
  # attempt cap (apps/cli/src/lib/tunnel/connection.ts), and a control-plane
132
97
  # reclaim pass (the api-worker lifecycle cron) is what decides whether a
133
98
  # runner that never connects gets suspended.
134
- start_tunnel "${runner_key}" "${api_url}" "${tunnel_url}"
99
+ start_tunnel "${runner_key}" "${api_url}" "${tunnel_url}" true true
135
100
 
136
101
  run_succeeded=true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evident-ai/runner-cdk",
3
- "version": "3.4.1-dev.51df4de",
3
+ "version": "3.4.1-dev.ab61560",
4
4
  "description": "Reusable CDK constructs for an Evident agent runner: a single scale-to-zero Fargate runner (task + service + per-agent self-stop role + waker Lambda), or a per-session AWS Lambda MicroVM that boots on demand and suspends between messages. Instantiate once per agent from your own stack.",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",