You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
feat(telemetry): give users explicit journal lifecycle controls #657
Users explicitly manage the lifecycle of project run journals without an automatic retention policy deleting or moving their data.
Scope
Run journals remain project data under aidd_docs/runs/. User-level telemetry reports remain separate under the user configuration directory.
No lifecycle action runs from a hook or in the background. The user chooses when it runs, which age boundary applies, and where an archive goes.
Archive
aidd telemetry archive --before <duration> --to <path> selects older journal files, compresses them into the chosen destination, verifies the archive, then removes only the archived source files.
Archives are not merged into user reports and are not read automatically. They remain recoverable data under the user's control.
Selective deletion
aidd telemetry prune --before <duration> previews the exact journal files that qualify and changes nothing.
aidd telemetry prune --before <duration> --yes deletes only the previewed files. The command states that deletion is irreversible before acting.
Boundaries
No automatic retention or default deletion window.
No shell commands: file selection, compression and deletion must be cross-platform Node behavior.
No change to the user-level telemetry report store.
No change to aidd telemetry off.
No change to aidd telemetry forget, which remains the explicit full-removal command.
No rewriting Git history; project journals are already explicitly git-ignored.
Done When
Archive selects only journal files older than the required --before boundary.
Archive writes to the required --to destination and removes no source until the archive is verified readable.
A failed or partial archive leaves every unverified source file intact and reports what happened.
Prune without --yes previews the exact selection and deletes nothing.
Prune with --yes deletes only that selection.
Path handling, age boundaries and file operations pass on Linux, macOS and Windows.
Existing off, forget, journal reading and report behavior remain unchanged.
Completion Evidence
Cross-platform tests archive and prune a mixed-age journal directory, prove that recent and non-journal files remain untouched, and restore/read an archived journal successfully.
Milestone 14 is scoped to what produces a trustworthy figure in five days: #620 the journal, #646 the switch, #647 the sink, #663 the step boundaries, #629 the figure, #617 the proof it is honest. Plus #658, which ships with them because the published documentation currently promises the opposite of what we are about to release.
This issue is not in that set. It keeps its value and its content; it simply is not what the week is measured on. It returns to the milestone board once the first figure exists.
No milestone is assigned rather than a later one, because where it lands depends on what the first week actually teaches.
One of the three questions is now answered, 2026-08-16
Version control status: decided. The journal is written outside the repository during a session and materialised into aidd_docs/runs/ on commit, and the placement is configurable. Recorded on #620.
That removes the ambiguity this issue opened with, and shrinks the retention problem at the same time: only records that accompany a commit ever enter history, so the growth rate is bounded by commits rather than by turns.
Two questions remain, and they are why this issue stays open.
Retention and rotation. Bounded growth is not no growth. A pruning path that does not require rewriting history still has to exist, and it has to exist before there is anything to prune.
There is also a third question now, raised by the configurability decision: which other properties should be configurable, and what the defaults are. Deliberately left open until the first figure exists and we know which knobs people reach for.
Landed with the sink (#647) and the journal, so this ticket is smaller than it reads:
Retention — day files older than 90 days are pruned, per file so one undeletable file does not spare every older one behind it. The window is measured rather than picked: a mapped request line is 576 bytes, so ~281 KB on a 500-request day and ~25 MB over the whole window.
Schema versioning — both surfaces already carry one. The journal writes schema_version: 2 on its session_start line, once per file, so a reader can tell a file's shape without scanning it. The sink writes sink_schema_version: 1 on every line, and the reader throws UnknownTelemetrySinkSchemaVersionError on anything else rather than guessing.
What remains is the version-control question, which neither delivered: whether aidd_docs/runs/ should be committed, ignored, or partially ignored, and what happens to a journal file when the branch that produced it disappears. The repository's own .gitignore currently excludes aidd_docs/runs/* while tracking marker files - asserted by test - but that is this repository's choice, not a decision the framework makes for a user's project.
Two of the five boxes are closed by #776 (5788ad88). Three were already met before this ticket was picked up — checked against the tree rather than taken from the description, which had gone stale in one place.
A reader given schema_version: 2 behaves predictably and says so. The hook stamps schema_version on every session_start (record.cjs's SCHEMA_VERSION), and the reader dropped it: parseSessionStart never looked at the field. A journal written under a schema whose line shapes had changed was read as if it were this one. The reader now carries the stated schema and refuses one it does not read, and aidd telemetry check gains journal-in-another-schema so the refusal is reported as a version disagreement rather than falling through to "the recorder is declared nowhere" or "none carry a readable session_start" — both false about a file whose header parsed perfectly well.
An additive key does not break a reader, asserted with a fixture. A key the reader has never heard of, under a schema it knows, costs it neither the header nor the boundaries.
Already met
aidd_docs/runs/ is either tracked or ignored by an explicit rule, never by omission. The scope says ".aidd/ is currently neither tracked nor gitignored in this repository". That is no longer true: .gitignore carries .aidd/* with !.aidd/config.json, and aidd_docs/runs/* with !aidd_docs/runs/.gitkeep and !aidd_docs/runs/README.md. git ls-files aidd_docs/runs returns those two files and nothing else.
A rotation path exists that does not require rewriting history, and it is exercised in a test.aidd telemetry forget removes run files by the name listRunFiles() gave them, through deleteRunFile, confined by isBareFileName, with e2e coverage. Nothing being tracked, no history is rewritten.
aidd telemetry disable states what happens to data already written. The command is telemetry off; it states what stays and warns when a tool's own settings file still exports, and forget is the verb that removes.
Worth a rewrite of the scope's first bullet before this closes, so the next reader is not sent to check a fact that changed.
Three policy questions are now answered: project run files are explicitly git-ignored, readers refuse an unknown schema while accepting additive keys, and telemetry off leaves data in place while telemetry forget removes it after a preview.
One outcome remains: no age-based retention or rotation exists for aidd_docs/runs/. forget is intentional full deletion, not retention. Keep this issue for a bounded, project-controlled policy for run-journal files. The sink's 90-day pruning policy should not be copied blindly: the two stores have different purposes and expectations.
changed the title [-]feat(framework): retention, version control status and schema versioning for the journal[/-][+]task(telemetry): bound project run-journal retention[/+]on Sep 23, 2026
Activity
blafourcade commentedon Aug 16, 2026
Out of the week's scope, 2026-08-16
Milestone 14 is scoped to what produces a trustworthy figure in five days: #620 the journal, #646 the switch, #647 the sink, #663 the step boundaries, #629 the figure, #617 the proof it is honest. Plus #658, which ships with them because the published documentation currently promises the opposite of what we are about to release.
This issue is not in that set. It keeps its value and its content; it simply is not what the week is measured on. It returns to the milestone board once the first figure exists.
No milestone is assigned rather than a later one, because where it lands depends on what the first week actually teaches.
blafourcade commentedon Aug 16, 2026
One of the three questions is now answered, 2026-08-16
Version control status: decided. The journal is written outside the repository during a session and materialised into
aidd_docs/runs/on commit, and the placement is configurable. Recorded on #620.That removes the ambiguity this issue opened with, and shrinks the retention problem at the same time: only records that accompany a commit ever enter history, so the growth rate is bounded by commits rather than by turns.
Two questions remain, and they are why this issue stays open.
schema_version: 1and nothing says what a reader does with2. feat(framework): an aidd-telemetry plugin whose hooks journal every session #620's strict key whitelist makes every additive change a breaking one, which is the opposite of what a version field is for.There is also a third question now, raised by the configurability decision: which other properties should be configurable, and what the defaults are. Deliberately left open until the first figure exists and we know which knobs people reach for.
blafourcade commentedon Aug 20, 2026
Two of the three are already delivered
Landed with the sink (#647) and the journal, so this ticket is smaller than it reads:
schema_version: 2on itssession_startline, once per file, so a reader can tell a file's shape without scanning it. The sink writessink_schema_version: 1on every line, and the reader throwsUnknownTelemetrySinkSchemaVersionErroron anything else rather than guessing.What remains is the version-control question, which neither delivered: whether
aidd_docs/runs/should be committed, ignored, or partially ignored, and what happens to a journal file when the branch that produced it disappears. The repository's own.gitignorecurrently excludesaidd_docs/runs/*while tracking marker files - asserted by test - but that is this repository's choice, not a decision the framework makes for a user's project.blafourcade commentedon Sep 5, 2026
Two of the five boxes are closed by #776 (
5788ad88). Three were already met before this ticket was picked up — checked against the tree rather than taken from the description, which had gone stale in one place.Closed by #776
schema_version: 2behaves predictably and says so. The hook stampsschema_versionon everysession_start(record.cjs'sSCHEMA_VERSION), and the reader dropped it:parseSessionStartnever looked at the field. A journal written under a schema whose line shapes had changed was read as if it were this one. The reader now carries the stated schema and refuses one it does not read, andaidd telemetry checkgainsjournal-in-another-schemaso the refusal is reported as a version disagreement rather than falling through to "the recorder is declared nowhere" or "none carry a readable session_start" — both false about a file whose header parsed perfectly well.Already met
aidd_docs/runs/is either tracked or ignored by an explicit rule, never by omission. The scope says ".aidd/is currently neither tracked nor gitignored in this repository". That is no longer true:.gitignorecarries.aidd/*with!.aidd/config.json, andaidd_docs/runs/*with!aidd_docs/runs/.gitkeepand!aidd_docs/runs/README.md.git ls-files aidd_docs/runsreturns those two files and nothing else.aidd telemetry forgetremoves run files by the namelistRunFiles()gave them, throughdeleteRunFile, confined byisBareFileName, with e2e coverage. Nothing being tracked, no history is rewritten.aidd telemetry disablestates what happens to data already written. The command istelemetry off; it states what stays and warns when a tool's own settings file still exports, andforgetis the verb that removes.Worth a rewrite of the scope's first bullet before this closes, so the next reader is not sent to check a fact that changed.
blafourcade commentedon Sep 12, 2026
Three policy questions are now answered: project run files are explicitly git-ignored, readers refuse an unknown schema while accepting additive keys, and
telemetry offleaves data in place whiletelemetry forgetremoves it after a preview.One outcome remains: no age-based retention or rotation exists for
aidd_docs/runs/.forgetis intentional full deletion, not retention. Keep this issue for a bounded, project-controlled policy for run-journal files. The sink's 90-day pruning policy should not be copied blindly: the two stores have different purposes and expectations.[-]feat(framework): retention, version control status and schema versioning for the journal[/-][+]task(telemetry): bound project run-journal retention[/+][-]task(telemetry): bound project run-journal retention[/-][+]feat(telemetry): give users explicit journal lifecycle controls[/+]blafourcade commentedon Oct 15, 2026
Done in #993:
aidd telemetry on/off/status/forgetcover the lifecycle of what is kept.