TIER docs

Legal & Privacy: Deploying TIER Where Per-Developer Measurement Is Regulated

Evaluation mode (operator choice)

Team reports are name-free and need at least k people (default 5, minimum 3). An operator can turn on evaluation mode to see small rows themselves while setting up; shared viewers never see them. This operator choice amends #185. k guards against accidental disclosure to viewers; it does not stop an admin inventing names. See Privacy for setup, the viewer rule, labels, and the prohibition on sealing small rows. Turn evaluation mode off and set k_anonymity to 3 or more (default 5) to share team reports. While k is below 3, shared viewers see team rows of 3 or more people.

v0.7.0 organizations: Use the credential scope map for current administration and report access. This guide remains separate from the data inventory and trust limits.

⚠️ This document is not legal advice. It is deployment and positioning guidance written by engineers, not lawyers. Employment law, works-council obligations, and data-protection rules vary by country, by industry, and over time, and they turn on facts specific to your organization. Before deploying TIER in a way that measures named individuals, consult your own legal counsel, your Data Protection Officer (DPO), and — where one exists — your works council or employee representative body. Nothing here creates a compliance guarantee.

Why this document exists

TIER attributes AI token spend to outcomes. In v0.7.0, named coaching cards are available on real data with serve --aggregation developer when a nonempty admin API token, a nonblank --admin-viewer operator identifier and at least one active permitted viewer credential are configured. This may be a legacy subject-bound viewer credential or an eligible personal/node key for a current, mapped person. Each card also requires positive verified spend in its window and either a configured subject viewer credential or a live declared-viewer check, under the declaration and view-log rules. Declared-viewer card opens require a writable server; every card open must commit its view log before the card is built. TIER is built for coaching, not for evaluating developers. Per-person figures are not accurate enough to judge an individual. In several of TIER's target markets, measuring the performance of named employees is legally constrained — sometimes requiring prior co-determination or works-council agreement, sometimes restricted outright under data-protection law. Adopters need to understand that exposure before their legal and HR review, not after.

This guide covers: what TIER actually measures and stores; the EU labor-law exposure of per-developer measurement; TIER's posture under GDPR Article 22 (automated profiling); when a Data Protection Impact Assessment (DPIA) is indicated; the works-council consultation prerequisites; and a jurisdiction-by-jurisdiction decision table for choosing a deployment mode.

TIER's stance, in writing

TIER is built for coaching, not for evaluating developers. Per-person figures are not accurate enough to judge an individual. TIER sets weighted merged work beside captured AI usage for coaching conversations; its positioning is grade the work, not the worker, by policy rather than by mechanism. Team reporting and access controls reduce disclosure but do not validate individual figures.

Two independent reasons make this the right posture:

  1. Legal. In co-determined jurisdictions (below), using a measurement system as an input to individual appraisal is precisely the use that triggers the heaviest obligations, and can be unlawful without prior agreement.
  2. Methodological. Per-developer TIER is easily distorted — by task mix, pairing, seniority, review load, and the incentive to game any number that is tied to a person's evaluation. TIER measures spend efficiency of a body of work, which is a team-and-portfolio property, not a fair proxy for individual worth.

The per-developer view is for coaching (a developer and their manager looking at how that person works with AI) and for engineering diagnosis (for example, "which spend is missing an issue reference?"). Make organizational decisions from team-level numbers.

What developer mode is (v0.7.0). It is a coaching view that a developer and their permitted viewers read together, seeing the same numbers. A tool that shows named people's numbers can be used to monitor individual performance, whatever you intend, so the rest of this document applies to it in full. TIER is built for coaching, not for evaluating developers. Per-person figures are not accurate enough to judge an individual. TIER cannot enforce that stance. It shows numbers; it cannot stop someone from copying one into a review. Only your written policy, or a works agreement where one applies, can.

Access and retention controls. Developer mode on real data requires a nonempty operator API token, a named audited operator and at least one active permitted viewer credential. The developer, their declared manager, optional skip-level manager and declared works-council viewers can receive separate credentials. Shared read credentials cannot read named pages. Views are logged and the subject can inspect that log on My card with a personal sign-in. In team or division mode with evaluation off, a write-token export is not logged. The legacy DELETE /api/v1/developer/{id} writes no audit row; the root DELETE /api/v1/org/people/{dev} writes a name-free person_erased audit row. The developer list has no TIER order. Use the credential scope map for who creates people, issues keys and reads reports. It links the separate rules for branch administration, personal-key custody and declared card access. The evaluation-mode choice includes the legacy shared admin token's access and audit label. These API controls do not restrict a host owner who can read the database file.

