> ## Documentation Index
> Fetch the complete documentation index at: https://docs.elevatedsignals.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Changelog

> What's new in Invariant, updated as the product is built.

<Note>
  Invariant is in active development (beta). This changelog tracks build progression for the internal
  team and beta testers — entries describe capabilities as they land. Status tags reflect maturity:
  **Prototype** (original demo build), **Preview** (design-partner review builds), **Beta** (the current
  productized system). For the authoritative current-state boundaries of any feature, see
  [Compliance & Validation](/invariant/compliance/overview) and the capability register.
</Note>

<Update label="2026-09-11" tags={["Beta"]}>
  ## Clearer quality follow-up, training, and import results

  * **Audit links:** open supported affected records from their audit events. Unavailable records and
    event types without detail pages remain text. See [Audit Trail](/invariant/reference/audit-trail).
  * **Complaints:** select existing deviations and CAPAs by number and title. Action-specific errors and
    pending-request controls make investigation and disposition actions clearer.
  * **Quality Calendar:** unfinished tasks with due dates appear as **Task** entries where the calendar
    and task workflow are enabled. This is not recurring scheduling or live document-routing history.
  * **Training:** combine group, role, and program matrix filters; create draft curriculum versions or
    retire published versions with a reason, within the existing role boundaries. Version-specific
    document assignments require approved revisions. New change-control audiences retain explicit
    group, user, or role identities; legacy labels are not automatically converted.
  * **Aging reports:** separate **91–180 days** from **180+**, meaning older than 180 days.
  * **Imports, where enabled:** a valid CSV can report invalid rows while importing the valid subset.
    **Validate only** now saves an audited validation report without creating the predicted records,
    invitations, or email jobs. Malformed files are still refused. See the
    [validation and import procedure](/invariant/reference/settings#validate-and-import-csv).
  * **Administration:** clearer outstanding-invitation handling and first-time site/licence creation.
    Existing-record changes retain their reason requirements.
  * **Optional categories and materials:** category controls remain feature-gated; material history
    respects the existing multi-site boundary. No live inventory integration is implied.

  This release does not activate additional features for an account. Imports, document categories,
  invitation visibility, and other optional workflows remain off where they were off. No schema
  migration or sign-in model change is included. Broader roadmap items remain separate.
</Update>

<Update label="2026-09-10" tags={["Documentation"]}>
  ## A clearer starting point for quality teams and partners

  * The introduction now links the complaint, task, document, training, and evidence workflows.
  * New evaluation guidance helps teams scope a first site and a guided SOP-based walkthrough.
  * Availability notes distinguish beta workflows from planned AI complaint intake, live production
    integrations, and broader multi-site work. The audit-history explanation states verification limits.

  This is a documentation update, not an application release or a change to account access.
</Update>

<Update label="2026-09-04" tags={["Beta"]}>
  ## QualityCore is now Elevated Signals Invariant

  * **The product has a new name.** Same product, same team, same roadmap. The name refers to the
    audit history: your records change throughout their lifecycle, as they must, but the recorded
    history of those changes is hash-chained, so any alteration to it is detectable.
  * **Existing documentation links keep working.** Every `/qualitycore/...` page now redirects to its
    `/invariant/...` equivalent, so previously shared links do not break.
  * Entries below this one were written under the previous name and are left as they were recorded.
</Update>

<Update label="2026-08-31" tags={["Beta"]}>
  ## Export your audit trail and verify it yourself

  * **Audit trail exports are now independently verifiable.** An export previously left out the fields
    you would need to check its integrity without us. Every export now carries the full hash chain, so
    you — or your auditor — can confirm that no row has been altered or removed, using nothing but the
    file. You do not have to take our word for it, which is the entire point of a tamper-evident record.
  * **Every audit trail download is itself recorded.** We logged the *request* for an export but not the
    export that actually left the system. Now the download is recorded with the number of rows it
    contained, so "who took this organization's audit trail out of the system, and when?" has a complete
    answer. If that recording ever fails, the download fails with it — you will never receive a copy
    that was not logged.
  * **Reports are restricted to QA managers and administrators.** This now applies to the report list as
    well as the downloads themselves. Previously any member could see that a report had been generated,
    when, and by whom — the index was open even though the file was not.

  ## SLA extensions: clearer rules, honest dates

  * **The rules are stated before you click, not after.** Requesting a due-date extension told you what
    was wrong only once you had tried. The justification minimum and the constraints on the new date are
    now shown up front. *(Found by Amar hitting exactly this wall on a live deviation.)*
  * **The date you see is the date that is checked.** A CAPA could reject a due date that was visibly
    later than the one on screen, because the display and the validator were resolving different dates.
    They now agree.
  * **One pending extension per record**, enforced by the database rather than by convention. Stacked
    requests could previously be approved out of order and produce a due-date history that depended on
    the order of approval.
  * **Extended records are marked** in list views without pushing the row to double height.

  ## Bulk import refuses bad files loudly

  * Malformed CSV is now rejected with a clear reason instead of being partially processed, and imports
    are bounded so an oversized file cannot run away.

  ## Smaller things

  * Creating or triaging a quality ticket no longer asks for a reason-for-change. Both are first-time
    actions, so there was no prior state to explain; the prompt still appears on later status changes,
    where it is meaningful.
  * Dashboard KPI widgets now explain what they measure.
  * Marketing and in-product claims about SLA, retraining and notification features now state their
    availability boundaries next to the claim itself, rather than relying on a note elsewhere on the page.

  ### Under the hood

  Most of this period's work does not appear above, because it was verification rather than features:
  correcting the tests and gates that police the product. Several checks were found to be reporting
  green while proving nothing — a feature-flag gate that passed with the flag removed, and a signature
  check that passed with credential re-verification disabled. Both now fail when the property they
  guard is violated, and each is accompanied by a deliberately broken control proving it can fail.
</Update>

<Update label="2026-08-23" tags={["Beta"]}>
  ## Bulk user import no longer overwrites existing people

  * **Importing a spreadsheet that contains someone who already has an account now leaves that account
    alone by default.** Previously a re-import could quietly change an existing person's role. If you
    genuinely intend to modify existing users from a spreadsheet, tick **update existing users** — the
    import then tells you plainly which rows it skipped and why, rather than failing the whole file.
  * **You cannot change your own account through an import.** A safeguard against an administrator
    removing their own access mid-file.
  * **Invitations to an email that already has an account in your organization** now return the same
    clear refusal as every other invitation conflict, instead of a raw database error.

  ### Under the hood

  Tenant-isolation checks, audit-trail integrity guards, and the automated tests that police them. Two
  points worth stating because they bear on how much weight our checks carry:

  * **Several automated checks were found to be passing without actually testing anything** — comparing
    an empty dataset against an empty dataset, or scanning for problems in a place the problem could
    never appear. Each has been rebuilt and then *deliberately broken* to confirm it now fails when it
    should. A check that has never been observed failing is not evidence.
  * **Signing in across multiple facilities** is being reworked so one person can hold a single set of
    credentials rather than one per site. The design passed independent review; **it is not yet
    released**, and nothing about how you sign in has changed. It will appear here when it ships.
</Update>

<Update label="2026-08-21" tags={["Beta"]}>
  ## Multi-site foundation, and audited bulk user import

  * **Multi-site foundation (Phase A).** Organizations can define sites as first-class entities, ahead
    of per-site scoping of records and permissions. Behind the `multi-site` flag, off by default;
    existing single-site behaviour is unchanged until you opt in.
  * **Bulk user import is now fully audited** — behind the `bulk-user-import` flag. Every provisioned
    or modified account appends an audit entry, so an import is reconstructable after the fact rather
    than being an unattributed bulk write.
  * **Archive and unlink on the sites screen no longer fail silently.** A rejected action (too short a
    reason, a constraint violation, a network error) previously produced no row change, no error and
    no spinner — leaving an administrator unable to tell whether an audited action had been recorded
    or refused. Found in review before the feature was enabled for anyone.
  * **Transactional outbox for system email**, so a message is committed exactly once with the work
    that triggered it — no "sent" claim for mail that never left, and no duplicate on retry.
</Update>

<Update label="2026-08-14" tags={["Beta"]}>
  ## Sign-in dead-ends fixed, and honest compliance language

  * **An expired or already-used invitation or reset link no longer dead-ends the login page.** You now
    get a real explanation and a route forward instead of a screen that cannot proceed.
  * **Invitation links are presented as account setup**, not as a login — the previous wording asked
    people to sign in to an account they had not created yet.
  * **Overdue and on-time are now graded against the same due date.** They could previously disagree,
    so a record could read as both.
  * **Unqualified compliance claims removed from our public site**, and the full list of what we do and
    do not claim is now enumerated internally and checked automatically. We describe QualityCore as
    built to support Part 11 and Annex 11 expectations — never as certified or validated on your
    behalf.
  * **The deviation screen no longer displays a production-telemetry panel** that was not backed by
    real data. It is gated off pending a genuine data source.
</Update>

<Update label="2026-08-11" tags={["Beta"]}>
  ## SLA extensions, due-date accuracy and dashboard honesty

  * **Extensions are refused on closed records**, and an extended due date is now labelled as such
    rather than silently replacing the original.
  * **An approved extension applies inside the signed transaction**, so the approval and the new date
    land together or not at all.
  * **Due dates render in UTC consistently**, closing gaps where a record could fall into the wrong
    aging bucket depending on the reader's timezone.
  * **A dashboard with no closures yet reads as "pending" rather than 0%.** An empty program was
    previously indistinguishable from a failing one.
  * **Unsupported dashboard figures removed**, and activity entries whose actor could not be verified
    are no longer attributed to a name.
  * **Training evidence and role gates enforced** — completion requires the evidence the assignment
    asks for, and the roles permitted to record it are checked server-side.
  * The Quality Tickets page shows its own help content, and its breadcrumb no longer reads
    "Quality-tasks".
</Update>

<Update label="2026-08-06" tags={["Beta"]}>
  ## Training completion reporting corrected

  * **Training compliance now measures completion, not absence of lateness.** The headline was previously `(total − overdue) / total`, which reported 100% whenever nothing was past due — including assignments nobody had started, and assignments with no due date, which can never be overdue. It is now `completed / total`. **If your training figure drops after this release, this is why — the new number is the accurate one.** Our reference tenant moved from 100% to 86%, matching the record table beneath it.
  * **The KPI is renamed "Training Completion"** (from "Overall Compliance") and states its own denominator — e.g. *25 of 29 assignments complete*.
  * **The Training page and the exportable Training Compliance report now share one contract** (`qualitycore.training-compliance.v1`). They could previously disagree: the export already used completion while the screen used absence-of-lateness, so the same tenant could show 86% in a PDF and 100% in the app.
  * **A date range now scopes only the detail rows, not the headline.** A bounded range previously reported 0% against 86% on screen.
  * **Completion and on-time are now distinct measures.** The completion figure no longer reuses the on-time field or the "On-Time Rate" label; CSV exports carry `completion_rate`. On-time rate keeps its closed-within-SLA meaning everywhere else.
  * **Exports disclose their cohort rule and metric contract version** on the artifact itself.
  * **100% is reserved for an exact result.** A non-empty incomplete cohort caps at 99%, so 199 of 200 no longer renders as "100%", and an empty cohort reports 0% rather than 100%.
  * Training matrix cells resolve *due soon* through the shared contract, so the cells and the "Due Within 30 Days" KPI can no longer diverge.
  * Ticket category labels render SOP/CAPA/QA/SLA acronyms correctly (`sop_revision` previously rendered "Sop Revision").
</Update>

<Update label="2026-08-05" tags={["Beta"]}>
  ## SLA policy versioning & alert alignment

  * **Closure targets are now versioned.** Each record is pinned to an immutable snapshot of the SLA policy in force when its clock started — including the working-day calendar — so tightening a target later cannot retroactively rewrite how earlier work is judged. Editing a target previously could hide work that had genuinely been overdue.
  * **Target changes are tighten-only**, so a loosened target cannot silently clear an existing overdue item from the dashboard.
  * **Overdue and aging alerts now follow severity-tiered targets** rather than a single org-wide number, and stale alerts are reconciled when a record's date moves or it closes — a closed record no longer keeps an "overdue" alert indefinitely. Reassigning a record resets read state so the new owner sees an unread alert.
  * **Deviation close and reopen now lock and re-validate inside the transaction**, so two people acting at the same moment cannot both write a transition.
  * Row-level security is enabled by default on new tables, with the tenant-isolation backstop and type checking enforced on every push in CI.
</Update>

<Update label="2026-08-04" tags={["Beta"]}>
  ## Employee groups, curricula & quality tickets

  * **Employee Groups and Curricula** on the Training page — define a group once, attach requirements to it, and matching assignments materialize for its members, so *"has everyone been trained on what they should be trained on"* is answerable without reconciling paper records. Behind the `employee-groups-training` flag.
  * **Quality tickets** — a gated intake and triage workflow for issues that need routing before they become a formal quality record, with audited state changes throughout. Behind the `quality-ticketing` flag.
  * **Fixed: the Schedule Training trainee list came back empty** under the production tenant-isolation role, leaving the dialog permanently unsubmittable.
  * **Fixed: training reference numbers restart their ordinal each year.** A tenant with 150 records in 2025 previously began 2026 at `TR-2026-151`.
  * **Fixed: opening and saving Settings no longer resets your closure targets.** The legacy SLA form initialized to a hardcoded 30/30 rather than loading current values, so an unrelated save could overwrite real targets — with an audit entry that made it look deliberate.
</Update>

<Update label="2026-07-22" tags={["Beta"]}>
  ## Deviation investigation & calendar refinements

  * **Assign the investigator when you start the investigation** — every deviation now gets a responsible owner from the moment investigation begins (defaulting to you), and the assignment is persisted and audit-logged. Hand ownership over later with **Reassign investigator**, which captures a reason for change.
  * Removed a redundant reason-for-change prompt from *Start Investigation* (starting an investigation is an inherent step, not a change to an existing controlled value); the audit trail still records the event.
  * **Quality calendar entries now show their context** — each item is labelled with its type and whether the date is a *Requested due date*, *Target due date* (SLA-derived), or *Due for review*, so you can see why an item is scheduled without opening it.
  * **Create a quality task directly from a deviation** (matching CAPAs and change controls) to delegate the work that happens between approval steps.
</Update>

<Update label="2026-07-20" tags={["Beta"]}>
  ## Complaints management

  * **Capture, classify, and close product complaints** in one controlled workflow: intake with source channel, product/lot, and site.
  * **Controlled two-level taxonomy** (type → subtype) that you manage, so complaint trends stay consistent and reportable.
  * **Link a complaint to a CAPA** when corrective action is needed, and track severity and status through to closure.
  * Every create and state change is written to the **tamper-evident audit trail** automatically. Behind the `complaints` flag.
</Update>

<Update label="2026-07-15" tags={["Beta"]}>
  ## File attachments & evidence (audit-bound)

  * **Attach evidence** to documents and deviations (one shared primitive, extending to CAPAs and change controls): upload a file and it's captured against the record.
  * **Tamper-evident by design** — every file's content hash is computed on the server, stored, and bound into the audit chain, so a substituted file is detectable; downloads re-verify the bytes and refuse altered content.
  * Private, organization-scoped downloads only. Behind the `attachments` flag.
  * *(Current backend is local/dev storage; durable cloud storage is a fast-follow — no WORM/durability claim yet.)*
</Update>

<Update label="2026-07-14" tags={["Beta"]}>
  ## Document control completion

  * **Draft editing** — edit a draft document's content and change summary (draft status only),
    audit-logged with a required reason.
  * **Reject / rework** — reviewers can send a document back with a signed rejection (independent
    approver, reason for change), returning it to draft while retaining the rejection evidence; the
    author can then edit and resubmit through to approval.
  * **Controlled-copy PDF** — one-click controlled PDF of an approved document (title, document + version
    numbers, approver, approval and generated timestamps, and a CONTROLLED COPY marking).
  * Behind the `document-control-completion` flag. Binary file upload / object storage remains out of
    scope for now.
</Update>

<Update label="2026-07-14" tags={["Beta"]}>
  ## Work-item tracker, in-app help, and this docs site

  * **Quality Work Items** — a new in-app task tracker spanning deviations, CAPAs, and change controls,
    with list + Kanban views, owner assignment, due-date SLAs, and overdue flags. Scoped to quality work
    (not a general project-management tool).
  * **In-app Help center** — browsable documentation available directly inside the app.
  * **Documentation site** — this site (docs.elevatedsignals.ai) went live.
</Update>

<Update label="2026-07-14" tags={["Beta"]}>
  ## Deviation → CAPA closure spine

  * **Deviations** — structured 5-Whys / Fishbone root-cause capture, persisted investigator assignment,
    signed reopen/amendment, and a close gate that requires an RCA conclusion plus a linked disposition.
  * **CAPAs** — enforced closure ordering (all actions complete → effectiveness verified → signed close),
    signed reopen/correction, and overdue flags.
  * **Maker-checker** (an independent approver, never the author) and **reason-for-change** are enforced at
    every controlled step.
</Update>

<Update label="2026-07-14" tags={["Beta"]}>
  ## Unified metrics, single verifier & capability register

  * **One versioned metric contract** (`qualitycore.metrics.v1`) so the dashboard, CSV export, and PDF
    export always report identical numbers — closure cohorts, SLA on-time rate, aging, 12-month trend,
    recurrence, and reopen rate — with fixture parity coverage across edge cases.
  * **Single audit verifier** — retired the standalone verifier so qualification, CI, scheduled checks,
    and demos all run the same `verifyOrgChain` the customer's **Verify Integrity** button uses.
  * **Capability register** established as the source of truth for implemented-vs-claimed; stale PRD,
    Settings, help, and marketing copy reconciled; fake "connected" states replaced with disabled
    planned-connector cards and evidence-scoped compliance statuses.
</Update>

<Update label="2026-07-13" tags={["Beta"]}>
  ## Tenant isolation, maker-checker & reason-for-change

  * **Database row-level-security backstop** across regulated tenant tables — transaction-local org
    context, scoped data access, and a guard that rejects raw unscoped queries.
  * **Independent approval/sign-off** enforced across documents, CAPA effectiveness + closure, and
    change-control approval/implementation.
  * **Reason-for-change** (10–1000 chars) required on routine regulated-value edits, written atomically
    into the hash-chained audit entry and bound into signed approval payloads.
  * Adversarial cross-organization proofs added.
</Update>

<Update label="2026-07-07" tags={["Beta"]}>
  ## Change-control depth & training loop

  * **Change controls** expanded — impacted teams, attachments, action plan, GMP impact,
    requires-training, and implementation dates — plus a pre-review comment stage before committee
    submission.
  * **Automatic training assignments** triggered by document approval, CAPA/deviation closure
    retraining, and implemented change controls.
  * **Document review radar** — next-review dates, dashboard review radar, and Quality Calendar review
    entries.
</Update>

<Update label="2026-07-06" tags={["Beta"]}>
  ## Audit Trail screen + Verify Integrity

  * New **Audit Trail** dashboard: organization-scoped events, human/AI/system actor badges, and
    pagination.
  * One-click **Verify Integrity** recomputes the tamper-evident chain from genesis and renders an
    unmistakable intact/broken result.
</Update>

<Update label="2026-07-05" tags={["Beta"]}>
  ## Database-enforced tamper-evident audit chain

  * The audit hash chain is enforced at the **database layer** (insert-time trigger, per-organization
    advisory lock, fail-closed on a missing chain head).
  * `audit_logs` made **append-only** — updates, deletes, and truncation are blocked, with an anti-fork
    uniqueness guard.
</Update>

<Update label="2026-07-03" tags={["Beta"]}>
  ## AI Investigation Assistant & quality-review hardening

  * **Flag-gated AI Investigation Assistant** for deviation intake, producing reviewable AI-generated
    drafts with both human and AI audit events (early access, behind a feature flag).
  * Per-organization vector substrate underpinning AI features.
  * **Falco Phase 1** automated end-to-end regression suite (read-only).
  * UI polish — loading skeletons, table and dialog cleanup.
  * First cut of the product marketing site.
</Update>

<Update label="2026-07-02" tags={["Beta"]}>
  ## Real data + full workflow spine

  * Core quality pages backed by real demo (Apex) data.
  * **Create flows and lifecycle transitions** wired across modules.
  * **Electronic-signature spine.**
  * **Reports + audit exports.**
  * User administration and bulk user import.
  * GMP gap analysis completed.
</Update>

<Update label="2026-07-01" tags={["Beta"]}>
  ## Closure-time KPI dashboard

  * Average closure time, configured-SLA on-time rate, aging buckets, a 12-month closure trend, and
    role-gated per-owner scorecards — the metrics a GMP quality program is measured on.
  * North-star product strategy set; first external cross-model review cycle run against the build.
</Update>

<Update label="2026-06-30" tags={["Preview"]}>
  ## Design-partner Round 1 preview

  * First preview deployment for design-partner (GMP consultant) review, with QA screenshots and a
    review package.
</Update>

<Update label="2026-06-19" tags={["Preview"]}>
  ## First quality workflow surfaces

  * Initial Round 1 quality workflow surfaces built for design-partner feedback.
</Update>

<Update label="2026-03-13" tags={["Prototype"]}>
  ## Initial QualityCore build

  * Original prototype: core module pages, a GMP-styled document editor with inline SOP editing and a
    change-reason dialog, and the first live deployment. This foundation was later rebuilt into the
    productized system above.
</Update>
