Aggregate is not a synonym for anonymous

Small groups, repeated releases, linked dimensions, and retained source data made a harmless-looking summary capable of singling out behavior.

The table contained counts, not people. One row still described one person's action.

Q2F8 aggregated form outcomes by day, step, validation rule, route variant, and locale. Direct identifiers never entered the table. Raw events were scheduled for deletion after aggregation. The result looked like the safe endpoint of the pipeline.

In the synthetic fixture, one route variant had only one session in a particular locale that day. The cell address_lookup_timeout = 1 could be linked to the public test schedule and identify exactly which participant encountered the failure.

The row did not contain a name. Its combination of dimensions singled out an individual in context.

“Aggregate” described a computation. “Anonymous” would be a much stronger conclusion about whether a person could be singled out, linked across records, or have information inferred about them. The former did not guarantee the latter.

Q2F8 stopped treating aggregation as a terminal privacy state. Derived tables gained their own purpose, schema, group thresholds, release model, retention, lineage, and re-identification review. Sometimes the correct output was a coarser table. Sometimes it was no table at all.

Summation preserved rare combinations

The aggregation query grouped by every dimension that might be useful later:

SELECT
  day,
  form_step,
  validation_rule,
  route_variant,
  locale,
  COUNT(*)
FROM form_outcomes
GROUP BY 1, 2, 3, 4, 5;

The count removed row-level event identity. The group key preserved a detailed signature.

If many sessions shared each combination, the table reduced the ability to isolate one. If a combination occurred once, the aggregate cell was effectively an individual fact expressed as a count.

The problem worsened with high-cardinality dimensions. Exact date, narrow location, device model, uncommon locale, experimental route, and rare error together can create unique groups even when each field appears ordinary.

I added a group-size distribution to the build report. The first result showed that most cells contained fewer than five synthetic subjects. The rich cube was primarily a sparse map of individual paths.

Aggregation had compressed storage while retaining specificity.

Three risks made a better review frame

The Article 29 Working Party's 2014 anonymisation opinion provided a useful vocabulary: singling out, linkability, and inference. I used those as engineering questions rather than claiming a formal certification.

Singling out

Can one record or group be isolated as referring to one person or a very small set?

Linkability

Can records within this output, across releases, or against another available dataset be connected to the same person or group?

Inference

Can a value about a person be deduced with meaningful confidence from the remaining attributes and context?

A daily count of one failed rule failed the first question. Releasing daily tables repeatedly could link a stable rare combination over time. Comparing totals before and after a known participant's session could infer the new outcome.

Removing names addressed none of those mechanisms by itself.

The framework made “looks anonymous” less persuasive. A derived output needed analysis against how it would actually be accessed and what other information was available.

The release model changed the risk

An aggregate viewed by one restricted maintenance process is not equivalent to the same table published publicly or exported to many tools.

Q2F8 defined three release contexts:

internal restricted computation
purpose-scoped audit view
exported or broadly shared output

The first could operate on more detailed data under narrow credentials and short retention when the purpose genuinely required it. The audit view exposed reviewed summaries and suppressed risky cells. Broad export required the coarsest result and strongest review, and the experiment avoided it entirely.

Access controls did not make detailed data anonymous. They reduced who could attempt linkage and what auxiliary data was present. The data remained governed and retained accordingly.

This distinction prevented a semantic shortcut. A table could be restricted aggregate data without being labeled anonymous. Policy, access, and deletion continued to apply.

The question was not only “What transformation ran?” It was “To whom is the result available, with which other information, for what purpose, and under what controls?”

Anonymity is contextual enough that the release boundary belongs in the architecture.

I introduced a minimum group threshold before a cell could appear. Cells below it were suppressed or combined into a broader category.

This reduced obvious singling out. It did not guarantee safety.

If every person in a group shares the same sensitive outcome, knowing someone belongs to the group can reveal that outcome even when the group is large. Several overlapping tables can allow suppressed cells to be reconstructed through subtraction. A group of five in a rare locale may still be identifiable when public context names the participants.

The threshold therefore served as one guardrail. Review also examined:

  • Diversity of sensitive outcomes within groups.
  • Availability of the grouping attributes elsewhere.
  • Repeated and overlapping releases.
  • Whether dimensions were stable enough for linkage.
  • Whether the audience could bring auxiliary data.
  • Whether the purpose required those dimensions at all.

For the personal synthetic experiment, group thresholds were chosen conservatively and the output remained internal. I did not claim that a particular number made a dataset legally anonymous.

k can describe one property of grouping. It is not a universal privacy certificate.

Suppression leaked through totals

The first report replaced small cells with suppressed while retaining row and column totals.

address_format: total 18
  current route: 17
  experimental route: suppressed

The suppressed value was obviously one.