In real writable developer mode, named usage and outcomes are pruned at startup and daily: 90 days by default, 60–365 days configurable. Name-free historical totals remain in roll-ups. A permanent watermark refuses older named writes; widening the window works forward only and cannot restore pruned history. Switching to team or division mode continues an already-armed retention policy. Team or division mode that has never armed that policy does not prune named usage and outcomes. Org audit names age out in every real writable mode. View logs have their own retention policy. Restrict access to the local database as well as the API.

What TIER measures and stores (and what it never touches)

The single most important fact for a privacy review: TIER never stores prompt or completion content, source code, or file contents, outside the free text of raw GitHub webhook payloads (below), and never sends any of it anywhere you have not already sent it: the optional reverse proxy passes prompts on to the provider you chose. Its parsers are field allowlists — token counts and metadata only. One opt-in switch, worktree attribution (off by default), widens the read when turned on, to find which branch the work was on. It decodes the file paths (file_path, notebook_path, path) from every tool call in every session file it scans, including sessions in repositories you did not configure, which are then dropped with nothing stored; it reads a git reflog, whose lines carry the committer's name and email and, for a commit, its subject line, only for a linked worktree of a repository you configured that those paths or the session's own folder are in, and for any other project it reads only the .git pointer and worktree admin files, never its reflog. It never reads the files the paths name, keeps none of those reflog fields and stores no path in an event, but the live watcher's checkpoint row keeps the absolute path of the worktree it is carrying, and spend in another repository's worktree is stored as unattributed:foreign-repo, without that repository's name or path; the full list is in privacy.md.

