getculpa 1.0.9 → 1.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 +43 -43
- package/README.md +9 -2
- package/assets/culpa-collector.ps1 +137 -137
- package/assets/culpa-compose.yml +161 -146
- package/assets/launch-culpa.ps1 +415 -415
- package/bin/culpa.js +22 -22
- package/bin/getculpa.js +186 -175
- package/lib/assets.d.mts +2 -2
- package/lib/bootstrap.d.mts +48 -29
- package/lib/bootstrap.mjs +163 -97
- package/lib/dispatch.d.mts +12 -12
- package/lib/dispatch.mjs +66 -59
- package/lib/docker.d.mts +76 -76
- package/lib/docker.mjs +290 -270
- package/lib/doctor.d.mts +29 -29
- package/lib/doctor.mjs +454 -420
- package/lib/fetch.d.mts +17 -17
- package/lib/fetch.mjs +211 -211
- package/lib/install-summary.d.mts +20 -18
- package/lib/install-summary.mjs +184 -156
- package/lib/paths.d.mts +9 -9
- package/lib/paths.mjs +61 -61
- package/lib/preflight.d.mts +45 -45
- package/lib/preflight.mjs +322 -274
- package/lib/provision.d.mts +54 -54
- package/lib/provision.mjs +47 -5
- package/lib/repair.d.mts +21 -21
- package/lib/repair.mjs +7 -7
- package/lib/start.d.mts +50 -44
- package/lib/start.mjs +575 -487
- package/lib/status.d.mts +23 -23
- package/lib/status.mjs +74 -74
- package/lib/stop.d.mts +15 -15
- package/lib/stop.mjs +46 -46
- package/lib/tty.d.mts +18 -18
- package/lib/tty.mjs +58 -58
- package/package.json +1 -1
- package/scripts/install.js +9 -2
- package/scripts/prepack.js +53 -53
package/assets/culpa-compose.yml
CHANGED
|
@@ -1,146 +1,161 @@
|
|
|
1
|
-
# Culpa — release compose file shipped inside the installers (T-087/T-088).
|
|
2
|
-
# Net effect is identical to running the stack from the repository:
|
|
3
|
-
# same services, same container names, same ports, same privacy default.
|
|
4
|
-
# Images are pulled from ghcr.io; a locally built/tagged image with the same
|
|
5
|
-
# name is used when present, which is how these pins were verified before
|
|
6
|
-
# publication.
|
|
7
|
-
#
|
|
8
|
-
# ── RELEASE STATE: v1.0
|
|
9
|
-
# The line above is REWRITTEN BY installers/publish.sh at real-publish time —
|
|
10
|
-
# this file has shipped a hand-edited, wrong publication claim twice, so the
|
|
11
|
-
# claim is now mechanical, never prose. While it reads NOT PUBLISHED, the pins
|
|
12
|
-
# below resolve only against locally built images and this file must not be
|
|
13
|
-
# distributed. v0.11.0 is the CF9-CF12 round (UI alignment fixes, forecast
|
|
14
|
-
# uncertainty-calibration repair + kappa bound + cohort/centring explain,
|
|
15
|
-
# cache coverage flags, relay-mesh W1/W2c groundwork — feature-gated out of
|
|
16
|
-
# shipped binaries) on top of v0.10.0, the CF7/CF8 round (forecast P50-anchor + cache
|
|
17
|
-
# counterfactual math repair, founder UI list U-1..U-8 + P-1, founder
|
|
18
|
-
# palette + card "i" tooltips, native CLI auto-update Option A, QW-1..4
|
|
19
|
-
# container-upgrade guards, CodeRabbit PR#13 triage) on top of v0.9.0.
|
|
20
|
-
# The relay and license-server carry NO changes since v0.9.0 and keep
|
|
21
|
-
# their v0.9.0 images — a version is only claimed where a real diff
|
|
22
|
-
# exists. A signed tag is never rebuilt (D-072), so new contents mean a
|
|
23
|
-
# new version.
|
|
24
|
-
#
|
|
25
|
-
# Once the state line reads PUBLISHED AND SIGNED, verify before you run:
|
|
26
|
-
# cosign verify \
|
|
27
|
-
# --certificate-identity 'info@myaigi.ai' \
|
|
28
|
-
# --certificate-oidc-issuer 'https://github.com/login/oauth' \
|
|
29
|
-
# ghcr.io/myaigidev/culpa-server:v1.0.
|
|
30
|
-
# Repeat for culpa-dashboard. Both must report VERIFIED.
|
|
31
|
-
#
|
|
32
|
-
# If a pull fails with an authentication or "denied" error rather than a
|
|
33
|
-
# missing manifest, the package has not been made public yet — the images
|
|
34
|
-
# exist. Check with:
|
|
35
|
-
# gh api user/packages/container/culpa-server --jq .visibility
|
|
36
|
-
# Do NOT use `docker manifest inspect` with an emptied DOCKER_CONFIG to test
|
|
37
|
-
# this: on Docker Desktop for Windows the daemon authenticates through its own
|
|
38
|
-
# credential store, so that check reports a false PUBLIC.
|
|
39
|
-
|
|
40
|
-
services:
|
|
41
|
-
db:
|
|
42
|
-
image: postgres:16-alpine
|
|
43
|
-
container_name: culpa-db
|
|
44
|
-
environment:
|
|
45
|
-
POSTGRES_USER: culpa
|
|
46
|
-
POSTGRES_PASSWORD: culpa
|
|
47
|
-
POSTGRES_DB: culpa
|
|
48
|
-
volumes:
|
|
49
|
-
- culpa_pgdata:/var/lib/postgresql/data
|
|
50
|
-
healthcheck:
|
|
51
|
-
test: ["CMD-SHELL", "pg_isready -U culpa -d culpa"]
|
|
52
|
-
interval: 2s
|
|
53
|
-
timeout: 2s
|
|
54
|
-
retries: 30
|
|
55
|
-
restart: unless-stopped
|
|
56
|
-
|
|
57
|
-
server:
|
|
58
|
-
image: ghcr.io/myaigidev/culpa-server:v1.0
|
|
59
|
-
container_name: culpa-server
|
|
60
|
-
environment:
|
|
61
|
-
DATABASE_URL: postgres://culpa:culpa@db:5432/culpa
|
|
62
|
-
# full forensic capture is the default (A5); set metadata-only to opt out
|
|
63
|
-
# CF24-T1 (S2): the server binds 127.0.0.1 by DEFAULT
|
|
64
|
-
# (native/culpa-api/src/bind.rs — the binary the image actually runs).
|
|
65
|
-
# Inside a container that is unreachable through the published port, so
|
|
66
|
-
# containers must say 0.0.0.0 explicitly. The host-side `ports:` mapping
|
|
67
|
-
# below binds 127.0.0.1, so nothing OFF THIS MACHINE can reach it —
|
|
68
|
-
# reachable-by-design is always an operator's written choice, never a
|
|
69
|
-
# default.
|
|
70
|
-
#
|
|
71
|
-
# Say precisely what that does and does not cover (CF25, CodeRabbit
|
|
72
|
-
# PR #18): the `ports:` mapping governs HOST exposure only. Because the
|
|
73
|
-
# listener inside the container is 0.0.0.0, any other container attached
|
|
74
|
-
# to this Compose network reaches the server directly on 4545, without
|
|
75
|
-
# traversing the published port at all. That is ordinary Docker
|
|
76
|
-
# networking and it is fine for the services defined here — but adding a
|
|
77
|
-
# container to this network grants it API access, and the port mapping
|
|
78
|
-
# will not stop it.
|
|
79
|
-
CULPA_API_BIND: "0.0.0.0"
|
|
80
|
-
CULPA_PRIVACY_MODE: full
|
|
81
|
-
# T-120: the machine secret encrypting the customer key at rest lives
|
|
82
|
-
# here as a file — a VOLUME, so it survives container recreation
|
|
83
|
-
CULPA_SECRET_DIR: /var/lib/culpa
|
|
84
|
-
# T-M1/T-M2: scan the mounted host logs; live sweep every 5 minutes
|
|
85
|
-
CULPA_SCAN_HOME: /host
|
|
86
|
-
CULPA_SCAN_EVERY_MS: "300000"
|
|
87
|
-
#
|
|
88
|
-
#
|
|
89
|
-
#
|
|
90
|
-
#
|
|
91
|
-
#
|
|
92
|
-
#
|
|
93
|
-
|
|
94
|
-
#
|
|
95
|
-
#
|
|
96
|
-
#
|
|
97
|
-
#
|
|
98
|
-
#
|
|
99
|
-
#
|
|
100
|
-
#
|
|
101
|
-
#
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
#
|
|
105
|
-
#
|
|
106
|
-
#
|
|
107
|
-
#
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
-
|
|
113
|
-
#
|
|
114
|
-
#
|
|
115
|
-
#
|
|
116
|
-
#
|
|
117
|
-
|
|
118
|
-
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
1
|
+
# Culpa — release compose file shipped inside the installers (T-087/T-088).
|
|
2
|
+
# Net effect is identical to running the stack from the repository:
|
|
3
|
+
# same services, same container names, same ports, same privacy default.
|
|
4
|
+
# Images are pulled from ghcr.io; a locally built/tagged image with the same
|
|
5
|
+
# name is used when present, which is how these pins were verified before
|
|
6
|
+
# publication.
|
|
7
|
+
#
|
|
8
|
+
# ── RELEASE STATE: v1.1.0 PUBLISHED AND SIGNED (2026-09-06) ─────────
|
|
9
|
+
# The line above is REWRITTEN BY installers/publish.sh at real-publish time —
|
|
10
|
+
# this file has shipped a hand-edited, wrong publication claim twice, so the
|
|
11
|
+
# claim is now mechanical, never prose. While it reads NOT PUBLISHED, the pins
|
|
12
|
+
# below resolve only against locally built images and this file must not be
|
|
13
|
+
# distributed. v0.11.0 is the CF9-CF12 round (UI alignment fixes, forecast
|
|
14
|
+
# uncertainty-calibration repair + kappa bound + cohort/centring explain,
|
|
15
|
+
# cache coverage flags, relay-mesh W1/W2c groundwork — feature-gated out of
|
|
16
|
+
# shipped binaries) on top of v0.10.0, the CF7/CF8 round (forecast P50-anchor + cache
|
|
17
|
+
# counterfactual math repair, founder UI list U-1..U-8 + P-1, founder
|
|
18
|
+
# palette + card "i" tooltips, native CLI auto-update Option A, QW-1..4
|
|
19
|
+
# container-upgrade guards, CodeRabbit PR#13 triage) on top of v0.9.0.
|
|
20
|
+
# The relay and license-server carry NO changes since v0.9.0 and keep
|
|
21
|
+
# their v0.9.0 images — a version is only claimed where a real diff
|
|
22
|
+
# exists. A signed tag is never rebuilt (D-072), so new contents mean a
|
|
23
|
+
# new version.
|
|
24
|
+
#
|
|
25
|
+
# Once the state line reads PUBLISHED AND SIGNED, verify before you run:
|
|
26
|
+
# cosign verify \
|
|
27
|
+
# --certificate-identity 'info@myaigi.ai' \
|
|
28
|
+
# --certificate-oidc-issuer 'https://github.com/login/oauth' \
|
|
29
|
+
# ghcr.io/myaigidev/culpa-server:v1.0.6
|
|
30
|
+
# Repeat for culpa-dashboard. Both must report VERIFIED.
|
|
31
|
+
#
|
|
32
|
+
# If a pull fails with an authentication or "denied" error rather than a
|
|
33
|
+
# missing manifest, the package has not been made public yet — the images
|
|
34
|
+
# exist. Check with:
|
|
35
|
+
# gh api user/packages/container/culpa-server --jq .visibility
|
|
36
|
+
# Do NOT use `docker manifest inspect` with an emptied DOCKER_CONFIG to test
|
|
37
|
+
# this: on Docker Desktop for Windows the daemon authenticates through its own
|
|
38
|
+
# credential store, so that check reports a false PUBLIC.
|
|
39
|
+
|
|
40
|
+
services:
|
|
41
|
+
db:
|
|
42
|
+
image: postgres:16-alpine
|
|
43
|
+
container_name: culpa-db
|
|
44
|
+
environment:
|
|
45
|
+
POSTGRES_USER: culpa
|
|
46
|
+
POSTGRES_PASSWORD: culpa
|
|
47
|
+
POSTGRES_DB: culpa
|
|
48
|
+
volumes:
|
|
49
|
+
- culpa_pgdata:/var/lib/postgresql/data
|
|
50
|
+
healthcheck:
|
|
51
|
+
test: ["CMD-SHELL", "pg_isready -U culpa -d culpa"]
|
|
52
|
+
interval: 2s
|
|
53
|
+
timeout: 2s
|
|
54
|
+
retries: 30
|
|
55
|
+
restart: unless-stopped
|
|
56
|
+
|
|
57
|
+
server:
|
|
58
|
+
image: ghcr.io/myaigidev/culpa-server:v1.1.0
|
|
59
|
+
container_name: culpa-server
|
|
60
|
+
environment:
|
|
61
|
+
DATABASE_URL: postgres://culpa:culpa@db:5432/culpa
|
|
62
|
+
# full forensic capture is the default (A5); set metadata-only to opt out
|
|
63
|
+
# CF24-T1 (S2): the server binds 127.0.0.1 by DEFAULT
|
|
64
|
+
# (native/culpa-api/src/bind.rs — the binary the image actually runs).
|
|
65
|
+
# Inside a container that is unreachable through the published port, so
|
|
66
|
+
# containers must say 0.0.0.0 explicitly. The host-side `ports:` mapping
|
|
67
|
+
# below binds 127.0.0.1, so nothing OFF THIS MACHINE can reach it —
|
|
68
|
+
# reachable-by-design is always an operator's written choice, never a
|
|
69
|
+
# default.
|
|
70
|
+
#
|
|
71
|
+
# Say precisely what that does and does not cover (CF25, CodeRabbit
|
|
72
|
+
# PR #18): the `ports:` mapping governs HOST exposure only. Because the
|
|
73
|
+
# listener inside the container is 0.0.0.0, any other container attached
|
|
74
|
+
# to this Compose network reaches the server directly on 4545, without
|
|
75
|
+
# traversing the published port at all. That is ordinary Docker
|
|
76
|
+
# networking and it is fine for the services defined here — but adding a
|
|
77
|
+
# container to this network grants it API access, and the port mapping
|
|
78
|
+
# will not stop it.
|
|
79
|
+
CULPA_API_BIND: "0.0.0.0"
|
|
80
|
+
CULPA_PRIVACY_MODE: full
|
|
81
|
+
# T-120: the machine secret encrypting the customer key at rest lives
|
|
82
|
+
# here as a file — a VOLUME, so it survives container recreation
|
|
83
|
+
CULPA_SECRET_DIR: /var/lib/culpa
|
|
84
|
+
# T-M1/T-M2: scan the mounted host logs; live sweep every 5 minutes
|
|
85
|
+
CULPA_SCAN_HOME: /host
|
|
86
|
+
CULPA_SCAN_EVERY_MS: "300000"
|
|
87
|
+
# ISS-V110-18: the local-models route (Ollama, LM Studio, vLLM …) must reach
|
|
88
|
+
# the HOST's runtime — "localhost" inside the container is the container
|
|
89
|
+
# itself, so the shipped default of http://localhost:11434 answered 500 and
|
|
90
|
+
# recorded nothing. Docker Desktop resolves host.docker.internal; the
|
|
91
|
+
# extra_hosts entry below maps it on Linux too. Change the port if your
|
|
92
|
+
# runtime listens elsewhere.
|
|
93
|
+
CULPA_LOCAL_UPSTREAM: http://host.docker.internal:11434
|
|
94
|
+
# LAUNCH CONFIG (founder go, 2026-07-31 — D-041 enforcement flip;
|
|
95
|
+
# gating scope corrected 2026-08-03 by D-055): every customer-facing
|
|
96
|
+
# READ of the customer's own spend data requires a valid entitlement.
|
|
97
|
+
# Capture (ingest, scan, imports) and licensing lifecycle routes (claim,
|
|
98
|
+
# activation, license, checkout, billing-portal, entitlement, terms)
|
|
99
|
+
# are NEVER gated — a licensing failure must never break the
|
|
100
|
+
# customer's production traffic or block them from activating. Fail
|
|
101
|
+
# open ONLY on infrastructure failure (license server unreachable, DB
|
|
102
|
+
# blip, WASM missing), where the cached entitlement stands; an ABSENT
|
|
103
|
+
# or CANCELLED entitlement refuses. Activation: buy → claim in-app (or
|
|
104
|
+
# set CULPA_LICENSE_KEY, or paste the key in the dashboard under
|
|
105
|
+
# Account -> Plan & Billing -> Activate); the license server below is where the app
|
|
106
|
+
# syncs counts-only and refreshes the signed entitlement. Remove the
|
|
107
|
+
# license-server line and nothing ever leaves this machine — paid
|
|
108
|
+
# reads then stay degraded (that is the deal).
|
|
109
|
+
CULPA_TRUST_ENFORCE: "1"
|
|
110
|
+
CULPA_LICENSE_SERVER: https://culpa.fly.dev
|
|
111
|
+
# T-CF4-12 (Culpaflight4 #15) — OPT-IN (Privacy Policy 4.4, founder ruling
|
|
112
|
+
# 2026-09-06): the daily public price-list download is OFF unless you turn
|
|
113
|
+
# it on. It is a DOWNLOAD only — nothing about your usage goes anywhere
|
|
114
|
+
# (D-034) — and the committed snapshot + seeds keep pricing working without
|
|
115
|
+
# it. To pick up new model prices automatically, uncomment the next line:
|
|
116
|
+
# CULPA_PRICING_SYNC: "1"
|
|
117
|
+
ports:
|
|
118
|
+
- "127.0.0.1:4545:4545"
|
|
119
|
+
# ISS-V110-18: makes host.docker.internal resolve on Linux (Docker Desktop
|
|
120
|
+
# already provides it); harmless where it already exists. On native Linux
|
|
121
|
+
# it resolves to the host's Docker gateway, so the local model runtime
|
|
122
|
+
# must listen on that interface, not only on 127.0.0.1 (Ollama:
|
|
123
|
+
# OLLAMA_HOST=0.0.0.0).
|
|
124
|
+
extra_hosts:
|
|
125
|
+
- "host.docker.internal:host-gateway"
|
|
126
|
+
volumes:
|
|
127
|
+
- culpa_data:/var/lib/culpa
|
|
128
|
+
# T-M3 ("+ See a cost"): the host's AI-tool session logs, READ-ONLY —
|
|
129
|
+
# this is what lets the in-dashboard scan see Claude Code/Codex history
|
|
130
|
+
# and keep it live. Only these two dirs, never the whole home.
|
|
131
|
+
# NARROW scope (review M2): only the session-log subdirs — ~/.claude
|
|
132
|
+
# also holds credentials/settings, which the container must never see
|
|
133
|
+
- ${CULPA_HOST_HOME:-${USERPROFILE:-${HOME:-}}}/.claude/projects:/host/.claude/projects:ro
|
|
134
|
+
- ${CULPA_HOST_HOME:-${USERPROFILE:-${HOME:-}}}/.codex/sessions:/host/.codex/sessions:ro
|
|
135
|
+
depends_on:
|
|
136
|
+
db:
|
|
137
|
+
condition: service_healthy
|
|
138
|
+
restart: unless-stopped
|
|
139
|
+
|
|
140
|
+
dashboard:
|
|
141
|
+
# Per-component release (D-087). v1.0.5 is a dashboard + relay release: no
|
|
142
|
+
# server, migration or API change, so culpa-server above deliberately stays
|
|
143
|
+
# at v1.0.3 rather than being re-tagged for a release it has no diff in
|
|
144
|
+
# (D-072: never rebuild a tag that already exists). The example this note
|
|
145
|
+
# used to give was CF14's v0.11.0/v0.11.1 pair, which no longer matches
|
|
146
|
+
# either pin in this file.
|
|
147
|
+
image: ghcr.io/myaigidev/culpa-dashboard:v1.1.0
|
|
148
|
+
container_name: culpa-dashboard
|
|
149
|
+
environment:
|
|
150
|
+
CULPA_API_BASE: http://server:4545
|
|
151
|
+
ports:
|
|
152
|
+
- "127.0.0.1:3000:3000"
|
|
153
|
+
depends_on:
|
|
154
|
+
- server
|
|
155
|
+
restart: unless-stopped
|
|
156
|
+
|
|
157
|
+
volumes:
|
|
158
|
+
culpa_pgdata:
|
|
159
|
+
name: culpa_pgdata
|
|
160
|
+
culpa_data:
|
|
161
|
+
name: culpa_data
|