threadwire 0.1.21 → 0.1.22
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/CHANGELOG.md +103 -0
- package/README.md +5 -3
- package/docs/container-runtime.md +2 -2
- package/docs/development-container.md +45 -47
- package/docs/evidence-artifacts.md +47 -0
- package/package.json +5 -3
- package/scripts/verify-package.js +2 -0
- package/src/cli.js +124 -23
- package/src/evidence-index.js +664 -0
- package/src/evidence-store.js +180 -44
- package/src/isolated-runtime.js +1 -1
- package/src/kimi-model-broker.js +18 -2
- package/src/redaction.js +50 -0
- package/src/run-worker.js +10 -3
- package/src/telegram-ingress/core.js +66 -6
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,109 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
- Fix Node 24 release-prepublish timeouts in `run-worker` process-tree cleanup.
|
|
6
|
+
The dedicated `npm-release` service now runs with Docker's `init: true` so
|
|
7
|
+
terminated descendants are reaped instead of becoming zombies that keep the
|
|
8
|
+
attempt-owned process group alive. Harden the default process-group probe in
|
|
9
|
+
`src/run-worker.js` to treat `EPERM` as "still alive" and only `ESRCH`/`EINVAL`
|
|
10
|
+
as "gone", preventing false settlement when signaling is denied. Add a focused
|
|
11
|
+
regression test that mocks `process.kill` returning `EPERM`.
|
|
12
|
+
|
|
13
|
+
- Allow the Kimi model broker to bind port `0` for both the admin and worker
|
|
14
|
+
listeners and expose the OS-assigned actual ports in the returned config.
|
|
15
|
+
Update `test/kimi-model-broker.test.js` to use this deterministic allocation
|
|
16
|
+
instead of a `freePort()` helper that closed a socket before the broker
|
|
17
|
+
rebound it, eliminating the EADDRINUSE race when `node --test` runs test
|
|
18
|
+
files concurrently. Add a regression test that starts many brokers in
|
|
19
|
+
parallel with port `0` and verifies no duplicate ports are assigned.
|
|
20
|
+
Production defaults (8791/8792) and explicit fixed-port configuration are
|
|
21
|
+
unchanged.
|
|
22
|
+
|
|
23
|
+
- Mount the existing read-only GitHub CLI config into the dedicated
|
|
24
|
+
`npm-release` service at `${DEV_CONTAINER_HOME}/.config/gh` and set
|
|
25
|
+
`GH_CONFIG_DIR`. The `docker/npm-release-entrypoint.sh` entrypoint now runs
|
|
26
|
+
`gh auth setup-git` before forwarding to `npm run release:patch`, initializing
|
|
27
|
+
GitHub CLI's HTTPS credential helper in the writable HOME git config from the
|
|
28
|
+
read-only GH config so the fresh origin/master preflight (`git fetch origin`)
|
|
29
|
+
can authenticate. Fail closed if setup-git fails. The npm publish token remains
|
|
30
|
+
the only release-only credential; no provider runtime, agent context, or
|
|
31
|
+
provider credentials are added to `npm-release`, and `home-init` still
|
|
32
|
+
receives no auth mounts. Update `AGENTS.md`,
|
|
33
|
+
`docs/development-container.md`, and contract tests to match.
|
|
34
|
+
|
|
35
|
+
- Align npm release auth with the fleet standard. Rename
|
|
36
|
+
`NPM_CONFIG_SOURCE_PATH` to `NPM_AUTH_SOURCE_PATH`; the canonical credential
|
|
37
|
+
is `${NPM_AUTH_SOURCE_PATH}/npmrc` and is mounted read-only into the
|
|
38
|
+
dedicated `npm-release` service at `${DEV_CONTAINER_HOME}/.npmrc`. The
|
|
39
|
+
persistent `app` service and profile-free `home-init` never receive the npm
|
|
40
|
+
auth source. Update `.env.example`, `AGENTS.md`,
|
|
41
|
+
`docs/development-container.md`, and tests to match.
|
|
42
|
+
|
|
43
|
+
- Add `release-patch@1.0.3` as a devDependency and a `release:patch` package
|
|
44
|
+
script. `npm run release:patch` is now the only normal publishing path; it
|
|
45
|
+
owns version bump, changelog/tag handling, publish verification, and the
|
|
46
|
+
final `npm publish` step. The dedicated `npm-release` service in
|
|
47
|
+
`compose.dev.yaml` now runs `npm run release:patch` instead of invoking
|
|
48
|
+
`npm publish` directly, and `AGENTS.md` and `docs/development-container.md`
|
|
49
|
+
document the new contract.
|
|
50
|
+
|
|
51
|
+
- Add a dedicated, profile-gated `npm-release` service to `compose.dev.yaml`
|
|
52
|
+
for npm releases. The service mounts the server-held publish token read-only
|
|
53
|
+
at `${DEV_CONTAINER_HOME}/.npmrc`, runs as UID/GID 1000 on the canonical
|
|
54
|
+
checkout, and executes the repository-owned `npm publish` procedure. The
|
|
55
|
+
persistent `app` service no longer mounts the npm auth config, so the token
|
|
56
|
+
is never exposed to workers, scripts, or the long-running development
|
|
57
|
+
container. A new `docker/npm-release-entrypoint.sh` image entrypoint simply
|
|
58
|
+
forwards to the release command without loading auth, agent context, or
|
|
59
|
+
provider discovery links. `AGENTS.md`, `docs/development-container.md`, and
|
|
60
|
+
`.env.example` document the new release-only workflow.
|
|
61
|
+
|
|
62
|
+
- Add a per-run SQLite evidence index using the built-in `node:sqlite` module.
|
|
63
|
+
Every evidence-creating run now writes a private, pending-until-finalized
|
|
64
|
+
`.index` database alongside the canonical raw and result artifacts. The index
|
|
65
|
+
stores a versioned manifest and an ordered event ledger of bounded fixed kinds
|
|
66
|
+
(prompt, provider stdout/stderr, assistant, tool, lifecycle, diagnostic,
|
|
67
|
+
context metrics, provider result) with timestamps, order, and artifact
|
|
68
|
+
references; it does not duplicate arbitrarily large raw chunks and applies the
|
|
69
|
+
same redaction and retention boundaries as the existing `read` surface. Indexes
|
|
70
|
+
use `DELETE` journal mode and atomic rename so crashes leave no published
|
|
71
|
+
database; leftover pending/journal files are reconciled on startup and removed
|
|
72
|
+
with their run when the last artifact is cleaned up.
|
|
73
|
+
- Add `threadwire evidence inspect --handle evidence_<bearer>` with fixed
|
|
74
|
+
selectors only: `--summary`, `--events` (with optional `--kind`, `--after`,
|
|
75
|
+
`--before`, and `--limit`), and `--failures` (with optional `--after` and
|
|
76
|
+
`--limit`). The database path is never exposed, results are byte/event bounded,
|
|
77
|
+
and authorization, expiry, and redaction remain consistent with `threadwire evidence read`.
|
|
78
|
+
`--failures` filters diagnostic errors and finished tool events inside SQLite
|
|
79
|
+
before applying the limit, supports deterministic `--after` pagination, and
|
|
80
|
+
reports `truncated: true` only when additional matching failures exist.
|
|
81
|
+
Telegram ingress creates and finalizes the same per-run index for its evidence runs.
|
|
82
|
+
- Account per-run `.index` bytes against the existing `maxRunBytes` and
|
|
83
|
+
`maxStoreBytes` quotas with bounded per-event reservations and final-size
|
|
84
|
+
settlement. Index growth that would exceed a run or store limit is rejected
|
|
85
|
+
safely, the pending database is never published, and bytes are released when a
|
|
86
|
+
run's last artifact is cleaned up, revoked, or aborted before finalization;
|
|
87
|
+
restart reconciliation reserves bytes for existing ready indexes.
|
|
88
|
+
- Apply the artifact redaction policy to index event metadata: secrets
|
|
89
|
+
configured for `evidence read` are replaced with `[REDACTED]` in persisted and
|
|
90
|
+
returned index summaries, lifecycle/diagnostic strings, and tool detail before
|
|
91
|
+
SQLite storage or inspection output; raw evidence remains the canonical
|
|
92
|
+
unindexed source.
|
|
93
|
+
- Upgrade the checked-in Node runtime target to the Node 24 LTS (Krypton)
|
|
94
|
+
release `v24.19.0`. Update `Dockerfile`, `docker/Dockerfile.dev`,
|
|
95
|
+
`src/isolated-runtime.js`, `docker/test/isolated-runtime-e2e.sh`, tests,
|
|
96
|
+
`AGENTS.md`, `README.md`, and `docs/container-runtime.md`; update
|
|
97
|
+
`@types/node` to `24.13.3` and `engines.node` to `>=24` in `package.json`.
|
|
98
|
+
Archive SHA-256 values for the development image are verified against the
|
|
99
|
+
official Node SHASUMS256.txt.
|
|
100
|
+
|
|
101
|
+
- Standardize the development container on Hermes' shared provider runtime with
|
|
102
|
+
UID/GID-1000-only Codex, OpenCode, and Kimi bootstrap links.
|
|
103
|
+
- Keep the OpenCode data directory (`~/.local/share/opencode`) local to each
|
|
104
|
+
`DEV_HOME_PATH`; share only the `auth.json` file from the provider runtime and
|
|
105
|
+
continue sharing the dedicated `.opencode` plugin-state directory. Update the
|
|
106
|
+
home initializer, entrypoint verification, tests, and guidance to match.
|
|
107
|
+
|
|
5
108
|
- Make the checked-in development container portable and secure for direct
|
|
6
109
|
native Kimi: runtime paths (`DEV_CONTAINER_HOME`, `KIMI_CODE_HOME`) are
|
|
7
110
|
explicit, portable, and absolute instead of hard-coded `/home/dev`; the
|
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ See [Isolated provider runtime](docs/isolated-provider-runtime.md).
|
|
|
24
24
|
|
|
25
25
|
## Run with npx
|
|
26
26
|
|
|
27
|
-
Threadwire requires Node.js
|
|
27
|
+
Threadwire requires Node.js 24 or newer. Run the published CLI without a global
|
|
28
28
|
installation:
|
|
29
29
|
|
|
30
30
|
```sh
|
|
@@ -122,7 +122,9 @@ Provider stdout is decoded as JSONL with a finite 1 MiB UTF-8 byte limit for eac
|
|
|
122
122
|
|
|
123
123
|
For normal `threadwire run` execution, Threadwire stdout is the parent-model admission plane. It emits exactly one versioned terminal `delegated_result` JSON object and no progress records. The envelope contains a bounded, credential-redacted, control-normalized final conclusion when one was produced, structured terminal state and exit code, and the exact bounded provider session handle when available. Its closed schema can also represent concise blocker/decision requests, opaque artifact handles, commit/URL references, and a concise validation summary; current provider adapters do not infer these optional fields from prose. Unknown, nested, wrongly typed, cardinality-invalid, or oversized admission candidates fail closed. See [Delegated-result protocol](docs/delegated-result-protocol.md) for the complete schema, limits, and caller obligations.
|
|
124
124
|
|
|
125
|
-
Scoped evidence artifacts are separate from both files above. Set the trusted operator setting `THREADWIRE_EVIDENCE_ROOT` for standalone runs; Telegram ingress uses its dedicated evidence volume automatically. CLI and ingress runs reserve separate normalized provider-result and raw prompt/provider-stream artifacts; CLI raw evidence also records final context metrics. A raw handle enters a normalized result only after the raw artifact is durable; if raw metrics append or finalization fails, the error remains visible while the completed provider result retains only its independently durable result handle. The result artifact carries a stable delivery identity and authenticated state, and ingress sends that result handle through the same bounded notice queue. Retrieve later with `threadwire evidence read
|
|
125
|
+
Scoped evidence artifacts are separate from both files above. Set the trusted operator setting `THREADWIRE_EVIDENCE_ROOT` for standalone runs; Telegram ingress uses its dedicated evidence volume automatically. CLI and ingress runs reserve separate normalized provider-result and raw prompt/provider-stream artifacts; CLI raw evidence also records final context metrics. A raw handle enters a normalized result only after the raw artifact is durable; if raw metrics append or finalization fails, the error remains visible while the completed provider result retains only its independently durable result handle. The result artifact carries a stable delivery identity and authenticated state, and ingress sends that result handle through the same bounded notice queue. Retrieve later with `threadwire evidence read`, inspect the per-run SQLite index
|
|
126
|
+
with `threadwire evidence inspect`, or use the authenticated `/evidence` Telegram
|
|
127
|
+
command with an explicit bounded selector. See [Evidence artifacts](docs/evidence-artifacts.md) for permissions, delivery states, quotas, retention, recovery, authorization, redaction, privacy, cleanup, and the inspect fixed-selector contract.
|
|
126
128
|
|
|
127
129
|
`threadwire capacity` is a read-only reporting command that probes live account capacity for authenticated Codex (`codex app-server` JSON-RPC `account/rateLimits/read`) and Kimi (`GET https://api.kimi.com/coding/v1/usages` with the installed OAuth credential), normalizes both into one closed short/long-window schema, and prints one deterministic reserve-gated admission selection as a single JSON document. It persists nothing, never prints tokens or account data, takes no session arguments, and does not change `run` provider selection; an external worker ledger consumes the report and owns pinning provider/model/session. See [Capacity admission](docs/capacity-admission.md) for the schema, tie-break, error taxonomy, and security boundary.
|
|
128
130
|
|
|
@@ -139,7 +141,7 @@ The delivery queue has finite defaults of 100 pending notices and 256 KiB of pen
|
|
|
139
141
|
## Development
|
|
140
142
|
|
|
141
143
|
The checked-in development container is the `app` service in `compose.dev.yaml`
|
|
142
|
-
(Ubuntu 26.04 pinned by digest, non-root `1000:1000`, Node
|
|
144
|
+
(Ubuntu 26.04 pinned by digest, non-root `1000:1000`, Node 24 LTS, npm-latest
|
|
143
145
|
coding CLI baseline). Setup, the read-only GitHub CLI and agent-context mount
|
|
144
146
|
contracts, and container commands are documented in [AGENTS.md](AGENTS.md).
|
|
145
147
|
|
|
@@ -19,7 +19,7 @@ force unless `THREADWIRE_MAX_CONCURRENT_WORKERS` is explicitly lowered or raised
|
|
|
19
19
|
|
|
20
20
|
## Build and configure
|
|
21
21
|
|
|
22
|
-
Use Node image `node:
|
|
22
|
+
Use Node image `node:24.19.0-bookworm-slim`. The build derives seed identity
|
|
23
23
|
inside the image from deterministic paths, modes, file contents, symlink targets, and the generated `node_modules`; only `.git` and the identity output itself are excluded. No caller revision argument is accepted. The exact base-image tags are recorded but are not claimed
|
|
24
24
|
immutable. Replace them with registry-verified manifest digests during a release
|
|
25
25
|
only after independently verifying those digests; no digest is invented here.
|
|
@@ -211,7 +211,7 @@ relay also uses UID/GID 10003 with no mounts and no credential environment; the
|
|
|
211
211
|
worker uses
|
|
212
212
|
UID/GID 10002 with only the selected worktree and provider-bound state; the
|
|
213
213
|
root supervisor alone receives the Docker socket. The broker/auth service uses
|
|
214
|
-
Node `
|
|
214
|
+
Node `24.19.0` and exactly `@moonshot-ai/kimi-code@0.34.0` with the checked npm
|
|
215
215
|
integrity and archive SHA-512 in the Dockerfile.
|
|
216
216
|
|
|
217
217
|
Enable the checked-in override with `--profile kimi` only after the OAuth/model
|
|
@@ -15,67 +15,65 @@ All source paths in `.env` are required and have no checked-in host defaults:
|
|
|
15
15
|
- `DEV_CONTAINER_HOME` is the absolute container path where `DEV_HOME_PATH` is
|
|
16
16
|
bind-mounted writable. The Threadwire checkout is expected at
|
|
17
17
|
`${DEV_CONTAINER_HOME}/threadwire`.
|
|
18
|
-
-
|
|
19
|
-
home. It must be a strict descendant of `DEV_CONTAINER_HOME` (for example
|
|
20
|
-
`${DEV_CONTAINER_HOME}/.kimi-code`) so the dev home bind remains the only
|
|
21
|
-
writable home mount. The Kimi auth volume's `credentials`, `config.toml`, and
|
|
22
|
-
`device_id` are mounted beneath this path.
|
|
18
|
+
- Kimi Code uses the standard `${DEV_CONTAINER_HOME}/.kimi-code` home.
|
|
23
19
|
- `GH_CONFIG_SOURCE_PATH` is the GitHub CLI config directory and mounts
|
|
24
20
|
read-only at `${DEV_CONTAINER_HOME}/.config/gh`.
|
|
25
|
-
- `
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
replacement.
|
|
21
|
+
- `NPM_AUTH_SOURCE_PATH` is the server-held npm auth directory. The canonical
|
|
22
|
+
credential is `${NPM_AUTH_SOURCE_PATH}/npmrc`; it is mounted read-only into
|
|
23
|
+
the dedicated `npm-release` service at `${DEV_CONTAINER_HOME}/.npmrc` so
|
|
24
|
+
`npm publish` can authenticate without copying tokens into the checkout,
|
|
25
|
+
image, or writable container state. The persistent `app` service never
|
|
26
|
+
receives this mount.
|
|
27
|
+
- `PROVIDER_RUNTIME_SOURCE_PATH` is Hermes' canonical shared provider runtime,
|
|
28
|
+
mounted at `/opt/hermes-dind-shared/auth/provider-runtime`.
|
|
34
29
|
- `AGENT_CONTEXT_VOLUME` is the name of the external Docker volume that holds
|
|
35
30
|
the immutable agent-context snapshot. It mounts read-only at
|
|
36
31
|
`/opt/agent-context`.
|
|
37
|
-
- `KIMI_AUTH_VOLUME` is the name of the external Docker volume that holds the
|
|
38
|
-
direct Kimi Code auth store.
|
|
39
|
-
- `KIMI_AUTH_VOLUME_SUBPATH` is the directory inside `KIMI_AUTH_VOLUME` that
|
|
40
|
-
contains the Kimi Code CLI home (default `.kimi-code`). The volume root may
|
|
41
|
-
hold other state, so the app mounts `credentials`, `config.toml`, and
|
|
42
|
-
`device_id` from this subpath.
|
|
43
32
|
|
|
44
|
-
Hermes owns the canonical
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
33
|
+
Hermes owns the canonical provider runtime. The UID/GID-1000 initializer links
|
|
34
|
+
`.codex`, `.opencode`, and `.kimi-code` from the development home to matching
|
|
35
|
+
directories under the mounted runtime. The OpenCode data directory
|
|
36
|
+
`~/.local/share/opencode` remains local within `DEV_HOME_PATH`; only its
|
|
37
|
+
`auth.json` file is linked to the shared runtime. It fails closed on
|
|
38
|
+
conflicting paths and never copies credentials or changes host ownership. The
|
|
39
|
+
app sets `CODEX_AUTH_PER_PROJECT_ACCOUNTS=0`, so `oc-codex-multi-auth` uses its
|
|
40
|
+
one global mounted account pool rather than creating per-project credential
|
|
41
|
+
copies.
|
|
48
42
|
|
|
49
|
-
##
|
|
43
|
+
## Provider runtime bootstrap
|
|
50
44
|
|
|
51
|
-
The
|
|
52
|
-
|
|
45
|
+
The profile-free `home-init` service creates the four provider-home symlinks as
|
|
46
|
+
UID/GID 1000 before Docker creates the profiled app container. The app mounts
|
|
47
|
+
the shared runtime read-write so provider login and token refresh can update its
|
|
48
|
+
canonical owner. No development service starts as root or invokes `chown`.
|
|
53
49
|
|
|
54
|
-
|
|
55
|
-
- `${KIMI_AUTH_VOLUME_SUBPATH:-.kimi-code}/config.toml` → `${KIMI_CODE_HOME}/config.toml` read-only
|
|
56
|
-
- `${KIMI_AUTH_VOLUME_SUBPATH:-.kimi-code}/device_id` → `${KIMI_CODE_HOME}/device_id` read-only
|
|
50
|
+
## npm releases
|
|
57
51
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
Interactive Kimi login and refresh use the dedicated `kimi-auth` service, which
|
|
63
|
-
bypasses the normal dev entrypoint:
|
|
52
|
+
Publish releases from the dedicated `npm-release` service. This profile-gated,
|
|
53
|
+
short-lived container is the only place the server-held npm publish token is
|
|
54
|
+
mounted; the persistent `app` service never sees it.
|
|
64
55
|
|
|
65
56
|
```sh
|
|
66
|
-
docker compose -f compose.dev.yaml
|
|
67
|
-
docker compose -f compose.dev.yaml --profile kimi-auth run --rm kimi-auth
|
|
68
|
-
docker compose -f compose.dev.yaml --profile app up --detach
|
|
57
|
+
docker compose -f compose.dev.yaml --profile npm-release run --rm npm-release
|
|
69
58
|
```
|
|
70
59
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
`${
|
|
74
|
-
|
|
75
|
-
`
|
|
76
|
-
`
|
|
77
|
-
|
|
78
|
-
|
|
60
|
+
The service runs `npm run release:patch` as UID/GID `1000` in the canonical
|
|
61
|
+
checkout at `${DEV_CONTAINER_HOME}/threadwire`, with
|
|
62
|
+
`${NPM_AUTH_SOURCE_PATH}/npmrc` bound read-only at
|
|
63
|
+
`${DEV_CONTAINER_HOME}/.npmrc`. It also binds the existing GitHub CLI config
|
|
64
|
+
read-only at `${DEV_CONTAINER_HOME}/.config/gh` and sets
|
|
65
|
+
`GH_CONFIG_DIR: ${DEV_CONTAINER_HOME}/.config/gh`. Before forwarding to
|
|
66
|
+
`npm run release:patch`, the entrypoint runs `gh auth setup-git`, initializing
|
|
67
|
+
GitHub CLI's HTTPS credential helper in the writable HOME git config from the
|
|
68
|
+
read-only GH config so the fresh origin/master preflight (`git fetch origin`)
|
|
69
|
+
can authenticate; it fails closed if setup-git fails. No GitHub token is copied
|
|
70
|
+
and the npm publish token remains release-only. It mounts only the dev home,
|
|
71
|
+
the npmrc file, and the read-only GitHub config; it does not mount agent
|
|
72
|
+
context, Codex, OpenCode, or Kimi credentials. `npm run release:patch` is the
|
|
73
|
+
only normal publishing path and owns the version bump, changelog/tag handling,
|
|
74
|
+
and publish verification; do not run `npm publish` directly. The repository's
|
|
75
|
+
`prepublishOnly` script still runs `npm run all-checks` and `npm run
|
|
76
|
+
verify:package` as the final publish gate.
|
|
79
77
|
|
|
80
78
|
## OpenCode catalog
|
|
81
79
|
|
|
@@ -123,6 +123,53 @@ and their pointer values become `[REDACTED]`; responses state whether they were
|
|
|
123
123
|
redacted or truncated. This finite policy is defense in depth, not
|
|
124
124
|
arbitrary-secret detection.
|
|
125
125
|
|
|
126
|
+
## Per-run SQLite index
|
|
127
|
+
|
|
128
|
+
Every run that creates evidence also builds a private per-run SQLite index using
|
|
129
|
+
the built-in `node:sqlite` module. The index is created in a pending state and
|
|
130
|
+
atomically renamed to a ready `.index` file only after the run's result artifact
|
|
131
|
+
is finalized, so a crash or finalization failure leaves no published database.
|
|
132
|
+
It uses `DELETE` journal mode: transient SQLite sidecars are removed on commit
|
|
133
|
+
and any leftover journal files are reconciled on startup. The index is stored
|
|
134
|
+
alongside the canonical raw and result artifacts and is removed when the run's
|
|
135
|
+
last artifact is cleaned up or revoked.
|
|
136
|
+
|
|
137
|
+
The index stores a versioned manifest (provider, destination, timestamps,
|
|
138
|
+
terminal state) and an ordered event ledger of bounded, fixed kinds: `prompt`,
|
|
139
|
+
`provider_stdout`, `provider_stderr`, `assistant`, `tool`, `lifecycle`,
|
|
140
|
+
`diagnostic`, `context_metrics`, and `provider_result`. It records metadata,
|
|
141
|
+
timestamps, order, and artifact references rather than duplicating arbitrarily
|
|
142
|
+
large raw chunks; the canonical raw evidence remains the source of truth.
|
|
143
|
+
Sensitive material is bounded or omitted consistently with the `read` surface.
|
|
144
|
+
|
|
145
|
+
Inspect the index through the same opaque bearer handle with fixed selectors
|
|
146
|
+
only; the database path is never exposed.
|
|
147
|
+
|
|
148
|
+
```console
|
|
149
|
+
threadwire evidence inspect --handle evidence_<bearer> --summary
|
|
150
|
+
threadwire evidence inspect --handle evidence_<bearer> --events --kind tool --limit 50
|
|
151
|
+
threadwire evidence inspect --handle evidence_<bearer> --failures --limit 20
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
`--summary` returns manifest, totals, and per-kind counts. `--events` supports an
|
|
155
|
+
optional `--kind` filter plus `--after`/`--before` order bounds and `--limit`
|
|
156
|
+
(up to 1000). `--failures` returns diagnostic errors and finished tool events,
|
|
157
|
+
supports `--after` pagination, and reports `truncated: true` only when further
|
|
158
|
+
matching failures exist after the returned page. Filtering happens inside SQLite
|
|
159
|
+
before the result limit, so benign rows never hide later failures.
|
|
160
|
+
|
|
161
|
+
The `.index` file size is counted against the same `maxRunBytes` and
|
|
162
|
+
`maxStoreBytes` quotas as other artifacts; the store reserves a bounded per-event
|
|
163
|
+
allowance during ingestion and settles against the final file size. Index growth
|
|
164
|
+
is rejected safely rather than allowed to exhaust the volume, and the index is
|
|
165
|
+
removed and its quota released when the run's last artifact is cleaned up,
|
|
166
|
+
revoked, or aborted before finalization. All index event metadata is redacted
|
|
167
|
+
with the same artifact redaction policy as `evidence read` before persistence
|
|
168
|
+
and before return, so provider secrets do not leak into the queryable index.
|
|
169
|
+
|
|
170
|
+
All results are byte/event bounded and expire with the artifact. A wrong scope,
|
|
171
|
+
bad selector, missing capability, or expired index reports generic unavailability.
|
|
172
|
+
|
|
126
173
|
## Operations
|
|
127
174
|
|
|
128
175
|
Run `cleanup()` from maintenance and use scoped removal for revocation. Cleanup
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "threadwire",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.22",
|
|
4
4
|
"description": "Stream Codex, Claude, Kimi Code, and OpenCode worker progress to an explicit Telegram destination",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai-agent",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"threadwire-telegram-webhook": "bin/telegram-webhook.js"
|
|
31
31
|
},
|
|
32
32
|
"engines": {
|
|
33
|
-
"node": ">=
|
|
33
|
+
"node": ">=24"
|
|
34
34
|
},
|
|
35
35
|
"repository": {
|
|
36
36
|
"type": "git",
|
|
@@ -55,16 +55,18 @@
|
|
|
55
55
|
"test:container-e2e": "sh docker/test/production-e2e.sh",
|
|
56
56
|
"test:isolated-runtime-e2e": "sh docker/test/isolated-runtime-e2e.sh",
|
|
57
57
|
"typecheck": "tsc --noEmit",
|
|
58
|
+
"release:patch": "release-patch",
|
|
58
59
|
"verify:package": "node scripts/verify-package.js",
|
|
59
60
|
"test:kimi-isolated-runtime-e2e": "sh docker/test/kimi-isolated-runtime-e2e.sh"
|
|
60
61
|
},
|
|
61
62
|
"devDependencies": {
|
|
62
63
|
"@eslint/js": "10.0.1",
|
|
63
|
-
"@types/node": "
|
|
64
|
+
"@types/node": "24.13.3",
|
|
64
65
|
"eslint": "10.0.1",
|
|
65
66
|
"eslint-plugin-jsdoc": "63.0.0",
|
|
66
67
|
"fallow": "3.2.0",
|
|
67
68
|
"globals": "17.0.0",
|
|
69
|
+
"release-patch": "1.0.3",
|
|
68
70
|
"typescript": "6.0.2"
|
|
69
71
|
},
|
|
70
72
|
"license": "AGPL-3.0-only"
|
|
@@ -48,6 +48,7 @@ const EXPECTED_FILES = [
|
|
|
48
48
|
"src/context-budget-metrics.js",
|
|
49
49
|
"src/delegated-result-admission.js",
|
|
50
50
|
"src/docker-api.js",
|
|
51
|
+
"src/evidence-index.js",
|
|
51
52
|
"src/evidence-store.js",
|
|
52
53
|
"src/isolated-runtime-client.js",
|
|
53
54
|
"src/isolated-runtime.js",
|
|
@@ -70,6 +71,7 @@ const EXPECTED_FILES = [
|
|
|
70
71
|
"src/providers/index.js",
|
|
71
72
|
"src/providers/kimi.js",
|
|
72
73
|
"src/providers/opencode.js",
|
|
74
|
+
"src/redaction.js",
|
|
73
75
|
"src/provider-capacity-codex.js",
|
|
74
76
|
"src/provider-capacity-kimi.js",
|
|
75
77
|
"src/provider-capacity.js",
|