Parents no longer carry (#1016); only message groups labelled isSidechain:true can use carry. Worktree attribution stays opt-in and off by default. Activation requires recorded gates, the operator's security rulings and an explicit operator decision. No new accuracy figures have been measured.

Full, code-grounded detail is in docs/privacy.md (guarantee verified against the code on 2026-07-04). In summary, TIER stores in a single local SQLite file, with no external transmission by default:

The privacy guarantee bounds content. It does not by itself resolve the labor-law question, because the developer identifier plus cost attribution is personal data about a named individual regardless of whether any prompt text is stored. That is the subject of the rest of this document.

Organization access and separate installations

A v0.7.0 organization tree scopes delegated API access within one installation. It does not turn that installation into a service for mutually untrusted tenants. TIER remains single-tenant with no cross-team/cross-entity data isolation: every org table uses tenant_id='', and developer identifiers remain global within the database. Root administration and host access remain trust boundaries; a node key's branch limit does not constrain the host owner.

For a deployment review, record the people and key inventory boundary, including subtree padding, the one server per developer rule, and the federation acceptance limit. Separate database files and host access controls are still needed when separate installations are the intended boundary. Include the child upstream SSRF residual in the deployment's network review. For a transfer between installations, the graft snapshot boundary states what remains at the receiving server after source erasure or consent withdrawal.

EU labor-law exposure of per-developer measurement

In much of the EU, systems that monitor employee performance or behavior are subject to co-determination or works-council consultation before they may be introduced. Per-developer TIER, which shows an efficiency number for each named developer, is squarely the kind of system these rules govern. The threshold is generally the capability to monitor individual performance, not whether you subjectively intend to use it that way.

Germany — Betriebsrat co-determination (§87 BetrVG)

Under §87(1) No. 6 of the Betriebsverfassungsgesetz (BetrVG), the works council (Betriebsrat) has a mandatory co-determination right over the introduction and use of "technical devices designed to monitor the behavior or performance of employees." German case law reads this broadly: a system that is objectively suitable for monitoring individual performance is covered even if that is not its stated purpose. A per-developer TIER deployment is very likely in scope.

France — CSE works-council consultation

In France, introducing a tool capable of monitoring employee activity generally requires prior information-and-consultation of the CSE (Comité Social et Économique) (see, broadly, Art. L2312-38 of the Code du travail), and employees must be informed in advance of any system used to monitor their activity. The CNIL (the French DPA) has repeatedly emphasized proportionality and transparency for workplace monitoring. Per-developer measurement without prior CSE consultation and employee information is a live legal risk.

Under the Wet op de ondernemingsraden (WOR), the works council (Ondernemingsraad) has a consent right (instemmingsrecht) under Article 27 over decisions to adopt, amend, or withdraw arrangements for personnel monitoring or for processing personal data of employees, including systems that monitor presence, behavior, or performance. Adopting per-developer TIER without the OR's prior consent can make the introduction voidable.

Other EU/EEA jurisdictions

Most EU/EEA member states have an analogous works-council consultation or co-determination regime for employee-monitoring systems (e.g. Italy's Art. 4 of the Statuto dei Lavoratori, which restricts remote monitoring of workers). Assume consultation is required and confirm locally. The safe default in any EU/EEA jurisdiction is team-only aggregate reporting plus advance consultation.

GDPR Article 22 posture (automated profiling)

GDPR Article 22 restricts decisions "based solely on automated processing, including profiling," that produce legal effects or similarly significantly affect an individual. TIER's designed posture keeps it clear of Article 22:

Independently of Article 22, per-developer cost attribution is personal data under GDPR. The usual obligations apply: a lawful basis (legitimate interest will require a balancing test and is weakened by any appraisal use), transparency to the data subjects, data minimization, purpose limitation, and storage limitation. Team-only aggregate reporting that cannot single out an individual is the strongest data-minimization posture.

When a DPIA is indicated

A Data Protection Impact Assessment is required under GDPR Article 35 when processing is "likely to result in a high risk" to individuals — explicitly including "systematic and extensive evaluation of personal aspects ... based on automated processing, including profiling" and "systematic monitoring." Several EU DPAs list employee monitoring on their mandatory-DPIA lists.

Practical guidance:

Works-council consultation prerequisites (checklist)

v0.7.0 availability: In developer mode, named coaching cards are available on real data to permitted viewers and the audited operator; the per-issue report remains denied in real-data developer mode. tierd demo shows its own invented data read-only in a private temporary database and cannot load yours (code: internal/api/identity.go, identityRoutePolicies, identityBoundary; internal/api/coaching.go, handleCoaching; cmd/tierd/demo.go, runDemo).

Where a works council or equivalent body exists, treat the following as prerequisites before per-developer TIER goes live. Adapt to local law with counsel:

  1. Engage early. Bring the works council in at the design/decision stage, not after deployment. In Germany the co-determination right precedes introduction.
  2. Limit the purpose in writing. TIER is built for coaching, not for evaluating developers. Per-person figures are not accurate enough to judge an individual. State the coaching purpose, what is measured, and the methodological limits.
  3. Describe the data. Provide the docs/privacy.md field list: what is stored, the no-content guarantee, retention bounds, and the conditional PII stores (watcher state, raw webhook payloads).
  4. Prefer the least-intrusive mode. Offer team-only aggregate reporting as the default; justify any per-developer processing against necessity and proportionality.
  5. Agree who may view, how views are logged, and how long data is kept. Name who may see a developer's numbers (for example, the developer and their declared manager); agree an audit log of who viewed what; set a retention period; and say how the single-tenant local database is protected. Per-viewer credentials, view logging and bounded retention are built; the agreement must specify their configuration and who administers them.
  6. Reach the required instrument — a Betriebsvereinbarung (DE), CSE information-and-consultation record (FR), or OR consent (NL) — before go-live.
  7. Provide transparency to employees and a route to raise concerns.
  8. Complete the DPIA and reconcile it with the consultation outcome.

Deployment decision table: team-only vs per-developer, by jurisdiction

The recommended deployment mode depends on where your developers are employed (the location of the employees measured, not the company HQ). "Team-only" here means reporting that never surfaces an individual developer's performance.

Availability note (accurate as of 2026-10-22): TIER now ships a dedicated team-only aggregation mode with a k-anonymity floor (issue #185). It is selected by a REQUIRED --aggregation team|division setting on tierd serve (env TIER_AGGREGATION, config key aggregation): there is no silent default. developer requires subject-bound credentials and a named audited operator on real data. tierd serve refuses to start until you choose, so an existing deployment can never change its reporting posture on upgrade by accident. In team or division mode GET /api/v1/scores, the dashboard, and GET /api/v1/scores/{developer} never return an individual developer name: named rows are replaced by team aggregates, and any team with fewer than the k-anonymity floor of counted people is collapsed into an aggregate "other" bucket. Since #856 an identifier counts only if it is on the roster, is not a bot, and has activity a collector, the proxy or a pull request captured in the window (not only hand-entered /costs spend or push-only merged work); each published figure (cost, points, paid spend, and each part of the coverage_pct split) also needs k counted people behind it. This protects what a read-token holder sees; the write token can edit the roster and aliases and is an admin credential until #908 (manager-faq.md has the full rule and the remedy). These modes publish one breakdown of each window (#864): the group rows and the grand total, with no work-type, per-model or cost-category split beside them, because two breakdowns subtract to a group below the floor. ⚠️ A residual that is itself below the floor withholds the whole response (#593, #864), the named rows and the grand total included, and says so in data_quality.kanon_suppressed. When the residual clears the floor it is emitted and its people's spend and outcomes remain in the totals. The floor defaults to k = 5 with a hard minimum of 3 (--k-anonymity, env TIER_K_ANONYMITY, config key k_anonymity); without evaluation mode, tierd serve refuses to start with a smaller value. The local tierd score CLI is a deliberate carve-out — it is a single-operator tool that reads the invoking user's own JSONL, not a served multi-viewer surface, so it is not gated. Still restrict access and consult as required: team mode removes individual rows from shared reports, but the underlying database still stores per-developer identifiers (see the storage note below), so run one instance per cohort and follow the works-council / DPIA steps below.

Jurisdiction of measured employees Recommended mode Prerequisites before go-live Rationale
Germany (DE) Team-only Betriebsrat co-determination; works agreement (§87 BetrVG) if any individual-level capability remains; DPIA Per-developer monitoring is co-determined under §87(1) No. 6; suitability to monitor is enough to trigger it.
France (FR) Team-only Prior CSE information-and-consultation; advance employee notice; DPIA Monitoring tools require CSE consultation and transparency (Code du travail L2312-38; CNIL guidance).
Netherlands (NL) Team-only OR consent under WOR Art. 27; DPIA Personnel-monitoring arrangements need works-council consent before adoption.
Other EU / EEA Team-only (default) Local works-council consultation; DPIA; lawful basis + transparency Most member states have analogous monitoring-consultation regimes; confirm locally.
UK Team-only. Named coaching cards: available in v0.7.0 developer mode under the access rules above UK GDPR lawful basis + DPIA; transparency; ICO employment-monitoring guidance No works-council co-determination regime, but ICO expects a DPIA and proportionality for monitoring.
US (at-will, non-union) Team-only. Named coaching cards: available in v0.7.0 developer mode under the access rules above Internal policy; transparency; TIER is built for coaching, not for evaluating developers. Per-person figures are not accurate enough to judge an individual. Fewer statutory constraints, but the coaching-not-appraisal stance still applies; state privacy laws may add duties.
Anywhere with a collective agreement / union Follow the agreement Whatever the agreement requires A collective bargaining agreement can impose obligations beyond statute regardless of country.

How to read this table: in every EU/EEA row the safe default is team-only aggregate reporting plus advance consultation. Run tierd serve with --aggregation team (the #185 mode), or --aggregation division to roll up one level higher (#270), so named per-developer views are technically suppressed — the API, dashboard, and per-developer endpoint never return an individual name, and sub-k cohorts collapse into "other". Pair that with access restriction (a read-only viewer token, #190) and separate instances per cohort.

Per-developer deployment in a co-determined jurisdiction should not go live until both (a) the required works-council instrument is in place and (b) a DPIA has been completed. TIER is built for coaching, not for evaluating developers. Per-person figures are not accurate enough to judge an individual.

Summary

Erased people and later imports (#1491, ruling A⁗)

TIER keeps this record so a completed erasure stays effective. Your organisation decides the legal basis with its counsel.

On an erasure request, if any identifier has an import trace, TIER stores one unlinked keyed hash for each canonical ID, alias and mapped source name. A batch row mapped to someone else is not a trace. If erasure deletes a mapping row whose target is someone else, it also records that source name; a wrong exclusion is reported and reversible. Applied-batch plaintext source-name rows for the erased mapped person are deleted. Retention ageing makes no entry and never deletes entries. The record holds no figures, timestamp or link between identifiers and uses its own HMAC domain. Hashes never appear in API output, logs, audit rows, receipts, previews or data-subject exports. Those compliance artifacts state the record's existence in fixed wording, without checking membership or counting entries.

The record is not anonymous: anyone holding the database could test a guessed identifier. It matches on the identifier alone, so the same identifier from any source is excluded, including a different person. Preview and apply leave a match behind, rechecking inside the apply transaction, with this report line naming nobody: “One or more people were left behind so a completed erasure stays effective.” The bundle is not refused; lookup failure refuses the import. A wrongly excluded person has to come forward because the report names nobody; root can release them. A different (renamed) identifier evades the record. A person erased here with no import trace is not recorded, except this clash case, so a later first import can recreate them. A staged copy can remain for 24 hours.

Entries are kept until root clears them or the database is deleted, with no timer. A clear removes only the named identifier; a returning person with several identifiers needs one clear each. Root states either “new consent” or “a different person with that identifier” (the API value is different person with that identifier). The response is identical whether or not an entry existed. Each clear is audited without the identifier, hash or entry count. An audited clear-all states “our counsel refused this record”. There is no dashboard control. Nothing in the release waits for counsel, and no Article is cited as the record's legal basis. The secret and entries share the database file. Entries do not survive a restore from an older backup that predates them: restoring it loses newer entries and undoes those erasures. Re-run erasures after a restore.

See the root API commands for one-identifier clear and counsel-refusal clear-all.