Complementary suppression hid additional cells so totals could not reveal the target through subtraction. In some tables, totals themselves were removed or rounded. In others, dimensions were collapsed before counting so risky cells never existed in the output schema.

Repeated releases created another subtraction path. If yesterday's total was 17 and today's was 18 after one known session, the delta revealed the new contribution. The system used broader time windows and delayed finalization rather than publishing continuously updating tiny groups.

These controls reduced utility. A dashboard could not offer every drill-down on demand. That limitation followed the purpose: the decision required a stable trend, not live observation of rare individual outcomes.

Suppression had to be designed across the whole output, not applied to cells as a visual mask.

Dimension minimization beat clever disclosure control

The safest improvement was often removing a dimension.

The original question was whether one validation rule and service delay made a form step difficult. Locale did not affect the decision and left the schema. Exact day became a multi-day evaluation period. Route variant remained only while the experiment compared it. Device detail became a coarse capability class where it was genuinely relevant to rendering.

The revised aggregation was closer to:

evaluationWindow
formStep
ruleCategory
performanceBucket
outcome
count

Fewer dimensions produced larger groups, easier interpretation, and a smaller linkage surface. It also prevented future queries unrelated to the original decision.

Disclosure techniques such as suppression, generalization, and rounding remained useful. They should not justify collecting and grouping every available attribute first.

Minimization at source and in the derived schema removed risk before a release algorithm had to manage it.

The most effective cube was the one that never contained unnecessary axes.

Pseudonyms did not make the source anonymous

Raw events used synthetic subject references separated from profile fixtures. The reference was a pseudonym: it enabled records for the same subject to be linked and could be resolved through controlled mapping.

That reduced direct exposure and supported deletion. It did not make the records anonymous.

The distinction mattered because the aggregation worker had access to pseudonymous rows. It could group across sessions and connect behavior over time. The mapping existed elsewhere, so re-attribution remained possible under controlled conditions.

Q2F8 kept pseudonymous source data under the full event policy: narrow access, short retention, purpose limitation, and erasure. Only a derived output that survived contextual identifiability review could be considered for a different treatment, and even then the project used cautious language.

Hashing an identifier would not change the conclusion. A stable hash remains a linkable token and can be vulnerable to guessing when the input space is known.

Pseudonymization was a useful security and minimization technique. Calling it anonymization would erase the very property—linkability—that made the analytics work.

Lineage kept the source risk visible

The first aggregate table had a name and columns. It did not record which raw definitions, filters, or transformation version produced a cell.

Q2F8 added lineage:

source event definition digests
source admission window
transformation version
filter and exclusion rules
grouping dimensions
suppression and rounding policy
release context
purpose and review date

This allowed a later review to see that one source version had included a higher-precision timestamp or a route dimension since removed. Regenerating under a safer transformation produced a new derived version rather than rewriting history silently.

Lineage also connected deletion. When raw records expired, the system knew which aggregates depended on them and whether their own purpose and retention remained valid. A derived table did not live forever merely because its source was gone.

The output inherited responsibility from its inputs and added new risks through combination. Lineage made both visible.

Even without exported tables, an interactive dashboard can act as a query interface for disclosure.

If a user can filter by many dimensions and observe exact counts, they can compare two nearly identical queries and isolate a contribution. Adding one route, one time range, or one category at a time creates difference attacks against suppressed groups.

The audit screen did not expose arbitrary filtering over protected aggregates. It offered purpose-specific approved views with a fixed dimension set. Query results applied minimum groups and consistent suppression across a release batch. Rate limits and audit identity reduced systematic probing.

Restricted maintainers could request a deeper synthetic reproduction without accessing real payload in the experiment. The general-purpose “explore anything” interface was intentionally absent.

This changed product design. Privacy controls were not only jobs behind the dashboard; they constrained which questions the dashboard could formulate.

A safe stored table can become unsafe through a flexible query surface. Access patterns are part of the release model.

The synthetic evaluation deliberately used a small number of sessions. After applying group thresholds and removing identifying dimensions, several cells disappeared. The resulting aggregate could not compare the experimental route reliably.

The honest conclusion was insufficient population, not permission to lower the threshold until a chart appeared.

I used qualitative task review and operational service timing for the small experiment. A broader future evaluation could define a sufficiently large population and coarser schema before collection.

This was a real loss of analytical capability. The project could not claim statistical patterns it did not have enough observations to support, independently of privacy.

Small groups create both disclosure risk and poor inference. Suppression protected people and prevented the interface from giving visual authority to unstable counts.

Sometimes privacy and analytical honesty point to the same empty cell.

Outliers remained revealing after grouping

An average service latency for a group can conceal the existence of one extreme case. Adding minimum and maximum would reveal it. Percentiles in small groups can approximate individual values. Free-form histograms can create sparse buckets.

