Install telemetry
ac7 ships with optional install telemetry. Off by default;
opt in via ac7 telemetry enable. The mechanism is designed to
be the most honest possible telemetry: silence by default,
precise when enabled, auditable at every step.
What gets sent
{
schema: 1,
event: "boot" | "directive-complete",
installId: "<22-char base64url, 128 bits of randomness>",
ac7Version: "0.0.4",
nodeVersion: "v22.x",
platform: "linux" | "darwin" | "win32" | ...,
arch: "x64" | "arm64" | ...,
deployMode: "localhost" | "lan" | "public" | "unknown"
}
deployMode is coarse — it answers “is this a developer
running on their laptop, on a LAN box, or behind a public
HTTPS endpoint” without revealing the hostname. No IPs, no
usernames, no objective content, no message content, no team
names, no member names.
Design invariants
- Off by default. ac7’s brand promise is data-local. Telemetry must be opted into explicitly; no implicit activation from any other flow.
- Zero PII. The payload above is the entire payload. Source IP is stripped at the edge.
- Two events max per enable-session. One
bootevent on firstac7 serveboot after enable; onedirective-completeevent on first successful objective completion after enable. No periodic beacon. No call-home-on-every-run. - Full transparency.
ac7 telemetry previewprints the exact bytes that would be sent. No hidden fields. No encoded blob. The source is public (Apache-2.0) and the monthly aggregate rollup is published attelemetry.ac7.dev/rollup/. - Rotatable.
ac7 telemetry rotatemints a fresh install-id at any time without disabling — useful when you want to reset correlation.
Subcommands
ac7 telemetry enable
ac7 telemetry disable
ac7 telemetry preview [--event boot|directive-complete] [--path <state>]
ac7 telemetry rotate
ac7 telemetry status
enable
ac7 telemetry enable
# > ac7 telemetry: enabled.
# > install-id: NX9GE0jBxDA0IDdmqe1qKQ
# > state file: ~/.config/ac7/telemetry.json
# > will send at most 2 events per enable-session (first boot, first directive complete).
# > `ac7 telemetry preview` shows the exact bytes that would be sent.
Mints an install id (or reuses the existing one) and resets the two one-shot send flags. If telemetry was already enabled, this is a no-op apart from the printed status.
disable
ac7 telemetry disable
# > ac7 telemetry: disabled. No further events will be sent.
Flips the enabled flag off. The install id is retained on disk —
re-enabling reuses the same id unless you also rotate. To break
correlation, run rotate after disable.
preview
ac7 telemetry preview --event boot
# > ac7 telemetry: the exact bytes that would be sent for this event:
# >
# > POST https://telemetry.ac7.dev/v1/install
# > Content-Type: application/json
# >
# > {
# > "schema": 1,
# > "event": "boot",
# > "installId": "NX9GE0jBxDA0IDdmqe1qKQ",
# > "ac7Version": "0.0.4",
# > "nodeVersion": "v22.4.0",
# > "platform": "linux",
# > "arch": "x64",
# > "deployMode": "unknown"
# > }
--event accepts boot (default) or directive-complete. No
network call; this is purely a render of what would go on the
wire. Run it before enabling to verify nothing surprising is in
the payload for your environment.
rotate
ac7 telemetry rotate
# > ac7 telemetry: install-id rotated.
# > old: NX9GE0jB...
# > new: ZbYtoJA-r3Ie4g7qbKXzkA
# > server cannot correlate past events to the new id.
Mints a fresh install id and resets the one-shot flags. The previous id is no longer correlatable — useful for periodic rotation, or to reset after sharing your install id while debugging.
status
ac7 telemetry status
# > ac7 telemetry: ENABLED
# > install-id: NX9GE0jBxDA0IDdmqe1qKQ
# > enabled at: 2026-04-15T14:23:45.000Z
# > boot event sent: yes
# > directive event: no
# > state file: ~/.config/ac7/telemetry.json
Read-only summary. Useful for confirming current state at a glance.
State file
Telemetry state lives at:
| OS | Path |
|---|---|
| Linux/BSD | $XDG_CONFIG_HOME/ac7/telemetry.json |
| macOS | ~/Library/Application Support/ac7/telemetry.json |
| Windows | %APPDATA%\ac7\telemetry.json |
Override via $AC7_TELEMETRY_PATH. File mode is 0o600 in a
0o700 directory.
Shape:
{
"enabled": true,
"installId": "NX9GE0jBxDA0IDdmqe1qKQ",
"enabledAt": "2026-04-15T14:23:45.000Z",
"bootEventSent": false,
"missionEventSent": false
}
(missionEventSent is the on-disk name for the directive-complete
flag. Internal naming drift; the wire event field is canonical.)
The two *Sent flags are one-shot per enable-session — once
true, the corresponding event won’t fire again until you
rotate or disable + enable.
Endpoint and overrides
The default upload target is
https://telemetry.ac7.dev/v1/install. Override via
$AC7_TELEMETRY_ENDPOINT — useful for preview in test
environments and for future self-hosted-aggregator scenarios.
The send path uses a 3-second timeout. Telemetry never blocks or errors the operator’s flow — failed sends are silent and the event stays unsent (will retry on the next eligible boot or directive-complete).
When events fire
Note: as of v0.0.4 the send path is exported but not yet wired
into ac7 serve boot or the objective-complete path. The wiring
will land in a follow-up PR; today this command surface lets you
preview the mechanism but no real events fire automatically. The
state file’s one-shot flags are reset by enable / rotate so
they’ll be ready when the wiring lands.
When wiring is complete:
- boot event — fires once on
ac7 serve’s first boot after enable. SetsbootEventSent: true. - directive-complete event — fires once on the first
successful
objectives_completecall after enable. SetsmissionEventSent: true.
What ac7 telemetry deliberately does NOT do
- No periodic heartbeat. Two events per enable-session, max.
- No usage metrics. Not “how many objectives created”, not “how many trace events captured”, not “how many minutes of agent runtime”.
- No identifying info. Not hostname, not username, not IP. Source IP is stripped at the edge before any logging.
- No content. Not chat bodies, not objective titles, not trace contents, not team names.
- No third-party SDKs. A bare
fetch()POST. No Sentry, Mixpanel, Segment, etc. - No silent activation. Every other flow (setup, serve, claude-code, codex) leaves telemetry untouched.
Source of truth
packages/cli/src/commands/telemetry.ts— the entire surfaceTELEMETRY_SCHEMA_VERSION— bump when the payload shape changes; stays in the wire payload asschemaDEFAULT_TELEMETRY_ENDPOINT— the default upload URL
If you don’t want telemetry, do nothing. It’s already off.