installer: the PATH line is the last thing printed, bare and bold green - #1208
Conversation
The installer said 'codeaf: add it to this shell with: export PATH=...' between the install line and 'codeaf version', so the one line a person has to paste sat mid-screen behind a prefix they had to trim. It is now the very last thing the script prints: a blank line, then the bare export line, bold green when stdout is a terminal and NO_COLOR is unset. test/installer-telemetry.sh lifts print_path_hint and pins the shape. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ws too The notice promises "see exactly what leaves: codeaf telemetry show", and two streams leave the binary for AgentField: the anonymous usage counts, and the Model Pool's judged seat scores, which go to codeaf.agentfield.ai under the separate `model_pool` switch. The verb printed only the first, so a person who read it and set CODEAF_TELEMETRY=off believed nothing more would leave while the pool went on sending model slugs and scores. The verb now prints both streams, each under a line naming where it goes or why it is not sent (`off: <ladder rung>` for the counts, `model_pool read, nothing is sent` for the pool), with the pool rows rendered in the outbox's own line shape so the bytes are the bytes the relay receives. It reads the outbox by path and stats first, so a reading form never creates the file. docs/TELEMETRY.md gains a section naming the second stream, its fields, its relay and its switch; the chat manual's telemetry and pool sections say the same, so the corpus no longer reads as though CODEAF_TELEMETRY=off stopped everything. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The notice says "Turn off: CODEAF_TELEMETRY=off" without qualification, and the Model Pool's rows are the other thing this binary sends to AgentField. The switch stopped the usage counts and nothing else: with `model_pool = on`, the default, the pool went on posting model slugs and seat scores. Every rung of the telemetry off ladder now caps the pool at `read` — the pool is still read, the judge still scores into the install's own sheet, nothing is sent — and the cap wins over an explicit `on`, because the notice's line carries no exception. The environment rungs (CODEAF_TELEMETRY off/0/false, DO_NOT_TRACK 1/true) are read inside poolcfg.Resolve through its injected lookup, spelled exactly as internal/telemetry's ladder spells them, so the resolver stays pure and the verb tests that inject an environment stay hermetic. The disk rungs — the project file and the profile row that `codeaf telemetry off` writes — are read by the new config.ModelPoolResolved, the one door every caller now resolves through, and applied with Config.Quieted. The mode's source word for the cap is `telemetry`, which `codeaf pool status` prints as `mode read · telemetry`. docs/TELEMETRY.md, the README and the chat manual say the switch covers both streams; the change entry carries the claim a stale memory would get wrong. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…t line last On a normal run the installer now prints exactly three things: 'installed codeaf v… built … · go… os/arch' (the binary naming itself), a two-line telemetry notice, and the bare export PATH line, bold green, with a blank line above and below. The channel/tag line and the 'codeaf: installed <path>' line move under --verbose on stderr. docs/TELEMETRY.md carries the installer's two-line form beside the full notice the binary still prints at first session, and the shell test reads both back. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…just the spool The notice says "See exactly what leaves: codeaf telemetry show", and a person runs it on the day they install, when nothing is waiting — so it printed two empty arrays, which told them nothing about what would leave the first time they used the program. The verb now prints, for each stream, what a row SAYS: the six every-event props with the values this binary on this machine would send right now, the identity and envelope fields with what each is, what each of the four events adds, the bands, and the never list; for the Model Pool, every field of a row and its meaning, the two identities a batch travels under, and the never list. Then, for each, the rows waiting to leave, or one line saying none are. The field words live in code now — telemetry.PropDoc and record.Fields — so the verb and docs/TELEMETRY.md's table read from one source; the doc test holds the table's third column to PropDoc word for word, and a record test holds Fields to the row's own JSON names. The install id hash is read without minting one: a reading verb on a machine that has sent nothing shows "(minted on the first send)" and leaves no file behind, and a test holds that. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A third line, 'see what is shared: codeaf telemetry show · turn off: CODEAF_TELEMETRY=off', so the install output itself says how to look and how to stop it. docs/TELEMETRY.md and the shell test follow. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…codeaf-install-message-b41040
The telemetry branch moved every outside reader of the pool row from ModelPoolSettingAt to ModelPoolAt / ModelPoolResolved, and the reader law still named the old function, so it failed the row as a dial wired to nothing. The map now names the reader the code has. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The verb printed a field-by-field table with a meaning column and a never line per stream. It prints what a row looks like now: the rows waiting first, then this machine's live every-event values, one example row per event spelled from the contract's own bands, the bands and stop reasons a row can carry, and the pool row in the relay's bytes, wrapped at a key. No never line; the notice and docs/TELEMETRY.md carry the disclaimer. The examples and band lists come from the telemetry package's constants and a test holds them to the allowlist; the pool's example row is marshalled from Row and a test parses it back. The pool Fields table, read by nothing else, is gone. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The example rows carry one of each and docs/TELEMETRY.md spells the rest; the three band lines were text a person does not need there. The band-list helpers, read by nothing else, go with them. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`codeaf telemetry info` takes over the listing — the shape of every row, this machine's live values, one example row per event, the pool row in the relay's bytes — and `codeaf telemetry show` prints only what is waiting to leave, as one JSON object indented by two with a key per destination (usage, model_pool), each carrying destination, an off reason when nothing is sent there, and waiting, the rows themselves. The notice's fifth line and the installer's third now point at `codeaf telemetry info`; the binary, README, docs/TELEMETRY.md and the installer carry the same bytes and their tests hold them together. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The first thing `codeaf telemetry info` says, before either stream, is the one thing a person came to check: codeaf does NOT collect or share your chat, with the never list, then only the fields that do leave. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1. Usage Counts and 2. Model Pool, capitalised alike; no blank line between the last event and the stop reasons; the pool's example row is indented by two, the way show prints a waiting one, instead of wrapped at a key. The wrapper, read by nothing else, goes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Reviewed this on Linux: a real install against the published v0.3.0 (pty, piped, One thing blocks merge:
Two smaller things, not blocking:
Noting for promotion rather than for this PR: a fresh stable install today rejects |
… too The five internal/release tests that asserted a normal run names the channel, tag and platform now ask for --verbose, where those lines moved, and read the receipt on a normal run. A missing release names its tag in the failure line itself, so a person is told which tag was not there without --verbose. The touched-packages gate never ran them for a scripts-only change; that gap is CI's to close separately. poolcfg reads CODEAF_TELEMETRY_ENDPOINT as the third environment rung of the telemetry off switch: set and empty caps the pool at read, as docs/TELEMETRY.md already claimed. And the comment over telemetryRowsOff now says why the legacy AFORGE_TELEMETRY spelling reaches the pool — ProjectBoolAt falls through to TelemetryAt, which reads the pin through internal/env — so nobody drops it by tidying. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…message-b41040 # Conflicts: # docs/GUIDE.md # scripts/install.sh
AbirAbbas
left a comment
There was a problem hiding this comment.
Re-verified 2026-09-21 after the review items were addressed: each item checked in the code and on the built binary, gates green locally and in CI at this head. Details in the review ledger.
Install prints three lines and ends on the
export PATHline.codeaf telemetrygainsinfo;showbecomes JSON. Four groups of change, 14 commits.1. The install one-liner prints three things and nothing else
Real capture, Debian arm64 container:
NO_COLOR.codeaf: stable v0.3.0 for …,codeaf: installed <path>, and thecodeaf: add it to this shell with:prefix.--verbosestill prints the first two, on stderr.PATH, never on Windows),--no-modify-path, the shell-file edit, checksums, channels.2.
codeaf telemetryhas five verbs, was fourinfo(new) opens oncodeaf does NOT collect or share your chat, then1. Usage Countsand2. Model Pool: this machine's live values, one example row per event from the contract's own band constants, and an indented example pool row. Noneverlines inside, no band lists.showis JSON only, indented by two:{"usage": {destination, off?, waiting[]}, "model_pool": {…}}.offappears only when nothing is sent there. Empty queue is[], nevernull.docs/TELEMETRY.mdnow sayWhat is collected: codeaf telemetry info. Tests hold all four copies to the same bytes.codeaf telemetry infoon a fresh stable installcodeaf telemetry showwith one event waiting{ "usage": { "destination": "https://agentfield.ai/api/oss/codeaf/telemetry", "waiting": [ { "event_name": "session_started", "event_id": "8c1f4bd3bf17bad6e701e0ece115288f", "install_id_hash": "cd95afc6…", "session_id_hash": "d6f189b2…", "event_time": "2026-09-19T18:11:32Z", "props": { "arch": "arm64", "channel": "stable", "codeaf_version": "v0.3.0", "install_method": "script", "mode": "chat", "os": "darwin", "resumed": false, "usage_context": "local" } } ] }, "model_pool": { "destination": "https://codeaf.agentfield.ai/pool/v1/rows", "off": "model_pool read (capped by the telemetry off switch)", "waiting": [] } }3. Merged from
claude/codeaf-telemetry-disclaimer-5af1ddcodeaf telemetry showcovers the Model Pool stream, and every telemetry-off switch caps the pool atread.ModelPoolAtfor themodel_poolrow, the reader that branch left it with.4. After review
internal/release's five installer tests asked a normal run for the channel, tag and platform. They ask a--verboserun now, where those lines live, and read the receipt on a normal run. The channel-picking tests still see which release was chosen.A missing release names its tag in the failure line itself:
no codeaf-linux-arm64 in release v9.9.9; check the tag on the Releases page.An empty
CODEAF_TELEMETRY_ENDPOINTcaps the Model Pool atread, asdocs/TELEMETRY.mdalready claimed.poolcfgreads it as the third environment rung, with tests.The comment over
telemetryRowsOffsays why the formerAFORGE_TELEMETRYspelling reaches the pool (ProjectBoolAtfalls through toTelemetryAt, which reads the pin throughinternal/env), so a tidy-up cannot drop it.Merged
devafter a dev build installs beside codeaf as devaf and follows the dev channel #1333 (devaf). The installer keeps its--name/CODEAF_INSTALL_NAMEand the quiet run: the receipt names the installed file'sversion, the notice follows, theexport PATHline is last. a dev build installs beside codeaf as devaf and follows the dev channel #1333's newTestV1InstallerNamereads the receipt and the last line on a normal run and the install path on a--verboserun. The guide and manual say the same.5. Proof
test/installer-telemetry.sh: 46 checks. Notice bytes againstdocs/TELEMETRY.md, the hint's blank lines, no escapes off a terminal,NO_COLOR, the hint call is the script's last line.record.Row,showre-encodes to the same bytes,infoopens on the chat sentence and has noneverline.go test ./internal/release/passes the five installer tests.make pr-ready: green except three macOS-only reds that fail identically on cleanorigin/devand pass on Linux, wheredev's Full check is green:TestC9SourceBuildRefusesBeforeTheNetworkandTestC9AnInstallEndsWithTheNewBinarysVersionLine(/var/foldersvs/private/var/folders), andTestTheReleaseSurfaceTestSurvivesEveryLedgerState(bash 3.2 and an empty array underset -u). Not from this branch.Try it
Installs into a throwaway folder; touches nothing under
~/.codeafor your shell files.Note:
agentfield.ai/get/codeafservesscripts/install.shfrommain, so the public one-liner changes on the next promotion, not on merge todev.🤖 Generated with Claude Code