Useful someday is not a purpose
Q2F8 required every event to support a named decision before collection, turning speculative telemetry from a cheap default into an explicit product proposal.
“We might want to know later” is one of the most expensive sentences in a data system.
It sounds cautious. Storage is cheap, instrumentation is easy, and future questions are hard to predict. Keeping a few extra properties appears to preserve options at almost no immediate cost.
The cost arrives later as obligations without owners.
The event remains in a table after its original feature disappears. Nobody can explain which decision it supports. Retention follows a platform default. A broad export includes it because excluding unknown fields feels risky. A privacy review encounters a property whose meaning lives only in old code. A future analysis treats the value as evidence even though its collection context has changed.
Q2F8 began rejecting “useful someday” as an event purpose. Every proposed signal had to name a current decision, explain why less revealing evidence was insufficient, define the population and interpretation, and set an end for collection or review.
This made the event catalogue smaller. It also made the remaining data much more useful because each record entered with a reason that could be challenged.
Event names described behavior, not purpose
The first synthetic catalogue contained familiar names:
page_viewed
filter_changed
form_started
button_clicked
search_submittedThey described what code observed. They did not explain why the system retained it.
filter_changed could support several unrelated questions. Was a default confusing? Was one filter unused and eligible for removal? Did filter combinations produce slow queries? Was the interface being evaluated for accessibility? Each question needed different properties, populations, and retention.
One generic event encouraged every future analyst to reinterpret the same payload. Adding a context object made it even more flexible and less accountable.
Q2F8 moved purpose outside the name and made it a versioned catalogue field:
event: report_filter_applied v1
decision: determine whether the default date range prevents access to older reports
properties: selectedRangeClass, hadOlderResults
population: synthetic reporting sessions in the evaluation window
reviewDate: 2018-04-30The purpose named a decision rather than “understand filters.” The schema carried only distinctions needed by that decision. A materially different question required a new proposal or definition version.
Names located events. Purposes constrained their interpretation.
A decision made necessity testable
Vague purposes are difficult to refuse because almost any data could help “improve the product.” A named decision allows a necessity test.
For each proposal, I asked:
- What choice will change based on the result?
- What observations distinguish the available choices?
- What is the least revealing form of those observations?
- What result would leave the decision unchanged?
- When will the decision be made or reviewed?
Consider a search event. Recording every raw query could support an open-ended study of what people want. The actual decision might be whether a small set of known filters belongs in navigation. That decision could use categorized query intent or explicit failed-result reasons without retaining the exact text someone entered.
If no result would change a choice, the event was curiosity rather than product evidence. Curiosity is legitimate, but it does not automatically justify collecting behavior from another person.
The decision test also found instrumentation theater. Sometimes a feature had already been chosen and the event existed to make the rollout look measured. If the decision would not be revisited, collection needed a different honest purpose or no event.
Making the downstream action explicit improved both restraint and analysis design.
The hypothesis came before the schema
I had previously started instrumentation by listing properties that might be useful. Q2F8 reversed the order.
A proposal included:
observation
hypothesis
alternative explanations
decision threshold or review method
candidate evidence
known limitationsFor T04P's reporting filter, the hypothesis was that the default date range concealed older results people expected. An alternative explanation was that the report labels were unclear. Evidence needed to distinguish an empty result caused by range from a user merely exploring filters.
This led to narrower events: whether the initial result was empty, whether an older-range option was selected, and whether results then appeared. It did not require user identity, raw query text, cursor movement, or a complete sequence of every filter value.
The catalogue could not verify that the hypothesis was wise. It forced the proposal to expose its causal assumptions. Later review could see that an event supported one interpretation and did not prove intent.
Without the hypothesis, a rich schema invites stories after the fact. With it, the event's limits become part of its definition.
Optional properties became permanent appetite
The early event helper accepted a base event and optional metadata:
track('search_submitted', {
resultCount,
query,
filters,
source,
...context
})Optional properties felt harmless because callers could omit them. In practice, they expanded the maximum sensitivity of every record and made analyses incomparable. One route included raw query text, another normalized it, and a third added a user-provided label through context.
Q2F8 used closed schemas with required meaning. A property entered only when the named decision required it. A caller could not attach extra context for later.
If two routes could not produce a property consistently, the definition either described separate versions or chose a coarser shared value. Optionality represented a genuine state such as “no results,” not uncertainty about whether an integration happened to send data.
The change reduced flexibility and improved interpretability. A query over selectedRangeClass meant the same thing across admitted records. A rejected extra field appeared as an integration error without its value being logged.
Data appetite often enters through optional fields because they avoid API friction. A closed schema moved the friction to the moment when purpose could still be reviewed.
Instrumentation proposals usually compared one event design with another. Q2F8 required alternatives that collected no behavioral event.
For a confusing form step, options included:
- Review labels and errors against the content model.
- Run voluntary usability sessions with explicit context.
- Add a visible help request that the person chooses to send.
- Inspect server validation failures already required for the transaction.
- Measure service latency without associating it with a detailed form trace.
These methods answered different questions. Qualitative observation could reveal why a label confused someone. Operational metrics could show a validation service was slow. A help action could identify explicit need without inferring uncertainty from pauses.
The proposal documented why the selected evidence fit the decision and what it could not establish. Sometimes the best result combined a narrow aggregate with conversation. Sometimes existing operational data was enough.
Treating non-collection as a first-class alternative prevented analytics from becoming the default tool merely because the infrastructure existed.
The event catalogue recorded rejected proposals and chosen alternatives so the same invasive idea did not return later under a new name.
Requiring a purpose field can create better prose without changing behavior. “Improve checkout conversion by understanding user friction” sounds specific while authorizing almost any interaction trace.
Q2F8 reviewed purposes against several failure patterns:
No decision
“Understand engagement” describes a topic, not an action that evidence can change.
Unlimited population
“Measure whether new users find the filter” does not justify collecting from every established user indefinitely.
Unlimited time
“Evaluate the new design” needs an evaluation window or review date.
Unbounded evidence
“Find points of friction” does not explain why raw input or high-resolution behavioral sequences are necessary.
Purpose laundering
“Security” or “essential” cannot be attached to optional product analytics to escape the normal policy path.
A valid purpose named decision, scope, evidence, owner label, and review. It remained contestable. The system could require structure; it could not determine ethical proportionality automatically.
The catalogue therefore displayed purpose beside schema and retention. A persuasive sentence could not hide a broad implementation.
Collection had a planned ending
If an event supported a finite decision, collection did not need to continue forever.
Definitions included an activation window and review date. At review, the event could:
retire because the decision is complete
continue under a newly justified window
change under a new version and purpose
move to a lower-volume operational sample
remain required for an ongoing, named functionExpiration did not delete existing records automatically; their own retention deadlines controlled that. It stopped new admission for the retired definition and marked client helpers deprecated.
This reduced zombie telemetry. An experiment could not become permanent because nobody remembered to remove its call. The server gate rejected events after the admission window even if a stale client continued sending them.
Ongoing purposes were possible. A reliability metric might support continuous service operation. It still needed a named function, bounded schema, retention, and periodic review.
Time turned “we need this now” into a claim that would be reconsidered rather than a permanent grant.
Ownership was a maintenance obligation
The catalogue's owner field initially contained a name label. It became stale quickly and implied responsibility without defining it.
Q2F8 defined ownership through duties:
- Review whether the purpose remains active.
- Respond to schema and rejection findings.
- Verify retention and deletion evidence.
- Interpret results within documented limitations.
- Retire the event when the decision ends.
In the personal project, the owner was usually me, so labels alone added little. The useful part was a review queue attached to the event. If I could not commit to those duties, the system should not accumulate the data.
The audit screen showed definitions past review date, events with no recent query or decision note, and retention failures. Ownership became visible work, not metadata decoration.
This also exposed the cost of speculative collection. Every “maybe useful” event created future review, security, deletion, and interpretation work even if nobody ever analyzed it.
Cheap ingestion can produce expensive stewardship.
Query use did not retroactively justify collection
One argument for broad collection is that future use will reveal value. If an analyst later finds an interesting correlation, the data must have been worth retaining.
That reasoning reverses accountability. Almost any sufficiently rich dataset can produce a story. Later usefulness does not prove the original collection was necessary or the interpretation valid.
Q2F8 linked analyses back to the event purpose. A query outside that purpose required a new compatibility review rather than becoming automatically acceptable because the fields were available. Synthetic experiments could explore broader ideas without using retained personal behavior.
The audit view recorded which decision notes referenced an event. An unused event was a removal candidate. A heavily queried event under unrelated purposes was a warning, not a success metric.
This protected against function creep in the small system. Data did not acquire new permissions merely by becoming convenient.
Purpose remained attached to collection and use across time.
Summaries can appear safer and more reusable than raw events. A derived table such as “engagement score” combines several signals and hides their origins behind one number.
Q2F8 required derived data to name source definitions, transformation version, purpose, population, retention, and access. The output did not escape review merely because it was aggregate or calculated.
For the reporting-filter experiment, a daily count by range class and result outcome supported the decision. It did not need a per-subject score or indefinite history. The aggregation job removed raw records on their shorter schedule and retained only the bounded summary while the evaluation remained active.
If source purpose ended, the derived output was reviewed too. A table cannot remain “useful someday” after its inputs retire without a new justification.
Lineage made interpretation more reliable. A later reader could see which versions and exclusions produced the measure instead of treating its column name as truth.
Purpose limitation applied to transformations as architecture, not only to the first tracking call.
Absence became a maintained decision
Rejected instrumentation normally leaves no artifact. Months later, the same proposal can return because nobody remembers the reasoning.
Q2F8 added a non-collection register:
proposed signal
decision it intended to support
revealing properties or risks
less revealing alternatives
chosen evidence
conditions for reconsideration
date and reviewThe register was not a graveyard of ideas. It preserved architectural intent. A code review could link to the decision when rejecting a new raw query property. A future product change could see what new condition would justify reconsideration.
The absence also became testable. With the relevant preference enabled, the client still did not emit the rejected event. The collection catalogue contained no admissible definition. A handcrafted request failed as unknown.
Non-collection was protected at source and server. This prevented a deleted tracking call from returning through another integration without review.
Choosing not to know something can be an engineering decision worthy of maintenance.
A purpose catalogue improved analysis
The restrictions did not merely reduce risk. They reduced ambiguity in the data that remained.
Closed schemas meant properties had consistent meaning. Named populations prevented comparisons across incompatible contexts. Versioned definitions made product changes visible. Review windows explained why a series began and ended. Decision notes recorded expected interpretations and alternatives.
An analysis could say:
During the four-week evaluation of the default report range,
under event definition v1 and synthetic test population,
empty initial results were followed by older-range selection
in the observed scenarios.It could not claim that people were confused without qualitative evidence. The data contract made that limit clear.
Broad telemetry often looks powerful because it can answer many queries. It also permits many incompatible stories. Narrow purposeful telemetry can produce fewer conclusions with stronger lineage.
Restraint and analytical quality were not opposites.
Client code could stop sending an event after its review window. A stale bundle might not.
The event definition carried admitUntil. The collection gate rejected the version after that server time unless a new immutable definition extended the purpose. The response told the integration that the event had retired and should be removed.
This separated source cleanup from policy enforcement. Removing calls reduced waste. Server expiry ensured forgotten calls did not keep data flowing.
The audit screen listed retired definitions still receiving attempts. That was migration debt, not permission to reopen collection. The payload values were not logged.
Admission expiry mirrored retention deadlines on stored records. One controlled when new obligations could begin; the other controlled when existing obligations ended.
Purpose therefore had an executable temporal boundary on both sides of storage.
Several proposals failed review in the first months:
- Raw search text for a navigation question that categories could answer.
- Hover duration intended to infer interest.
- A general
contextobject for future debugging. - Detailed cursor movement on a form.
- Indefinite page-view history after the related redesign decision ended.
Rejecting them did not mean no evidence was gathered. Operational timings, explicit help actions, categorized outcomes, accessibility review, and voluntary observation covered the actual questions more appropriately.
The catalogue became smaller than the application event surface and more aligned with decisions that existed.
This also made the server gate understandable. A small versioned set of known events could be reviewed, tested, retained, and deleted. A universal event envelope would turn the gate into a type checker for unrestricted appetite.
The ability to refuse a schema was part of the architecture's capacity.
The question preceded the capability
Modern applications make behavioral collection technically easy. One helper can record every click. Session replay can preserve far more. Storage and query systems encourage collecting first because future computation feels cheaper than future reinstrumentation.
Q2F8 imposed the opposite order:
name the decision
-> state the hypothesis and alternatives
-> choose the least revealing evidence
-> define closed schema and population
-> set admission and retention windows
-> activate through the server policy gate
-> review and retireThe sequence made some future questions impossible to answer from stored behavior. That was an explicit tradeoff, not a defect to hide.
A system capable of retaining everything still needs a reason to retain this thing. “Useful someday” avoids that reasoning by transferring the decision to an unknown future person while the present system accepts all the risk and maintenance.
Purpose is not the event name, a paragraph in a catalogue, or a consent category. It is a specific relationship between evidence and a decision, bounded by scope and time.
Once that relationship ends, the collection should end with it.