Q2F8 chose coarse predeclared performance buckets and minimum group rules. It did not publish raw min/max. A separate operational system could investigate a timeout by request receipt and synthetic reproduction without joining it to a person's form path.

Outlier handling followed purpose. If the decision concerned whether the service violated a reliability budget, a count of timeouts and a broad latency distribution was enough. If it concerned one incident, aggregate analytics was the wrong tool.

This prevented a familiar escalation: add more summary statistics until the aggregate nearly reconstructs the source.

A group result can still expose its most unusual member. Reviewing only direct identifiers misses that risk.

Adding statistical noise can protect aggregate releases under a carefully designed privacy model. I considered it and did not implement a formal differential privacy system.

The personal experiment lacked the scale, expertise, and privacy-budget accounting needed to make that claim responsibly. Randomly perturbing counts without a defined mechanism would reduce accuracy and produce security theater.

Instead, Q2F8 used minimization, coarser groups, suppression, delayed windows, narrow access, and no public export. The audit record stated that these controls reduced risk without certifying anonymity.

This was an important limit. Advanced terminology should not be used as a decorative guarantee. A mathematically strong method requires correct sensitivity analysis, budget composition, threat model, and implementation.

The absence of formal noise made the release less ambitious and the evidence easier to inspect.

Aggregation jobs did not keep raw data by accident

The first pipeline wrote raw rows, generated aggregates, and retained both under unrelated defaults. The existence of the aggregate did not cause the source to leave.

Raw event definitions carried short deadlines. The aggregation job processed only admitted source versions, wrote a lineage receipt, then allowed the normal retention worker to remove raw records. It did not delay raw expiry because a downstream report had failed unless the original purpose explicitly required successful aggregation.

If the aggregate could not be produced before raw expiry, the data was lost and the report showed a gap. Optional analytics did not earn indefinite raw retention through pipeline unreliability.

The aggregate had its own deadline and review. When the decision ended, it left too.

This kept transformation from becoming retention extension. Derived data was a new governed artifact, not a reason to keep both detailed and summarized versions forever.

The aggregate test suite did more than compare expected totals.

It generated populations with unique and rare combinations, repeated releases, overlapping totals, and known auxiliary information. It attempted:

  • Direct unique-cell identification.
  • Difference attacks between related queries.
  • Reconstruction through row and column totals.
  • Linkage of stable rare groups across windows.
  • Inference when all members shared one outcome.
  • Outlier exposure through min, max, or narrow buckets.

The tests were not proof against every motivated attacker. They encoded known failure modes into the release process. A schema diff adding a dimension reran the group-size and reconstruction checks.

Manual review considered what an actual audience could know from public schedules, application state, or other internal tables. Context cannot be generated entirely from the dataset.

The test goal was to falsify casual anonymity claims early.

The audit language changed

The first dashboard labeled derived tables anonymous aggregates. That wording disappeared.

The revised audit surface used precise states:

restricted pseudonymous source
purpose-scoped aggregate
suppressed aggregate view
anonymisation review incomplete
not approved for export

Where the project could not establish that people were no longer identifiable in context, it kept the data under privacy controls. It did not need an anonymity label to justify using a bounded internal aggregate for a declared purpose.

The language reduced pressure to make a binary claim. Risk can be mitigated through access, minimization, retention, and disclosure control even when data remains governed.

Calling something anonymous too early encourages broader access and longer retention—the exact consequences the review should prevent.

The final form outcome view removed locale, exact day, device, route details after the evaluation, and all subject linkage. It used multi-day windows, broad rule categories, coarse performance buckets, and suppression. It stayed inside a restricted purpose view and expired with the decision.

It could answer whether a named validation rule and service delay appeared frequently enough to justify a product change. It could not trace sessions, compare rare subgroups, or support arbitrary future analyses.

That limitation was the designed outcome.

Aggregation helped by reducing row-level detail and supporting a smaller result. It became safer only through the surrounding decisions: fewer dimensions, adequate groups, release controls, lineage, finite retention, and refusal to label a transformation as proof.

A computation is not a conclusion

GROUP BY and COUNT are precise operations. They say nothing by themselves about whether the output identifies or reveals someone.

Anonymisation requires contextual assessment of singling out, linkability, inference, auxiliary information, audience, and future release. Pseudonyms remain linkable. Small cells remain small. Repeated tables can expose differences. Derived data retains a purpose and lifecycle.

Q2F8's lesson was not that aggregates are useless or always personal data. It was that the word aggregate cannot perform the risk analysis.

The system began treating every derived table as a new data product with a schema, release model, controls, and expiration. When evidence was insufficient, it remained governed or was not released.

The count of one had no name. In context, it did not need one to describe one person.

That is why aggregate and anonymous are not interchangeable words.