ravensight-playtest 0.1.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.
- package/LICENSE +21 -0
- package/README.md +380 -0
- package/addons/ravensight_driver/driver.gd +836 -0
- package/addons/ravensight_driver/export_plugin.gd +51 -0
- package/addons/ravensight_driver/plugin.cfg +7 -0
- package/addons/ravensight_driver/plugin.gd +36 -0
- package/bin/ravensight-playtest.js +31 -0
- package/package.json +45 -0
- package/src/api/README.md +500 -0
- package/src/api/client.js +340 -0
- package/src/api/errors.js +115 -0
- package/src/api/http.js +194 -0
- package/src/api/index.js +107 -0
- package/src/auth/deviceCode.js +79 -0
- package/src/auth/keychain.js +159 -0
- package/src/auth/session.js +128 -0
- package/src/cli.js +335 -0
- package/src/commands/brief.js +303 -0
- package/src/commands/check.js +318 -0
- package/src/commands/fakeCore.js +379 -0
- package/src/commands/init.js +120 -0
- package/src/commands/login.js +90 -0
- package/src/commands/logout.js +70 -0
- package/src/commands/open.js +125 -0
- package/src/commands/profile.js +262 -0
- package/src/commands/resume.js +156 -0
- package/src/commands/run.js +1015 -0
- package/src/commands/upload.js +137 -0
- package/src/config.js +100 -0
- package/src/dashboard.js +97 -0
- package/src/detect.js +77 -0
- package/src/errors.js +44 -0
- package/src/fsutil.js +77 -0
- package/src/godot.js +85 -0
- package/src/packs/index.js +191 -0
- package/src/paths.js +129 -0
- package/src/run/aggregate.js +658 -0
- package/src/run/args.js +111 -0
- package/src/run/context.js +181 -0
- package/src/run/deps.js +184 -0
- package/src/run/drivers/driver.js +183 -0
- package/src/run/drivers/godot-observation.js +138 -0
- package/src/run/drivers/godot-project.js +475 -0
- package/src/run/drivers/godot-rpc.js +225 -0
- package/src/run/drivers/godot.js +587 -0
- package/src/run/drivers/index.js +52 -0
- package/src/run/drivers/web.js +385 -0
- package/src/run/exit.js +21 -0
- package/src/run/heartbeat.js +131 -0
- package/src/run/index.js +31 -0
- package/src/run/json.js +56 -0
- package/src/run/model.js +384 -0
- package/src/run/paths.js +88 -0
- package/src/run/personaLoop.js +871 -0
- package/src/run/profile.js +214 -0
- package/src/run/regenerate.js +149 -0
- package/src/run/repoTools.js +286 -0
- package/src/run/report.js +222 -0
- package/src/run/resume.js +272 -0
- package/src/run/secretScan.js +171 -0
- package/src/run/state.js +198 -0
- package/src/run/synthetic.js +206 -0
- package/src/run/tools.js +344 -0
- package/src/run/transcript.js +93 -0
- package/src/run/usage.js +115 -0
- package/src/state/index.js +105 -0
- package/src/states.js +104 -0
- package/src/ui/index.js +195 -0
- package/src/upload/allowlist.js +116 -0
- package/src/upload/index.js +467 -0
- package/src/upload/queue.js +114 -0
- package/src/version.js +63 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Reality Software Entertainment
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
# ravensight-playtest
|
|
2
|
+
|
|
3
|
+
AI personas play your game, then file a report you can read, mark up and argue
|
|
4
|
+
with. The personas run on your machine, against your build; Ravensight stores
|
|
5
|
+
the reports and renders them.
|
|
6
|
+
|
|
7
|
+
You need a Ravensight account and Node 22 or newer. You do not need an
|
|
8
|
+
Anthropic API key: model calls go through Ravensight under the same token you
|
|
9
|
+
log in with, so there is one credential on your machine and you can revoke it
|
|
10
|
+
from the dashboard.
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
Run it without installing anything:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npx ravensight-playtest login
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Or install it globally:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install -g ravensight-playtest
|
|
24
|
+
ravensight-playtest login
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Nothing is downloaded until you need it. Playwright is an optional dependency,
|
|
28
|
+
so `login`, `check`, `init` and `brief` work without a browser installed;
|
|
29
|
+
`run --driver playwright_web` is what asks for one. `keytar` is optional too,
|
|
30
|
+
which is why a machine with no keychain still installs cleanly.
|
|
31
|
+
|
|
32
|
+
## First run
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
ravensight-playtest login # device code, approved in the browser
|
|
36
|
+
cd path/to/your/game
|
|
37
|
+
ravensight-playtest init --game <gameId> # links this repo
|
|
38
|
+
ravensight-playtest check # confirms the machine and the balance
|
|
39
|
+
ravensight-playtest brief # four questions, two minutes
|
|
40
|
+
ravensight-playtest run # prints the price, asks, then plays
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`login` stores the token in your OS keychain (macOS Keychain, Windows
|
|
44
|
+
Credential Manager, libsecret on Linux). With no keychain available it falls
|
|
45
|
+
back to a file with 0600 permissions under your home directory, and says so.
|
|
46
|
+
In CI, set `RAVENSIGHT_TOKEN` instead and skip `login` entirely.
|
|
47
|
+
|
|
48
|
+
## Commands
|
|
49
|
+
|
|
50
|
+
Eleven commands. Flags below are the ones the code accepts, not the ones the
|
|
51
|
+
prose elsewhere describes; `--help` on any command prints the same list.
|
|
52
|
+
|
|
53
|
+
Every command takes these four:
|
|
54
|
+
|
|
55
|
+
| Flag | Effect |
|
|
56
|
+
|---|---|
|
|
57
|
+
| `--api-url <url>` | Point at another Ravensight deployment. Defaults to `RAVENSIGHT_API_URL`. |
|
|
58
|
+
| `--repo <dir>` | Work in a different directory. |
|
|
59
|
+
| `--json` | Machine readable output, and nothing else on stdout. Stable for CI. |
|
|
60
|
+
| `-y, --yes` | Answer every confirmation with yes. Required for CI, since a prompt with no terminal is treated as no. |
|
|
61
|
+
|
|
62
|
+
### login
|
|
63
|
+
|
|
64
|
+
Device code flow. Prints a code, waits for you to approve it in the dashboard,
|
|
65
|
+
stores the token.
|
|
66
|
+
|
|
67
|
+
| Flag | Effect |
|
|
68
|
+
|---|---|
|
|
69
|
+
| `--no-browser` | Do not try to open a browser. `RAVENSIGHT_NO_BROWSER=1` does the same thing. |
|
|
70
|
+
|
|
71
|
+
The token goes in your OS keychain (macOS Keychain, Windows Credential Manager,
|
|
72
|
+
libsecret on Linux). With no keychain available it falls back to a file with 0600
|
|
73
|
+
permissions under `RAVENSIGHT_HOME`, and says which store it used. In CI, set
|
|
74
|
+
`RAVENSIGHT_TOKEN` and skip `login` entirely.
|
|
75
|
+
|
|
76
|
+
### logout
|
|
77
|
+
|
|
78
|
+
Revokes the token on the server, then forgets it locally. No flags of its own. A
|
|
79
|
+
token from `RAVENSIGHT_TOKEN` is left alone: it is probably a CI secret shared
|
|
80
|
+
with other jobs.
|
|
81
|
+
|
|
82
|
+
### check
|
|
83
|
+
|
|
84
|
+
The doctor. Node version, server reachable, CLI new enough, credential valid and
|
|
85
|
+
which store it came from, game visible, balance against the next job's price,
|
|
86
|
+
content pack verified by sha256, disk, recommended concurrency, and the two
|
|
87
|
+
optional tools. Exit code 3 when any row fails; a missing optional tool is a
|
|
88
|
+
warning and never a failure, so CI does not break on it.
|
|
89
|
+
|
|
90
|
+
Past `--personas` in `POST /jobs`, requesting more than 100 personas or the same
|
|
91
|
+
slug twice is refused with 400 `too_many_personas`, and a slug this game does
|
|
92
|
+
not have is 400 `unknown_persona`; `run` checks the count against the same
|
|
93
|
+
ceiling before it asks the server anything. Past 8 personas the job is still
|
|
94
|
+
allowed, but a warning row explains that the later runs may not get to play
|
|
95
|
+
inside the job's wall clock; any run that does not play is refunded
|
|
96
|
+
automatically. `check` shows that same warning as a row when it applies.
|
|
97
|
+
|
|
98
|
+
| Flag | Effect |
|
|
99
|
+
|---|---|
|
|
100
|
+
| `--game <gameId>` | Check against this game instead of the linked one. |
|
|
101
|
+
| `--modules <list>` | Price this module list, comma separated. |
|
|
102
|
+
| `--personas <list>` | Price this persona list. Without it the balance row prices no personas, so the quote is lower than a real job's. |
|
|
103
|
+
| `--godot-path <path>` | Where Godot is, if it is not on the PATH. |
|
|
104
|
+
|
|
105
|
+
### init
|
|
106
|
+
|
|
107
|
+
Links this repo to a game and writes `.ravensight/config.json`. Refuses a game
|
|
108
|
+
your token cannot see, so the first job does not fail with a 404. Adds
|
|
109
|
+
`.ravensight/jobs/` to an existing `.gitignore`.
|
|
110
|
+
|
|
111
|
+
| Flag | Effect |
|
|
112
|
+
|---|---|
|
|
113
|
+
| `--game <gameId>` | The game to link. With one visible game it is optional. |
|
|
114
|
+
| `--force` | Relink a repo that is already linked. |
|
|
115
|
+
|
|
116
|
+
### brief
|
|
117
|
+
|
|
118
|
+
Writes the expectations brief: your goals, what success looks like, how the game
|
|
119
|
+
is controlled, where a persona starts. Then prints what a job would cost,
|
|
120
|
+
whether your balance covers it, and, past 8 personas, the same wall-clock
|
|
121
|
+
warning `run` shows. A brief is required before `run`; the server answers 409
|
|
122
|
+
`brief_required` without one.
|
|
123
|
+
|
|
124
|
+
| Flag | Effect |
|
|
125
|
+
|---|---|
|
|
126
|
+
| `--show` | Print the current brief and stop. |
|
|
127
|
+
| `--open` | Open the brief form in the dashboard instead of asking here. |
|
|
128
|
+
| `--draft` | Save as a draft even when it looks complete. |
|
|
129
|
+
| `--from <file>` | Read the fields from a JSON file instead of asking. |
|
|
130
|
+
| `--game <gameId>` | The game, when this repo is not linked. |
|
|
131
|
+
| `--modules <list>`, `--personas <list>` | Price this module and persona list in the estimate it prints. |
|
|
132
|
+
|
|
133
|
+
### profile
|
|
134
|
+
|
|
135
|
+
Builds the game profile and the capability report: what your game is, what can
|
|
136
|
+
drive it, what a persona will be able to do. Takes `--game <gameId>` and all the
|
|
137
|
+
run options below.
|
|
138
|
+
|
|
139
|
+
### run
|
|
140
|
+
|
|
141
|
+
Registers a job, plays it, writes the reports, uploads them, finishes the job.
|
|
142
|
+
Prints the price and asks before spending.
|
|
143
|
+
|
|
144
|
+
There is no product limit on how many personas one job can name; an unplayed
|
|
145
|
+
run is refunded automatically when the job settles, so a large job never costs
|
|
146
|
+
more than what actually got played. `--personas` past 100, or the same slug
|
|
147
|
+
twice, is refused before anything is charged, checked locally against the
|
|
148
|
+
content pack so the round trip to the server is never spent finding that out.
|
|
149
|
+
Past 8 personas the job is still allowed; `run` prints a warning above the
|
|
150
|
+
price prompt saying the later runs may not fit inside the job's wall clock, and
|
|
151
|
+
splitting the job in two is what gets everything played.
|
|
152
|
+
|
|
153
|
+
| Flag | Effect |
|
|
154
|
+
|---|---|
|
|
155
|
+
| `--game <gameId>` | The game, when this repo is not linked. |
|
|
156
|
+
| `--personas <list>` | Comma separated persona slugs. Defaults to the pack's set. |
|
|
157
|
+
| `--driver <name>` | `playwright_web` or `godot_driver`. |
|
|
158
|
+
| `--build-url <url>` | The web build to play. |
|
|
159
|
+
| `--godot-project <dir>` | The Godot project directory. |
|
|
160
|
+
| `--cli <command>` | The command that starts a text build. |
|
|
161
|
+
| `--max-actions <n>` | Cap the actions one persona may take. |
|
|
162
|
+
| `--concurrency <n>` | Personas at once. Default 2; `check` recommends a number for this machine. |
|
|
163
|
+
| `--upload-video` | Upload `session.webm` as well as the reports. |
|
|
164
|
+
| `--upload-transcript` | Upload `transcript.jsonl` as well as the reports. |
|
|
165
|
+
| `--dry-upload` | List every file and byte that would be sent, and send nothing. |
|
|
166
|
+
| `--headed`, `--headless` | Show or hide the browser. |
|
|
167
|
+
| `--verbose` | Print each turn. |
|
|
168
|
+
|
|
169
|
+
Four flags are accepted and reported as not applied by this release, rather than
|
|
170
|
+
silently ignored: `--budget-usd` and `--quality` (the budget and the model tier
|
|
171
|
+
are the server's, enforced at the proxy), `--offline-upload` (uploads already
|
|
172
|
+
queue) and `--build-dir` (serve the build and pass `--build-url`).
|
|
173
|
+
|
|
174
|
+
### resume
|
|
175
|
+
|
|
176
|
+
With no job id, lists the jobs this repo has a journal for, newest first. With
|
|
177
|
+
one, keeps finished runs, restarts or replays the rest, and never charges twice:
|
|
178
|
+
the register is replayed under the journal's own idempotency key, which answers
|
|
179
|
+
the stored job without pricing anything.
|
|
180
|
+
|
|
181
|
+
| Flag | Effect |
|
|
182
|
+
|---|---|
|
|
183
|
+
| `--game <gameId>` | The game, when the job journal is missing. |
|
|
184
|
+
| `--status` | Report and stop, without restarting anything. |
|
|
185
|
+
| `--restart-interrupted` | Replay an interrupted run from the start. By default a run that got far enough is finalised from the transcript it already has, which spends no model turns; this forces the replay, which spends the action budget again. |
|
|
186
|
+
|
|
187
|
+
### upload
|
|
188
|
+
|
|
189
|
+
Finishes the uploads a crashed or offline run still owes. Safe to run
|
|
190
|
+
repeatedly: files already sent are skipped by checksum.
|
|
191
|
+
|
|
192
|
+
| Flag | Effect |
|
|
193
|
+
|---|---|
|
|
194
|
+
| `--game <gameId>` | The game, when the job journal is missing. |
|
|
195
|
+
| `--dry-upload` | List what would be sent and send nothing. |
|
|
196
|
+
| `--video` | Include the session video. |
|
|
197
|
+
| `--transcript` | Include the transcript. |
|
|
198
|
+
|
|
199
|
+
### review
|
|
200
|
+
|
|
201
|
+
Opens the post job review form. Your marks on the findings are what tunes the
|
|
202
|
+
personas, so this is the useful half of the loop. Takes `--game <gameId>` and an
|
|
203
|
+
optional job id.
|
|
204
|
+
|
|
205
|
+
### open
|
|
206
|
+
|
|
207
|
+
Opens the dashboard page for a job, or for the game. Takes `--game <gameId>` and
|
|
208
|
+
an optional job id.
|
|
209
|
+
|
|
210
|
+
## Playing a Godot game
|
|
211
|
+
|
|
212
|
+
`--driver godot_driver` launches your own Godot binary against your own project,
|
|
213
|
+
with a small driver addon injected so the persona can read the scene tree and
|
|
214
|
+
send input.
|
|
215
|
+
|
|
216
|
+
**Your project directory is never written to.** The project is copied to a temp
|
|
217
|
+
directory and the addon is injected into the copy, through an `override.cfg` and
|
|
218
|
+
the copy's own `project.godot`. Nothing about the copy is written back. The copy
|
|
219
|
+
excludes `.git` and `node_modules` and is refused above 2 GB, and its temp root
|
|
220
|
+
is `0700`, because a project directory can contain a `.env`.
|
|
221
|
+
|
|
222
|
+
The addon only ever activates deliberately: it needs `--ravensight-driver` on the
|
|
223
|
+
command line or `RAVENSIGHT_DRIVER=1` in the environment, it binds `127.0.0.1`
|
|
224
|
+
and nothing else, it requires a per run token in a `hello` call before it will
|
|
225
|
+
answer any other method, it accepts one client at a time, and it frees itself the
|
|
226
|
+
moment any of that fails. On a release export it is stripped from the build
|
|
227
|
+
unless the preset carries the `ravensight_driver` feature tag.
|
|
228
|
+
|
|
229
|
+
**Headless Godot routes no synthesized mouse or GUI input.** A click on a button
|
|
230
|
+
does nothing under `--headless` and works windowed, and nothing takes keyboard
|
|
231
|
+
focus without a click first. So `--headless` is a smoke test mode, not a playtest
|
|
232
|
+
mode, for anything with a user interface: on a machine with no display, use Xvfb
|
|
233
|
+
and a windowed Godot rather than `--headless`. The driver prints this in the
|
|
234
|
+
run's console log when it launches headless.
|
|
235
|
+
|
|
236
|
+
Video from the Godot driver is a `frames/` sequence at 4 fps rather than a
|
|
237
|
+
container, so stitching needs ffmpeg and ffmpeg stays optional.
|
|
238
|
+
|
|
239
|
+
`docs/godot-driver.md` has the protocol, the method set and the error codes.
|
|
240
|
+
|
|
241
|
+
## What a report has to contain
|
|
242
|
+
|
|
243
|
+
`report.json` is validated against the pack schema before it is sent, and
|
|
244
|
+
`report.md` is linted against the four sections the server expects:
|
|
245
|
+
|
|
246
|
+
- **What worked**
|
|
247
|
+
- **Top issues**
|
|
248
|
+
- **What this run didn't cover**
|
|
249
|
+
- **Suggested next step**
|
|
250
|
+
|
|
251
|
+
A missing section is a lint finding rather than a rejection, so a report is never
|
|
252
|
+
lost to it. The CLI lints locally first and feeds any miss back into one repair
|
|
253
|
+
turn, which costs a model turn; a report written with the four headings from the
|
|
254
|
+
start avoids that.
|
|
255
|
+
|
|
256
|
+
## Exit codes
|
|
257
|
+
|
|
258
|
+
| Code | Meaning |
|
|
259
|
+
|---|---|
|
|
260
|
+
| 0 | Success |
|
|
261
|
+
| 1 | Failure |
|
|
262
|
+
| 2 | Budget exceeded. Partial results were written and uploaded. |
|
|
263
|
+
| 3 | Environment check failed |
|
|
264
|
+
| 4 | Authentication failed |
|
|
265
|
+
| 5 | Model API error after retries |
|
|
266
|
+
| 10 | Canceled |
|
|
267
|
+
|
|
268
|
+
CI can treat 2 as a success with a warning.
|
|
269
|
+
|
|
270
|
+
## Environment variables
|
|
271
|
+
|
|
272
|
+
| Variable | Effect |
|
|
273
|
+
|---|---|
|
|
274
|
+
| `RAVENSIGHT_TOKEN` | Use this token instead of the keychain. The CI path. |
|
|
275
|
+
| `RAVENSIGHT_API_URL` | The API base URL. Defaults to `https://api.ravensight.io`. |
|
|
276
|
+
| `RAVENSIGHT_DASHBOARD_URL` | Where the dashboard is, if it is not derivable from the API URL. |
|
|
277
|
+
| `RAVENSIGHT_GAME_ID` | The game, when there is no linked repo. |
|
|
278
|
+
| `RAVENSIGHT_INGEST_KEY` | The game's ingest key, so a web run can emit its synthetic session into your event stream. `ingest_key` in `.ravensight/config.json` does the same. Without either the run still reports; it just sends no telemetry. |
|
|
279
|
+
| `RAVENSIGHT_GODOT` | Path to the Godot binary. Tried first, then `$GODOT`, then `$GODOT_PATH`, then the PATH, then the platform's usual install locations. `--godot-path` beats all of them. |
|
|
280
|
+
| `RAVENSIGHT_FFMPEG` | Path to ffmpeg. |
|
|
281
|
+
| `RAVENSIGHT_HOME` | Where per user state lives. Defaults to `~/.ravensight-playtest`. |
|
|
282
|
+
| `RAVENSIGHT_CACHE_DIR` | Where the content pack cache lives. Defaults to the OS cache directory. |
|
|
283
|
+
| `RAVENSIGHT_NO_BROWSER` | Set to 1 to never try to open a browser. |
|
|
284
|
+
|
|
285
|
+
## What ends up on disk
|
|
286
|
+
|
|
287
|
+
In your repo:
|
|
288
|
+
|
|
289
|
+
```
|
|
290
|
+
.ravensight/
|
|
291
|
+
config.json the game link and your defaults
|
|
292
|
+
jobs/<jobId>/
|
|
293
|
+
state.json the resumable journal
|
|
294
|
+
upload-queue.jsonl what was uploaded, and what is still owed
|
|
295
|
+
runs/<runId>/
|
|
296
|
+
report.md report.json usage.json
|
|
297
|
+
screenshots/NN-slug.png
|
|
298
|
+
transcript.jsonl only when you opt in
|
|
299
|
+
session.webm only when you opt in
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Add `.ravensight/jobs/` to your `.gitignore`; `init` does it for you when you
|
|
303
|
+
already have one.
|
|
304
|
+
|
|
305
|
+
## What leaves your machine
|
|
306
|
+
|
|
307
|
+
The dashboard has the full answer, artifact by artifact, at
|
|
308
|
+
|
|
309
|
+
```
|
|
310
|
+
https://app.ravensight.io/games/<gameId>/playtest/what-leaves-your-machine
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
which is the page to trust: it is rendered from the server's own allowlist, so
|
|
314
|
+
it cannot drift from what is actually accepted. `ravensight-playtest open` links
|
|
315
|
+
to it. The short version:
|
|
316
|
+
|
|
317
|
+
Uploaded by default: `report.md`, `report.json`, `usage.json`, the aggregate and
|
|
318
|
+
capability reports, and `screenshots/`. Uploaded only when you ask:
|
|
319
|
+
`transcript.jsonl` (`--upload-transcript`) and `session.webm`
|
|
320
|
+
(`--upload-video`). **Source code never, at any path.** The upload allowlist has
|
|
321
|
+
no entry for it, the CLI refuses it locally, and the server refuses anything not
|
|
322
|
+
on its own copy of the list. `src/upload/allowlist.js` is that copy, and a test
|
|
323
|
+
pins it equal to the server's file when a checkout is on the same machine.
|
|
324
|
+
|
|
325
|
+
Findings cite a file and a line range. The source text behind that line is not
|
|
326
|
+
uploaded.
|
|
327
|
+
|
|
328
|
+
Run `upload --dry-upload` or `run --dry-upload` to see the exact file list and
|
|
329
|
+
byte count before anything leaves the machine.
|
|
330
|
+
|
|
331
|
+
Model calls go to Ravensight's proxy rather than to Anthropic, under the token
|
|
332
|
+
you logged in with. No Anthropic key exists on your machine, and the CLI builds
|
|
333
|
+
its client with `apiKey` explicitly null, so an `ANTHROPIC_API_KEY` already in
|
|
334
|
+
your environment is never picked up and never sent anywhere.
|
|
335
|
+
|
|
336
|
+
Before anything is written to a run directory, the transcript and `usage.json`
|
|
337
|
+
are scanned for secrets. A hit is replaced by a line naming the shape that
|
|
338
|
+
matched, never the value.
|
|
339
|
+
|
|
340
|
+
### The 90 day artifacts
|
|
341
|
+
|
|
342
|
+
The session video and the transcript expire after 90 days; everything else lives
|
|
343
|
+
for the life of the game. That is enforced as an S3 object tag rather than as a
|
|
344
|
+
filename rule, because a lifecycle rule can filter on a tag or a key prefix and
|
|
345
|
+
the filename is at the end of the key.
|
|
346
|
+
|
|
347
|
+
The tag is a contract between three parties, and the CLI is one of them: the
|
|
348
|
+
presign response hands back the exact `x-amz-tagging` value that was signed, and
|
|
349
|
+
the CLI sends it **verbatim** on the PUT. Changing it, or dropping it, is a
|
|
350
|
+
`SignatureDoesNotMatch` rather than an untagged object, which is the failure you
|
|
351
|
+
want: an untagged 200 MB video would sit in the bucket forever and nothing would
|
|
352
|
+
say so. The CLI never computes the value itself.
|
|
353
|
+
|
|
354
|
+
## Offline
|
|
355
|
+
|
|
356
|
+
After one online fetch the content pack is cached and verified by sha256, so a
|
|
357
|
+
run works with the network down except for the model calls themselves. Uploads
|
|
358
|
+
and progress reports queue up and flush when the server is reachable again;
|
|
359
|
+
`upload <jobId>` drains them by hand.
|
|
360
|
+
|
|
361
|
+
## Embedding
|
|
362
|
+
|
|
363
|
+
`src/api/README.md` documents the one module other code may import, which is
|
|
364
|
+
also this package's entry point:
|
|
365
|
+
|
|
366
|
+
```js
|
|
367
|
+
import { createClient, packs, uploadRunDir } from 'ravensight-playtest';
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
## Reference
|
|
371
|
+
|
|
372
|
+
| File | What is in it |
|
|
373
|
+
|---|---|
|
|
374
|
+
| `docs/api-contract.md` | Every server route this CLI calls, with the headers it sends and the status codes it handles. The list to check a server change against. |
|
|
375
|
+
| `docs/godot-driver.md` | The Godot driver protocol, its method set, its error codes and its safety rules. |
|
|
376
|
+
| `src/api/README.md` | The module other code may import, and what the runner half expects from it. |
|
|
377
|
+
|
|
378
|
+
## License
|
|
379
|
+
|
|
380
|
+
MIT. Copyright Reality Software Entertainment.
|