Ctrl K
ComunidadGuías…

CHANGELOG.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Changelog

## 2.1.5 - 2026-11-09

- Include a server-issued request ID in REST and HTTP MCP responses, including early authorization failures.
- Show representative responses for index status, refresh and warning-stage retries in OpenAPI.
- Exercise a client generated from OpenAPI in the existing contract checks.

## 2.1.4 - 2026-11-08

- Document the self-hosted REST responses, request bodies, permissions, and retry behavior in OpenAPI.
- Describe the existing API key and workspace discovery routes and API v1 route aliases.

## 2.1.3 - 2026-11-08

- Preview and restore large legacy Markdown without autosaving the rendered output.
- Preserve the current view mode during version preview.

## 2.1.2 - 2026-11-08 (publication canceled)

- Preview and restore historical document versions without reloading the page.
- Skip unchanged history writes, invalidate restored document caches, and reject stale saves.

## 2.1.1 - 2026-11-02

- Refresh Bun 1.4.4, SvelteKit/Vite adapters and Better Auth/core security patch versions.
- Fix compatible transitive security advisories; retain explicit evidence for two build-tool advisories requiring upstream major migrations.
- Keep MCP/REST contracts and permissions unchanged.

## 2.1.0 - 2026-11-01

- Add scoped, stateless HTTP MCP and public web-origin proxy alongside stdio.
- Generate the MCP documentation catalog from actual discovery and compact equivalent schemas.
- Add redacted JSON-RPC argument diagnostics while retaining upstream authorization and protocol checks.
- Add server-side document filtering, stable cursors, accurate totals, previews and effective-category metadata.
- Add canonical search aliases, metadata-rich markdown export, credential discovery and explicit SDK API prefixes.
- Keep legacy routes, result envelopes and OAuth boundaries; detailed diagnostics are opt-in.

## 2.0.4 - 2026-10-26

- Restore focus to the replacement mobile navigation trigger after the drawer closes.
- Defer focus until the closing render completes and skip restoration if navigation reopens.
- Preserve previous connected focus targets and avoid focusing detached controls.


## 2.0.3

- Declare optional MCP workspaceId in every operation branch as well as at the schema root, so operation-based client normalization preserves explicit workspace selection. Runtime authorization, the 22-tool catalog and existing OAuth grants are unchanged.


All notable changes to DocsMint are documented in this file.

The format follows [Keep a Changelog](https://keepachangelog.com/en/2.0.0/),
and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.0.2] - 2026-10-25

Align public framework overrides with their declared peer ranges so npm accepts publication. The packed-package gate now performs an actual npm publish dry-run, and the CLI entry is explicitly included in the file list. Node24 is used for npm verification/publication. The immutable 2.0.1 tag passed all verification gates but npm rejected its public manifest; no npm package was published.

## [2.0.1] - 2026-10-25

Fix the SvelteKit 3 PWA worker output directory so adapter-node serves `/sw.js` and its precache contains the actual immutable client assets. Includes the MCP workspace routing and security changes prepared for 2.0.0. The 2.0.0 tag failed the browser artifact gate and was not published. No release gate is bypassed.

## [2.0.0] - 2026-10-25

- Add host-authorized MCP workspace discovery and per-call workspaceId selectors, including empty workspaces.
- Publish validated multi-scope result envelopes while retaining the 22-tool catalog and existing single-scope responses.
- Update SvelteKit, Zod and Happy DOM to resolve production dependency audit findings.

## [1.0.3] - 2026-10-23

### Fixed

- Export closed MCP operation unions with a shared root property closure so clients can add account-routing fields without invalidating every operation branch.
- Preserve provider-side validation and reject unknown or operation-incompatible arguments. No account-routing field becomes a business API parameter.

### Security

- Update the MCP server/client SDK to 2.3.0 and patch Vite, ProseMirror view and source-map-js audit findings without disabling release gates.

## [Unreleased]

## [1.0.2] - 2026-09-28

### Changed

- Clarify when MCP clients should choose a single-document tool or
  `batch_documents`, and keep the LobeHub tool descriptions aligned. The
  22-tool catalog, input schemas, and behavior are unchanged.

## [1.0.1] - 2026-09-28

### Added

- Add `batch_documents` for one bounded action across 1–25 explicit document
  IDs: move, set category, add/remove a tag, trash, restore, or refresh index.
  Results are per-document and partial success is explicit. The existing API
  enforces each operation's workspace and category permissions; authentication
  and rate-limit failures stop remaining calls. Permanent purge is excluded.
- Add `get_workspace_item` for a visible folder, category, or tag by UUID.
  Folder reads use the direct API route; categories and tags use complete,
  permission-filtered lists. No new authorization path is introduced.

### Changed

- Synchronize the 22-tool MCP catalog across the runtime, README, MCP Registry,
  and LobeHub metadata. The existing 20 tools, SDK, CLI, REST routes, prompts,
  resources, and self-hosted API-key setup remain available.

### Compatibility

- The two new tools require the 1.0.1 bridge or matching hosted Cloud package.
  Batch actions are sequential and non-atomic. No database migration is needed.

## [0.10.0] - 2026-09-27

### Changed

- Consolidate the MCP discovery surface from 31 to 20 tools while preserving
  all 31 operations. Explicit `mode`, `view`, `kind`, and `action` selectors
  separate browse/search, read/export/history, create/update, and graph flows.
- Keep deletion, version restore, trash restore, and permanent purge as
  separate operations. Grouped results include an `operation` discriminator.
- Update the runtime catalog, Glama-facing docs, MCP Registry count, and
  LobeHub declarations together. The SDK, CLI, REST API, prompts, resources,
  API-key scope enforcement, and Docker deployment are unchanged.

### Migration

- MCP clients must replace old tool names with the 20-tool catalog and supply
  the selector shown in `packages/mcp-server/README.md`. Old tool names are not
  advertised as aliases. Hosted Cloud deployment must adopt the matching
  package before Cloud clients use the new names. No database migration is required.


## [0.9.4] - 2026-09-27

### Added

- Extend the self-hosted MCP catalog from 21 to 31 tools: create, update,
  delete, assign, and remove tags; update folders and categories; list trash;
  restore trashed documents; and permanently purge documents already in trash.
- Add typed SDK methods for listing trash, restoring a trashed document, and
  permanently deleting one. Existing REST authorization remains authoritative.

### Improved

- Synchronize MCP runtime, README, Registry, and LobeHub tool definitions,
  including input validation, output schemas, and destructive annotations.
- Keep the hosted DocsMint Cloud Connector separate from the self-hosted stdio
  bridge. No database migration or hosted OAuth change is required.

## [0.9.3] - Unpublished candidate

The `v0.9.3` tag failed the contract-evidence gate before artifact publication.
The MCP management expansion and README updates are included in 0.9.4.

## [0.9.2] - 2026-09-25

### Documentation and registry metadata

- Replace the repository-root Glama Connector claim with the current Glama
  Server schema and the authorized GitHub maintainer for the OSS listing.
- Clarify the published stdio command, Bun requirement, reachable self-hosted
  API URL, and API key needed for Glama Server hosting. Keep the Cloud Connector
  and its ownership process separate.
- Update the MCP catalog validator to check the Glama Server claim format.

No MCP capabilities, API routes, or database migrations changed.

## [0.9.1] - Unpublished candidate

The `v0.9.1` tag failed the required unit gate before artifact publication.
The Glama metadata changes are included in 0.9.2.

## [0.9.0] - 2026-09-24

### Fixed

- Return folder and category names from the offset document-list endpoint, as
  promised by the public SDK type and MCP `list_documents` output schema.
- Invalidate cached document-list labels after category and folder metadata
  changes across all members of the affected workspace.
- Prevent category-scoped credentials from creating a document in a folder
  belonging to another category.

### Improved

- Publish the canonical MCP catalog with stable tool schemas and clearer
  parameter guidance; expose `capabilityCatalog` from the public MCP package.
- Align category-list response types for API-key principals and Cloud
  authorization setup guidance with the supported connection flow.

No database migration is required.

## [0.8.9] - 2026-09-24

### Improved

- Improve all 21 MCP tool descriptions, parameter guidance, effect annotations,
  and stable output schemas. Keep README, Registry, LobeHub, and runtime tool
  declarations tied to the canonical capability catalog.
- Export the canonical `capabilityCatalog` from the public MCP package entry so
  hosted consumers can compare their advertised tools with the OSS contract.
- Type `GET /api/categories` responses for both workspace principals and
  API-key principals, whose response intentionally omits workspace permission
  metadata.
- Direct Cloud OAuth setup copy to the hosted connection guide so it does not
  freeze currently supported client-registration methods into the OSS package.

### Fixed

- Reject document creation when a category-scoped credential selects a folder
  in a different category, including requests that explicitly name the allowed
  category ID.
- Align MCP category and search-tag input contracts with their REST behavior;
  unsupported category descriptions are no longer exposed by the MCP tool.

No database migration is required.

## [0.8.8] - 2026-09-23

### Documentation and registry metadata

- Clarify the DocsMint Cloud hosted MCP authorization contract and distinguish
  it from the self-hosted stdio bridge, which uses the operator's own API key.
- Synchronize the MCP Registry and LobeHub metadata with Cloud and self-hosted
  setup guidance, including the current OAuth discovery and DCR behavior.
- Correct the registry catalog count to the implemented surface: 21 tools,
  2 prompts, and 3 resources.
- Update the supported security version line, disclosure address, and scope
  language while keeping technical authorization-protocol flaws reportable.

### Verification

- Add a focused self-hosted API route contract test for the absence of Cloud
  MCP authorization-server and DCR endpoints.
- Validate registry tool, prompt, and resource metadata against the canonical
  MCP capability catalog.
- Update the frontend's `devalue` dependency to 5.9.4 to resolve the moderate
  malformed-input denial-of-service advisory caught by the release audit.

No runtime capability, SDK, CLI, stdio authentication, or database schema
change is intended by this release.

## [0.8.7] - 2026-09-16

### Added

- MCP tools for moving documents to trash, deleting folders and categories, and
  restoring document content from saved versions or snapshots.
- Destructive-operation annotations, documented permissions, and complete MCP
  parameter descriptions. Existing 17 tools remain available; the catalog has 21.

### Fixed

- Apply graph-related result limits after authorization and active-generation filtering.
- Filter and rank graph-related documents by query text using multilingual/simple
  and English full-text matching, with exact-title priority; no extra model calls.
- Keep LobeHub Cloud and self-hosted instructions in separate readable sections.


- Show a network error for authentication proxy/server failures instead of
  incorrectly reporting invalid credentials.
- Restore graphical platform badges in the project README.

## [0.8.6] - 2026-09-16

### Fixed

- Update Docker Hub descriptions through the supported repository PATCH endpoint.
  The namespace read endpoint rejected description updates even with a correctly
  scoped publisher token. Existing images, package names, and public APIs are unchanged.
- Add direct Docker Hub and self-hosted setup links to the LobeHub overview.

No database migration or credential rotation is required.

## [0.8.5] - 2026-09-16

### Documentation and release presentation

- Simplify the project introduction and clarify Cloud, self-hosted, SDK, CLI,
  and MCP installation paths around the single `@hiai-gg/docsmint` package.
- Make root README documentation links work on npm as well as GitHub, and
  correct the SDK quick-start example for empty workspaces.
- Explain the API, web, and Caddy image roles and matching versioned Docker tags.
- Refresh the documentation index and publish benefit-focused release notes.

### Upgrade notes

- This release updates documentation and distribution presentation. It introduces
  no database migration or public API change.
- Use `@hiai-gg/docsmint@0.8.5` for SDK, CLI, and MCP clients. The matching Docker
  tags are `api-v0.8.5`, `web-v0.8.5`, and `caddy-v0.8.5`.

## [0.8.4] - 2026-09-14

### MCP discovery and onboarding

- Present DocsMint Cloud first in MCP registry, LobeHub and npm metadata while
  preserving self-hosted DocsMint as the full Apache-2.0 alternative.
- Link marketplace visitors to the canonical Cloud onboarding page with
  source-aware registry, LobeHub, npm and GitHub URLs.
- Document hosted browser authorization with PKCE S256, workspace/scoped consent,
  one-hour tokens and API-key fallback. Hosted OAuth belongs to DocsMint Cloud;
  it is not added to the self-hosted server or npm bridge.
- Clarify self-hosted URL/API-key setup and correct NPX executable selection.
- Keep all 17 MCP tools, 2 prompts, 3 resources, package exports and API contracts.

### Verification and regression coverage

- Add focused authorization regressions for mixed category scopes, personal versus
  external tenant predicates, unsigned workspace headers, category-scoped attachment
  deletion, workspace tag management and partial category API updates.
- Extract the existing category API merge and workspace-tag authorization decisions
  into focused helpers without changing public request or response contracts.
- Add a deterministic offline retrieval evaluation baseline and failure matrix. These
  fixtures make retrieval checks repeatable; they do not claim improved live retrieval.
- Assert every declared public export and required MCP binary exists after the SDK build,
  both in CI and in the package release workflow. Add focused SDK, CLI and editor-save
  regression tests around the existing public behavior.

No database migration or deployment configuration change is required. Catalogs
may refresh asynchronously; publication does not prove a generated LobeHub
installation card has been corrected.

## [0.8.3] - 2026-09-07

### Fixed

- Keep delayed editor saves and retries bound to the document that produced
  them, preventing a document switch from redirecting content to another ID.
- Serialize overlapping content saves and flush pending edits before in-app
  navigation; keep the user on the document if saving fails and warn before
  a full-page unload with unsaved content.
- Reuse an idempotency key across SDK document-creation retries so a lost
  response does not create a duplicate. Explicit caller keys remain supported.
- Require unrestricted write access for workspace-wide tag creation, rename,
  and deletion. Category-scoped keys and workspace viewers cannot mutate the
  global tag collection.
- Preserve omitted category API settings in partial PATCH requests, locking
  the row while merging permissions to avoid concurrent lost updates.
- Restore the stored workspace context when resolving public share links,
  allowing workspace folders and documents to load under the correct tenant.

### Upgrade notes

- No schema migration is added by this release. Public request and response
  shapes and published exports remain compatible.
- Tag authorization is intentionally stricter: integrations that used scoped
  or read-only credentials for workspace-wide tag management now receive 403.
  Use an appropriately authorized unrestricted writer for those operations.
- Use Bun 1.4.0 or later for source development. Versioned application images
  are `api-v0.8.3`, `web-v0.8.3`, and `caddy-v0.8.3` under
  `vgalibov/docsmint`.

## [0.8.2] - 2026-08-31

### Added

- Pipeline status exposes machine-readable graph and summary warnings, including
  stable error codes and retryability.
- `POST /api/documents/:id/pipeline/retry-warnings` and the SDK
  `retryDocumentPipelineWarnings()` method retry only failed optional stages on
  the active embedding generation.

### Fixed

- Preserve candidate identity when empty rerank documents are filtered, so
  provider indexes and scores always map back to the correct document IDs.
- Import theme spread and UI components through published `hiai-ui` package
  exports without SvelteKit source or distribution aliases.
- Keep optional-stage diagnostics independent, retry transient provider
  failures with the configured BullMQ backoff, and avoid regenerating an
  already-ready summary during graph-only recovery.

## [0.8.1] - 2026-08-30

### Fixed

- Allow the frozen 0.5.0 compatibility contract to validate the 0.8.x release
  line, restoring the unit-test release gate after the 0.8.0 version bump.

## [0.8.0] - 2026-08-30

### Fixed

- GraphRAG search expansion runs AGE `cypher()` on one pooled connection with
  `search_path=ag_catalog, public`. A cold pool connection with `public` first
  could return zero neighbors without throwing, so scoped live search reported
  `graphAttempted: true`, `graphFailed: false`, and `graphContribution: false`.
- The scoped live fusion test disables rerank and checks share-ACL graph SQL
  without re-applying category inheritance.

## [0.7.9] - 2026-08-30

### Fixed

- Restricted-assertion and share GraphRAG no longer re-apply category
  inheritance on top of `allowedDocumentIds`. Folder-inherited neighbors that
  the ACL already admitted were dropped, so live scoped search reported
  `graphContribution: false` after rerank.

## [0.7.8] - 2026-08-30

### Fixed

- Keep GraphRAG evidence on documents already in the reranked prefix. After
  RRF+rerank, overlapping AGE neighbors no longer drop the `graph` channel, so
  `graphContribution` stays true for scoped search.
- Use DocsMint as the public API identity in `/api/health` (`service: docsmint`)
  and startup/SDK error strings instead of `hiai-docs`.

## [0.7.7] - 2026-08-30

### Added

- Cross-encoder rerank after reciprocal rank fusion. The reference profile
  calls OpenRouter `voyageai/rerank-2.5`, then `cohere/rerank-v3.5`, then
  `nvidia/llama-nemotron-rerank-vl-1b-v2:free`. Timeouts and provider errors
  keep the RRF order (fail-open). There is no public HTTP `/rerank` route.
- `SEARCH_RERANK_*` operator controls, default `SEARCH_RERANK_ENABLED=true`.
  Graph neighbors still append after the reranked prefix
  (`SEARCH_RERANK_GRAPH_POSITION=after`). Set `SEARCH_RERANK_ENABLED=false`
  to restore the previous RRF-only ranking path.
- Dual fallbacks for embeddings, entity extraction, and query expansion
  (primary plus two models per job).
- Offline retrieval eval: `bun run eval:retrieval -- --mode=baseline|rerank`.

### Changed

- Default search ranking is RRF, then rerank of the original query over the
  fused prefix, then GraphRAG append. Live eval on a 24-document labeled
  corpus (16 queries) with Voyage rerank-2.5:

  | Metric | RRF only | RRF + rerank |
  |---|---:|---:|
  | MRR | 0.969 | **1.000** |
  | nDCG@10 | 0.958 | **0.986** |
  | Recall@10 | 1.000 | 1.000 |

  Voyage served all 16 rerank calls with no fallback. The largest lift was a
  paraphrase query (`operator API key header`): MRR 0.50 → 1.00, putting the
  Better Auth / API-key document first. An offline title-overlap proxy on 12
  queries moved MRR 0.776 → 0.958. RRF already recovered every labeled
  document in the live set; rerank mainly improved first-hit ranking.

### Migration notes

- New installs rerank by default. Existing `.env` files that omit
  `SEARCH_RERANK_ENABLED` pick up the new default on upgrade.
- Ollama-only and other non-OpenRouter deployments fail open to RRF when the
  rerank chain has no usable key. Dedicated keys remain URL-scoped; the shared
  `OPENROUTER_API_KEY` is never sent to a non-OpenRouter host.
- Set `SEARCH_RERANK_ENABLED=false` to disable the extra provider call.

## [0.7.6] - 2026-08-30

### Fixed

- Preserve one-version Better Auth 1.6 rollback compatibility after migration
  0047 by deriving the legacy account issuer in a database trigger.

## [0.7.5] - 2026-08-30

### Changed

- Upgrade the supported runtime and dependency graph to Bun 1.4, TypeScript 6,
  Better Auth 1.7, BullMQ 6, ioredis 6, TipTap 3.30, Svelte 5.57, Vite 8.2,
  and current compatible stable packages.
- Replace the deprecated TipTap collaboration cursor extension with the v3
  collaboration caret while preserving provider awareness and cursor styling.
- Pin every GitHub Action to an immutable commit SHA and audit production
  dependencies in CI.

### Fixed

- Add the fail-closed Better Auth 1.7 `issuer` migration, collision guard, and
  provider-id identity strategy.
- Consolidate API-key and Better Auth session resolution so every authorization
  guard uses the same admin-key, user-key, and session precedence.

## [0.7.4] - 2026-08-30

### Fixed

- Shorten the MCP Registry server description to the 100-character
  `_meta.io.description` limit so `mcp-publisher validate` accepts the catalog
  entry.

## [0.7.3] - 2026-08-30

### Fixed

- Keep nested routes from loading relative `./_app` CSS that 404s on `/login`
  and `/docs/:id`. Asset URLs now resolve from the origin root.
- Restore modal chrome after `@hiai-gg/hiai-ui` 0.1 split `Dialog` from
  `DialogContent`, so settings, folder, category, and related dialogs no longer
  dump into the sidebar and dashboard.
- Keep category-dialog focus rings inside the scroll region instead of clipping
  off the left edge.
- Add Share to Recent document menus, using the same public-link dialog as the
  folder tree.

### Changed

- Default the OSS share contour to a public token link everywhere (dashboard,
  sidebar document/folder/category, editor, Recent). Hosts may opt into
  restricted "Specific people" once via `DocsmintAppShellHost` `share`.
- Consume `@hiai-gg/hiai-ui` 0.1.3 for the circular theme spread and Inter
  `--font-sans` token; the app still loads Inter Variable webfont files.
- Activate a newly installed service worker immediately and do not cache HTML
  shells, so a hashed-asset deploy cannot leave an unstyled previous shell.

## [0.7.2] - 2026-08-29

### Fixed

- Keep the public share view from stretching Twitter and Twemoji SVG emoji
  images across the full column. Those imported image nodes now render as
  Unicode glyphs so shared HTML matches the editor.
- Constrain leftover unsized SVG images in share, print, and editor CSS so a
  viewBox-only graphic cannot fill the reading column.

### Changed

- Load Inter Variable as the product UI typeface and map `--font-sans` to it so
  the sidebar matches docsmint.com instead of the operating-system sans stack.
- Publish MCP Registry, LobeHub, CLI, Swagger, OpenAPI, and PWA identity as
  0.7.2 with the dark catalog logo (`frontend/static/logo-dark.png`) and the
  current product-aligned MCP description.

## [0.7.1] - 2026-08-28

### Changed

- Publish MCP catalog metadata for hosted docs (`https://docsmint.com/docs/mcp`),
  Apache-2.0 license, theme icons, the `npx … docsmint-mcp` stdio entry, and
  Glama connector contact `app.croco.team@gmail.com`.
- Keep `publish-mcp-registry` from tagging until `server.json` and `glama.json`
  pass the catalog validator.

### Documentation

- Tighten the public README around DocsMint 0.7.x, add a product roadmap, and
  align security, usage, architecture, OpenAPI, and CLI display copy with the
  current knowledge-workspace identity.
- Publish the LobeHub claim badge, Apache-2.0 license contract, and an explicit
  MCP Features catalog (17 tools, 2 prompts, 3 resources) for marketplace
  scanners.
- Use `npx -y @hiai-gg/docsmint docsmint-mcp` as the primary MCP install command
  and list the bundled `docsmint-document-manager` Skill so marketplace
  validators can handshake over Node and count the skill.
- Link Docker Hub (`vgalibov/docsmint`) from the README with role-specific
  `docker pull` tags so marketplace listings can treat Docker as an active
  source, matching the GitHub repository link.

## [0.7.0] - 2026-08-24

### Added

- Add trusted, signed category-scoped workspace assertions with independent
  `read`, `edit`, and `write` permissions. Unscoped assertions retain
  workspace-wide, role-derived compatibility.
- Apply direct-or-inherited effective-category authorization before count,
  pagination, index, search, and graph access. Index status requires `read` and
  refresh requires `write`.
- Preserve embedding context identity and recovery state across durable pipeline
  work so stale or legacy work cannot activate an incorrect generation.

### Changed

- Make release metadata, PWA deployment identity, CLI, MCP, Swagger, OpenAPI,
  and every workspace package consistently report 0.7.0.
- Keep hermetic unit, required database integration, Docker health, dependency,
  and release-contract gates fail closed for release preparation.
- Snapshot metadata-driven re-embed targets into a durable PostgreSQL outbox
  while holding the tenant topology lock, then dispatch bounded pages only
  after commit. Each metadata event owns a distinct deterministic generation;
  retained rows recover through set-based database staging and bounded BullMQ
  bulk writes without delaying worker readiness when Redis admission fails.

### Fixed

- Allow document tags, attachments, versions, and embeddings to follow their
  parent document across actors in the same verified workspace while retaining
  personal-owner and foreign-workspace isolation under forced RLS.
- Copy attachment rows and SeaweedFS objects when one workspace actor duplicates
  another actor's document, and repair nullable personal pipeline-batch checks.
- Keep folder, category, and tag metadata snapshots bounded in application
  memory; `*_REEMBED_BATCH_SIZE=0` now selects the safe domain page size rather
  than materializing an unbounded result.
- Preserve document revision and `updatedAt` concurrency fields while staging
  metadata refreshes, make completed outbox retries document-state no-ops, and
  serialize bulk staging with worker document/run row locks to prevent inverse
  lock-order deadlocks.
- Serialize hard document purges and account/benchmark cascade deletion with
  pipeline workers before PostgreSQL locks document pipeline child rows.
- Authorize hard-purge targets before acquiring document pipeline locks, reset
  benchmark owners under one globally ordered lock union, and enforce a durable
  OSS account-purge admission fence. Concurrent document/import/duplicate/
  restore, workspace, attachment, pipeline, API-key, and auth writes can no
  longer escape a completed account purge; guarded REST writes return stable
  `409 ACCOUNT_PURGE_FENCED` responses.
- Repair historical `0037` installs where the AGE session search path placed
  `document_create_operations` in `ag_catalog`; migration `0042` moves or
  creates the durable idempotency table in `public` before enabling its fence.
- Serialize purge-fence enforcement per statement across every direct actor and
  parent-derived owner, guard Better Auth user updates, and keep existing
  pipeline cancellation transitions available without admitting new work.
- Persist every presigned attachment admission before returning its URL, bind
  confirmation and cleanup to an exact signed object key, and keep lifecycle
  purge retryable until issued URLs expire and confirmed or pending SeaweedFS
  objects attributed to the account are durably removed.
- Commit attachment and hard-purge row deletion with an exact storage-cleanup
  outbox intent before touching SeaweedFS. Bounded leased recovery makes object
  deletion and idempotent quota reserve/finalize/release crash-safe across
  concurrent instances, including late PUTs against an already-issued URL.
- Serialize hard purge and restore on the document pipeline advisory, recheck
  `deleted_at` only after that lock, and roll back staged cleanup when the
  final document delete matches zero rows. Attachment deletes join the same
  lock order. Cleanup-outbox insert locks the parent document before requester
  fence subjects. Lease and expiry predicates compare UTC database timestamps
  so a session TimeZone cannot keep an already-expired URL retryable.

## [0.6.8] - 2026-08-21

### Fixed

- Preserve each document's workspace context when an operator queues an
  explicit reindex, so workspace documents can enter the durable knowledge
  pipeline instead of failing its RLS lookup.
- Treat both documented admin authentication forms (`Authorization: Bearer`
  and `x-api-key`) as internal maintenance requests for rate limiting.

## [0.6.7] - 2026-08-20

### Fixed

- Accept secure Better Auth cookies consistently across protected frontend routes.
- Exclude trashed documents before retrieval and graph visibility ranking.
- Require an explicit chat-completion provider for GraphRAG entity extraction.
- Re-embed folder documents after placement changes as well as renames.
- Validate trusted origins through the canonical environment schema and ignore
  empty CORS entries.
- Bind the SeaweedFS operator UI to loopback and keep `.env` out of filesystem
  backup snapshots.

### Documentation

- Align the agent, security, deployment, API, architecture, and self-host
  configuration contracts with the JSON-first 0.6.x product.

## [0.6.6] - 2026-08-20

### Fixed

- Keep the active embedding generation searchable while an explicit document
  reindex creates and prepares its replacement.
- Force admin reindex recovery into a new durable generation, bypass the
  interactive debounce slot, await queue admission, and return `503` instead
  of a false-positive success when admission fails.
- Align the README release summary with the current MCP Registry and knowledge
  pipeline release line.

## [0.6.5] - 2026-08-20

### Fixed

- Aligned the OpenAPI release contract test with the published package and server metadata.

## [0.6.4] - 2026-08-20

### Fixed

- Preserve the canonical Biome formatting required by the backend release
  lint gate.

## [0.6.3] - 2026-08-20

### Fixed

- Match the case-sensitive GitHub organization namespace in npm `mcpName` and
  the official MCP Registry manifest so OIDC ownership validation succeeds.

## [0.6.2] - 2026-08-20

### Added

- Publish the verified `io.github.HiAi-gg/docsmint` identity through
  `server.json`, npm `mcpName`, the public `@hiai-gg/docsmint/mcp` seam, and
  matching stdio and Streamable HTTP registry transports.
- Allow hosts to inject a scoped DocsMint API client into the complete MCP
  capability catalog without importing private server implementation code.

### Changed

- Move the MCP server to the stable Model Context Protocol v2 server package
  while preserving modern and legacy-compatible stdio negotiation.
- Extend packed-package verification to include the MCP registry manifest,
  public capability factory, bundled Skill, prompts, resources, and tools.

## [0.6.1] - 2026-08-20

### Added

- Publish the complete MCP document-manager catalog with 17 tools, two prompts,
  three resources, a bundled Skill, and three documented installation methods.
- Expose transactional document writing and generation-aware reindex controls
  through public OSS contracts.

### Fixed

- Keep global and category API-key permissions consistent across documents,
  categories, folders, tags, GraphRAG, and index operations.
- Supersede failed pipeline generations during full reindexing, release failed
  extraction claims for retry, and prevent stale generations from replacing
  current summaries or graph projections.
- Generate Apache AGE-compatible replacement queries and substitute every
  repeated graph parameter.
- Resolve published frontend imports through canonical hiai-ui exports.

## [0.6.0] - 2026-08-15

### Added

- Stable document cursor sorting by title, category, folder, or updated time
  with canonical category and folder names.
- Public reactive editor preferences and compact TipTap editor entrypoints for
  reusable host writing surfaces.
- Additive `ShareDialog.onCreated` callback and a visible restricted invitation
  URL with an explicit Copy action.

### Fixed

- Keep sidebar Copy and overflow actions visible on touch and coarse-pointer
  devices without changing desktop hover behavior.
- Version standalone PWA caches per deployment and verify the install manifest,
  service worker, offline fallback, and mobile compatibility contract.
- Align README, npm package metadata, GitHub discovery topics, and the complete
  canonical Apache-2.0 license with the 0.6.0 release.

## [0.5.10] - 2026-08-12

### Fixed

- Make the admin re-embedding orchestration test deterministic when the full
  backend suite runs concurrently in CI.

## [0.5.9] - 2026-08-12

### Fixed

- Make the mobile sidebar reliably open by touch and by a wider edge swipe
  without intercepting vertical document scrolling.
- Keep editor formatting, emoji, table, and alignment menus inside the mobile
  viewport and above the editor surface.
- Keep sidebar document actions and category settings directly reachable on
  coarse-pointer Android devices.

## [0.5.8] - 2026-08-11

### Fixed

- Filter authorized and non-deleted search candidates before pagination so
  result pages remain full and totals match visible documents.
- Prevent relative editor image sources from resolving into application
  document routes and exhausting API database connections.

## [0.5.7] - 2026-08-10

### Fixed

- Invalidate scoped single-document Redis entries after saves so an immediate
  reload returns the persisted title and content instead of a stale cache hit.

## [0.5.6] - 2026-08-08

### Fixed

- Route snapshot creation, version history, restore, and diff requests through
  the host-provided request adapter so embedded workspace headers are retained.

## [0.5.5] - 2026-08-01

### Fixed

- Replace the embedded dashboard's native document-delete prompt with the
  branded confirmation dialog.
- Refresh document and folder projections after a trash restore so restored
  items return to navigation and dashboard views without a reload.

## [0.5.3] - 2026-07-28

### Fixed

- Refresh documents, folders, tags, and sidebar navigation immediately after
  successful embedded-host mutations without requiring a page reload.
- Save category API access before issuing a category key so the first key can
  be created in one canonical dialog flow.
- Restore the search filter order to Category, Folder, Tags, and Date, and
  limit folder choices to the selected category, including nested folders.
- Keep GraphRAG and host-provided profile controls inside the canonical
  Advanced settings disclosure.

## [0.5.2] - 2026-07-27

### Added

- Add a backwards-compatible dashboard extension contract for chrome-free and
  full-width host widgets, including packed declaration coverage.
- Add restricted document sharing metadata, per-recipient roles, policy
  versioning, and the supporting database migration without changing existing
  public routes.

### Fixed

- Preserve attachment quota reservation identifiers through the public
  presign/confirm facade and make confirmation retries idempotent by storage
  key.
- Export the global frontend layer contract in the packed stylesheet and keep
  sidebar, popover, modal, and toast ordering consistent in embedded hosts.
- Render dashboard hint cards without empty extension cells so any two visible
  hints share one row with equal sizing.
- Use the canonical hiai-ui Select for restricted-share guest roles, including
  aligned trigger text and chevron.
- Keep embedded sidebar navigation and import routing synchronized with the
  host workspace.

## [0.5.1] - 2026-07-26

- Prevent embedded dashboard and search dropdowns from stretching their host rows by rendering menu content in portals.
- Preserve colored tag indicators in dashboard filters.
- Refresh OSS sidebar categories, folders, and recent documents immediately after host document mutations.
- Keep large Markdown editor hydration regression coverage aligned with the packaged frontend.

## [0.4.1] - 2026-07-21

### Fixed

- Include the request-scoped app-shell adapter and navigation options in the published frontend declaration artifact, so packed SvelteKit consumers receive the same typed contract as the runtime bundle.

## [0.4.0] - 2026-07-21

### Fixed

- Public application hosts now propagate typed route and request adapters through
  the dashboard, search, sidebar, cards, import, share, and command surfaces.
  Embedded consumers can preserve route prefixes and tenant headers without
  rewriting global `window.fetch` or relying on standalone hard-coded routes.

## [0.3.9] - 2026-07-21

### Added

- `DocsmintAppShellHost`, a request-scoped public application shell preserving
  the standalone desktop/mobile sidebar, mobile focus trap, dialogs, editor
  and search preferences, and scroll-to-top behavior for SvelteKit hosts.
- Public `@hiai-gg/docsmint/frontend/styles.css` export, verified directly
  from the packed npm artifact.
- Typed `DocsClient.searchDocuments()` retrieval mode contract for explicit
  GraphRAG (`graph`) or lexical/vector RAG (`rag`) server-side requests.

## [0.3.8] - 2026-07-19

### Added

- Tenant-scoped Trash lifecycle with soft delete, restore, permanent purge, and migration `0039_document_trash`.
- Deleted-document filtering across documents, search, GraphRAG, attachments, versions, folders, tags, visibility, shares, and pipeline paths.
- Configurable `DOCUMENT_TRASH_RETENTION_DAYS` with a safe 30-day OSS default.

### Fixed

- Frontend façade builds now externalize the complete Svelte and SvelteKit consumer-runtime import families, preventing a second bundled Svelte runtime from crossing package host boundaries.
- Packed-package verification rejects bundled Svelte runtime chunks and builds a clean SvelteKit consumer through the public extension-provider, dashboard-host, and component seams.

## [0.3.7] - 2026-07-18

### Added

- Packaging-only public frontend seams for host integrations: attachments, sharing, collaboration, keyboard and folder-refresh state, document tabs, offline identity, drag/drop coordination, and the explicitly named dialog/folder hosts.
- Packed SvelteKit consumer verification for every declared frontend subpath.

### Changed

- Release metadata and package consistency checks now target `0.3.7`.

## [0.3.6] - 2026-07-18

### Fixed

- Restored emitted persistent lifecycle and server-only browser-guard artifacts
  for every declared public package export.
- Bound workspace assertions to a 60-second lifetime and five-second skew.
- Added typed attachment admission and an in-process launcher composition seam
  so tenancy-enabled attachment writes can fail closed before presign.

### Added

- Tables can now be edited after insertion: users can add or remove rows and
  columns, merge a rectangular selection of cells, split merged cells, and
  remove the table from the existing editor table menu.

## [0.3.5] - 2026-07-18

### Added

- `@hiai-gg/docsmint/backend/launcher`, a Bun-only server entrypoint that
  starts the backend bundled inside the published package, exposes readiness
  and shutdown handles, and never resolves checkout-relative source paths.
- `@hiai-gg/docsmint/storage-quota`, an immutable, adapter-backed contract for
  atomic quota reservation, commit, release, idempotency, and typed redacted
  quota rejection.

### Fixed

- The npm tarball now contains runtime JavaScript, declarations, and the
  bundled backend artifact required by both new server-only entrypoints.
- Packed-package verification now imports and typechecks both entrypoints and
  proves that neither can enter a browser bundle.

## [0.3.4] - 2026-07-18

### Added

- GraphRAG is enabled by default for configured installations, with a
  user-controlled Profile switch that can select the faster standard RAG path.
- The authenticated GraphRAG benchmark now compares RAG-only and GraphRAG
  latency and recall without exposing a public query override.

### Fixed

- Mobile dialogs consistently cover persistent navigation and editor chrome,
  while editor menus and the scroll-to-top control use the correct stacking
  and docking order.
- Search preferences can be read by the typed API client without importing a
  Svelte rune module into server-side or package test runtimes.
- Date picker, sharing, editor toolbar, and mobile overlay regressions found
  during release candidate verification.

## [0.3.3] - 2026-07-17

### Fixed

- The published frontend façade declarations now expose the complete extension
  contract and concrete typed API DTOs, inputs, and function signatures.
- The packed-package fixture verifies those declarations from the emitted
  artifact, without resolving frontend source paths at runtime.

## [0.3.2] - 2026-07-16

### Changed

- Public documentation and user-facing metadata now use DocsMint consistently;
  legacy names remain only for documented compatibility identifiers.
- Application, favicon, Apple touch, maskable, and PWA icon assets now use the
  DocsMint mark instead of the former HiAi document logo.

### Removed

- The unstable Raw JSON editor mode and its Settings toggle; existing
  JSON-only preferences safely fall back to the visual editor.

### Added

- Stable server-side lifecycle, workspace assertion, cursor-listing, and
  storage package APIs.

## [0.3.1] - 2026-07-16

### Added

- Tag-driven publication to Docker Hub under
  `vgalibov/docsmint:{api,web,caddy}-<tag>` and matching role-specific
  `latest` tags, alongside the canonical GHCR images.

### Fixed

- Release builds now pass stable PWA application and deployment identifiers to
  the frontend image.
- The npm package whitelist excludes tests, migrations, internal backend
  implementation, generated reports, and repository-only files.
- Root workspace validation scripts now match the commands executed by GitHub
  Actions.

## [0.3.0] - 2026-07-16

### Added

- Installable Progressive Web App support with a manifest, `/sw.js`, offline
  shell, installability prompt, update prompt, responsive mobile shell, and
  configurable branding and icons.
- Identity-partitioned Dexie snapshots for cached offline reads and explicit
  local drafts with saved timestamps, review/apply flow, and conflict recovery.
- Typed frontend host surfaces and additive extension slots for dashboard,
  search, navigation, settings, editor actions, and document tabs.

### Changed

- Standalone UI, repository, and public package are branded as DocsMint.
- Dashboard, editor header, mobile sidebar, raw Markdown, Settings, and recent
  document ordering were refined for narrow screens and PWA use.
- Offline updates use explicit drafts and optimistic `expectedUpdatedAt`
  concurrency; reconnect never silently replays mutations.

### Fixed

- Private API and authenticated navigation responses are network-only and are
  not stored in shared Cache Storage.
- Service-worker registration, offline fallback, host-prefixed cache cleanup,
  logout partition cleanup, and install/update safety were tightened.
- Mobile editor scrolling, Saved status placement, action overflow, and recent
  document ordering were corrected.

### Security

- The public npm package is renamed to `@hiai-gg/docsmint`; the legacy
  `hiai-docs` and `hiai-docs-mcp` binaries remain compatibility aliases.
- Docker publication uses GHCR images
  `ghcr.io/hiai-gg/docsmint-{api,web,caddy}`.
- Licensing changes from MIT to Apache-2.0 across source, package metadata,
  Swagger/OpenAPI, and documentation.

### Migration notes

- `PUBLIC_APP_ID` and `PUBLIC_DEPLOYMENT_ID` define the PWA host/deployment
  boundary; keep them stable per deployment strategy.
- Offline schema upgrades discard legacy mutation-queue rows without replay.
- Existing personal installations remain owner-scoped.

### Breaking changes

- The GitHub repository is now `HiAi-gg/docsmint`; install
  `@hiai-gg/docsmint` and pull `ghcr.io/hiai-gg/docsmint-*` images.
- The project is licensed under Apache-2.0. Existing `hiai-docs` CLI aliases
  remain available throughout the `0.3.x` series.

## [0.2.9] - 2026-07-12

### Added

- Public SvelteKit host components for the dashboard and search surfaces, with
  request-scoped extension providers for DocsMint and other product builds.
- Additive frontend extension slots for dashboard widgets, search widgets,
  navigation links, settings sections, document tabs, and editor actions.
- Deterministic extension ordering, duplicate-id filtering, and safe visibility
  predicates that cannot take down the base application.

### Changed

- Existing HiAi-Docs routes remain thin wrappers around the same page bodies;
  an empty extension manifest preserves the standalone UI and behavior.
- Release creation is idempotent when a GitHub Release already exists for a tag.

## [0.2.8] - 2026-07-12

### Added

- Global owner-wide and category-bound API keys with an explicit, non-hierarchical `read` / `edit` / `write` authorization matrix across documents, folders, search, graph, versions, attachments, tags, sharing, and visibility.
- SDK coverage for category/folder placement, document pipeline status, publish/unpublish, attachment presign/confirm, and session-backed API-key lifecycle operations.
- BullMQ document-processing pipeline with independent prepare, embed, graph,
  summarize, and finalize workers. PostgreSQL is
  the durable source of truth for nonterminal runs while Redis remains the job
  transport.
- One-release legacy embedding-queue bridge documentation and deterministic
  prepare-job migration checks.

### Changed

- API-key lifecycle routes now require a real Better Auth browser session. Global raw secrets remain one-time; category secrets are encrypted at rest and recoverable only by the owning session.
- CLI configuration enforces `0700` directory and `0600` file permissions on POSIX systems; CLI and MCP route contracts and public `bunx` invocation are aligned with the published package.
- Admin and metrics authentication accepts both `x-api-key` and Bearer forms and fails closed when the operator key is unset.
- Release verification now includes worker restart, Redis-loss reconciliation,
  owner isolation, and rollback safety checks.
- Worker scheduling now applies per-owner fairness, bounded per-document fan-out,
  provider concurrency controls, deterministic retry-safe job identifiers, and
  automatic reconciliation after restart.
- The canonical local runtime uses API port `50700` and web port `50701` across
  quickstart, release verification, and browser acceptance instructions.

### Fixed

- TipTap image insertion and resizing now trigger autosave, persist dimensions, and preserve them in shared/PDF and Markdown rendering; rich Markdown export retains images, tables, and legacy table content.
- Editor image resizing uses responsive bounds and persisted width/height attributes, while share rendering and document export keep the selected dimensions.
- The deprecated storage webhook is documented as an inbound signed no-op; false outbound lifecycle-webhook and storage-synchronization claims were removed.
- SvelteKit's production request-body limit now matches the documented import
  contour, allowing requests up to 100 MB to reach the backend while retaining
  the backend's 10 MB per-file limit.
- Pipeline migrations place state tables and enum types in `public`, repair
  objects created under the AGE search path during an earlier candidate run,
  and grant the runtime role only the required access.
- Empty documents and optional graph/summarization failures reach deterministic
  terminal states without blocking usable embeddings.

### Migration Notes

- Apply the complete Drizzle journal (`0000–0030`) before starting the API.
  Migration `0030` safely repairs pipeline objects created under the AGE schema
  by an earlier unreleased candidate.
- The verified candidate passed fresh-database and upgraded-database migration
  checks while preserving legacy documents and 1024-dimensional embeddings.
- Tagging, pushing, npm/Docker publication, and the GitHub Release remain
  explicit release actions after CI and operator browser acceptance.

## [0.2.7] - 2026-07-11

### Added

- **Adaptive multilingual search**: exact/title, multilingual lexical, fuzzy,
  vector, one-pass query expansion, and automatic GraphRAG retrieval are
  combined with reciprocal rank fusion (RRF).
- **Search explanations and chunks**: results expose bounded channel and graph
  contribution metadata, with request-scoped chunk hydration for authorized
  documents.
- **Generation-aware embeddings**: embedding generations use explicit
  pending/processing/ready/failed/stale states and atomic activation, while
  enforcing finite, non-zero 1024-dimensional vectors.
- **Relevance benchmark and observability**: the release contour includes
  tenant-scoped benchmark credentials, latency/relevance gates, and bounded
  search metrics without credentials in process arguments.

### Fixed

- **GraphRAG safety**: graph seeds are visibility-authorized before traversal,
  Cypher inputs use safe dollar-quoted values, and graph failures degrade to
  direct search results without leaking tenant data.
- **Share and pagination scope**: public/share search preserves document
  visibility while hydrating global authorized totals and page slices correctly.
- **Embedding test isolation**: provider tests no longer inherit process-global
  integration mocks, keeping the full suite deterministic.

### Migration Notes

- Apply the complete Drizzle journal (`0000–0026`) before enabling search
  generations or reindexing embeddings. The reference PostgreSQL image includes
  AGE and vector extensions required by the migrations.
- This candidate has passed fresh-database, upgraded-database, and live GraphRAG
  verification. Tagging and publication remain explicit release actions.

## [0.2.6] - 2026-07-10

### Fixed

- **Public share attachments**: protected document images are fetched with the share token and rendered through revocable blob URLs instead of anonymous raw URLs that returned `401`.
- **Public rich-text rendering**: paragraph/heading alignment, bullet lists, ordered-list start values, and task lists now share one tested ProseMirror renderer. Invalid block nodes from older imports are flattened inside headings instead of producing browser-rewritten HTML.
- **Public share hardening**: Markdown fallback and export HTML now pass through the same escaped renderer, and unsafe link protocols are rejected.
- **Audit RLS**: audit events are inserted inside a tenant transaction. Migration `0020_fix_audit_log_rls.sql` permits actors to append their own events, restricts reads to admins, and keeps update/delete unavailable.
- **SeaweedFS runtime**: production and development Compose files now generate the supported S3 identity configuration, use the filer health endpoint, and keep application traffic on the non-superuser `hiai_app` database role.
- **Attachment streaming**: async-iterable S3 bodies are consumed before AWS transform helpers, avoiding Bun runtime incompatibilities.
- **Release stability**: the metrics route test no longer binds an ephemeral host port, category API-access validation matches the current contract, and the session schema includes the already-migrated revocation fields.

### Changed

- Version synchronized to `0.2.6` across all workspace packages, the public package manifest, Swagger, OpenAPI, and release metadata.

### Migration Notes

- Run `bun run db:migrate` after upgrade to apply migration `0020_fix_audit_log_rls.sql`.

## [0.2.5] - 2026-07-09

### Fixed

- **Attachments raw streaming**: the `GET /api/attachments/:id/raw` route now reads SeaweedFS/S3 bodies through a runtime-agnostic body reader, so it handles both WHATWG streams and async-iterable S3 bodies during raw attachment downloads and integrity probes.
- **Editor toolbar list/alignment**: list toggles now fall back cleanly when the current TipTap command surface differs, and left alignment clears text alignment through `unsetTextAlign()` when available.
- **DOCX serializer**: paragraph/heading alignment handling is tightened and the serializer no longer relies on loose `any` typing for the local node/mark helpers.
- **Sidebar share actions**: folder and document menus now open the share dialog from the sidebar, with share state wired through the tree component.

### Changed

- Version bumped from `0.2.4` to `0.2.5` across workspace manifests, `package.public.json`, Swagger/OpenAPI, and production status metadata.

## [0.2.4] - 2026-07-08

### Fixed

- **package.public.json — broken export paths**: Three new v0.2.3 exports (`./backend/lib/rate-limit`, `./backend/lib/api-keys`, `./backend/lib/audit`) used `backend/...` paths missing the `./` prefix. Published package would fail to resolve these imports. Paths corrected to `./backend/...` to match all other exports.
- **docs/API.md — API keys mismatch**: Documented `expiresIn` duration field, but code uses `expiresAt` ISO 8601 datetime. Docs updated to match actual code behaviour.
- **docs/API.md — plugins response shape mismatch**: Documented `displayName`/`enabled` fields that do not exist in the `PluginManifest` type. Actual shape is `name`/`version`/`description`. Docs updated to match code.
- **docs/PRODUCTION_STATUS.md — route count**: Stale count of 14 route files. Actual count is 17 (added keys, plugins, visibility in v0.2.3). Corrected.

### Changed

- Version bumped from `0.2.3` to `0.2.4` across all workspace manifests: root `package.json`, `package.public.json`, `backend/package.json`, `frontend/package.json`, `packages/{sdk,cli,mcp-server,db}/package.json`, `backend/src/index.ts` (Swagger), `docs/openapi.json`, `docs/PRODUCTION_STATUS.md`.

## [0.2.3] - 2026-07-08

### Added

- **Chunk offsets** (HIAI-1): charStart/charEnd tracking through the embedding pipeline
- **Search chunks** (HIAI-2): `includeChunks` parameter in search to get top-3 chunk snippets per result
- **API keys** (HIAI-3): create, list, revoke, and Bearer-auth user API keys with scopes and expiry
- **Document visibility** (HIAI-4): public/private/shared visibility per document with RLS for public reads
- **Editor plugins** (HIAI-5): read-only Plugin Registry API exposing available editor plugins
- **Reusable rate-limit factory** (HIAI-6): extracted `createRateLimiter` to backend lib for external consumers
- **Share roles** (HIAI-7): viewer/commenter/editor roles on share links with PATCH endpoint
- **Audit log** (HIAI-8): append-only audit trail with admin query endpoints and fire-and-forget integration

### Changed

- ChunkResult extended with charStart/charEnd positional tracking
- Search response extended with optional `chunks` array per document
- Rate-limit middleware now re-exports from reusable lib factory
- Share link schemas accept `role` parameter (default viewer)
- API key auth integrated into auth pipeline (admin key → user API key → Better Auth)

### Security

- API key Bearer auth for user-scoped API access
- Document visibility RLS: public documents readable by all authenticated users
- Audit trail records document/share/API-key lifecycle events

### Migration Notes

- New migrations: 0014 (chunk offsets), 0015 (api_keys table), 0016 (document visibility enum), 0017 (share roles), 0018 (audit_log table)
- Run `bun run db:migrate` after upgrade

## [0.2.2] - 2026-07-07

### Fixed

- **README.md — stale GraphRAG health note**: The note referencing "v0.1.8" and the "AGE shared library auto-loading known gap" was replaced with accurate v0.2.2 wording confirming all GraphRAG audit findings (G1–G9, N1) are resolved. GraphRAG remains optional/off by default and requires explicit `GRAPH_EXTRACT_BASE_URL` for production.
- **docs/PRODUCTION_STATUS.md — test count wording**: Changed "459 base + 3 N1 graph-routes" to the generic "backend/core + frontend" to stay accurate across releases.
- **Version bump**: All workspace packages, CLI, MCP server, Swagger/OpenAPI spec, and docs updated from `0.2.1` to `0.2.2`.

### Changed

- All workspace `package.json` files, `package.public.json`, `packages/sdk/package.json`, `packages/cli/package.json`, `packages/mcp-server/package.json`, `backend/src/index.ts` (Swagger version), `docs/openapi.json`, and `docs/PRODUCTION_STATUS.md` updated to `0.2.2`.

### Documentation

- Stale `v0.1.8`-era GraphRAG language removed from `README.md`. Historical references left intact only where clearly dated/historical (CHANGELOG entries).

## [0.2.1] - 2026-07-07

### Fixed

- **GraphRAG N1 — graph route (`graph.ts`) cypher bind parameter**: `fetchDocumentEntities` in `backend/src/api/routes/graph.ts` used the postgres-js tagged-template form `sql\`...${...}\`` which passes the cypher string as a bind parameter (`$1`). AGE's `cypher()`rejects bind parameters — it requires a literal dollar-quoted string constant. Replaced with`sql.unsafe()`using`$$ ... $$`dollar-quoting, matching the pattern used in`search-expansion.ts`(G7 fix),`extract-entities.ts`, and `admin.ts`.
- **docs/GRAPHRAG_AUDIT.md**: Post-Audit Resolution table updated with N1 fix documentation; remaining risks section cleaned to remove false claims of unresolved CRITICAL/HIGH items.
- **docs/PRODUCTION_STATUS.md**: Updated to v0.2.1 verified status, removing stale v0.1.8 references.
- **docs/openapi.json**: Stale version `0.1.9` corrected to `0.2.1`.
- **packages/sdk/package.json**: Stale version `0.1.9` corrected to `0.2.1`.

### Added

- **Test coverage for N1**: `backend/src/__tests__/graph-routes.test.ts` (3 tests) — verifies `sql.unsafe()` is called with `$$` dollar-quoted cypher, graceful return of `[]` when AGE is unreachable, and special-character docId escaping via JSON.stringify.

### Changed

- All workspace packages, CLI, MCP server, Swagger/OpenAPI spec, and docs version references updated to `0.2.1`.

## [0.2.0] - 2026-07-07

### Breaking Changes

- **MinIO → SeaweedFS migration**: MinIO completely removed as the object storage backend. SeaweedFS (chrislusf/seaweedfs:3.85) is now the only supported storage backend.
- **Config rename**: All `MINIO_*` environment variables renamed to `STORAGE_*` (e.g., `MINIO_ENDPOINT` → `STORAGE_ENDPOINT`, `MINIO_SECRET_KEY` → `STORAGE_SECRET_KEY`). See `.env.example` for the full list.
- **DB schema rename**: `attachments.minio_key` column renamed to `attachments.storage_key` (migration `0013_rename_minio_key_to_storage_key.sql`).
- **npm package change**: `minio` npm dependency replaced with `@aws-sdk/client-s3` and `@aws-sdk/s3-request-presigner`. Exports path `./backend/lib/minio` renamed to `./backend/lib/storage`; `createMinio` renamed to `createObjectStorageClient`.
- **Docker Compose**: MinIO service replaced with SeaweedFS S3 Gateway service. Volume `minio_data` renamed to `seaweedfs_data`.
- **Webhook**: `POST /api/webhooks/minio` replaced with `POST /api/webhooks/storage` as a no-op stub (SeaweedFS does not emit MinIO-compatible bucket notifications).
- **Health check**: MinIO health endpoint removed from `/api/health`; SeaweedFS S3 liveness check added.

## [0.1.9] - 2026-07-03

### Documentation

- Updated all docs to reflect v0.1.8 architecture (B.1/B.4/B.3 refactors)
- Fixed DATABASE_URL default port (5433 → 5437) in config-schema.ts
- Added subpath import examples to README
- Documented factories and module boundaries in ARCHITECTURE.md
- Added missing env vars to DEPLOYMENT.md and README
- Documented /api/admin/metrics endpoint in API.md
- Fixed PRODUCTION_STATUS.md version (v0.1.6 → v0.1.8)

## [0.1.8] - 2026-07-03

### Fixed

- **Pure DI factories** — `createRedis` and `createMinio` (+`ensureBucket`) extracted into `backend/src/lib/redis-factory.ts` and `minio-factory.ts`. These new modules import only `ioredis`/`minio`/`pino`-logger — **no `./config` import**, so no `envSchema.parse` + `process.exit(1)` runs when an external consumer (e.g. docsmint) imports them. The npm subpath exports `./backend/lib/redis` and `./backend/lib/minio` now resolve to these factory files. The original `redis.ts`/`minio.ts` keep their hiai-env-gated singletons for the internal runtime and re-export the factories for backwards compatibility.
- **peerDependencies** — `ioredis`, `minio`, `pino`, `zod` added to `package.public.json` (all optional). Previously a docsmint `import { createRedis } from '@hiai-gg/hiai-docs/backend/lib/redis'` failed to resolve `ioredis` because it was undeclared.
- **bin/files mismatch** — `packages/cli/src` and `packages/mcp-server/src` were removed from `files[]` in v0.1.6 but the `bin` field still pointed at them. Re-added so `npx hiai-docs` / `npx hiai-docs-mcp` work again.
- **`adminTenantContext`** now accepts an optional `ownerId` parameter; the host middleware passes `config.OWNER_ID` explicitly so `packages/db` no longer needs to read `process.env` directly (the env fallback remains for stand-alone use).

## [0.1.7] - 2026-07-03

### Features

- **B.1**: RLS client (withTenant, TenantContext, adminTenantContext, shareGuestTenantContext) moved to packages/db for shared use
- **B.4**: redis and minio refactored to factory functions (createRedis, createMinio) with backwards-compatible singletons
- **B.3**: package.public.json updated with subpath exports for db/client, db/with-tenant, backend/lib/redis, backend/lib/minio, backend/lib/logger

## [0.1.6] - 2026-07-02

### Fixed

- **npm export cleanup** — removed five broken or unnecessary export paths from `package.public.json`:
  - `./auth` was non-functional: `backend/src/lib/auth.ts` imports `@hiai-docs/db`, a `private` workspace package that is not published to npm and therefore cannot be resolved by external consumers. Removed rather than fixed — auth is a server-internal concern and does not belong in the public package surface.
  - `./db` exposed `packages/db/src/index.ts`, which instantiates a `postgres()` connection with a hardcoded `localhost:5433` fallback. This is an internal database client, not a public API. The `./schema` export already covers the Drizzle table definitions that external consumers need.
  - `./backend/*`, `./frontend/*`, `./packages/*` were unscoped wildcard exports that leaked the entire monorepo source tree. No documented use case existed for these paths.
- **`files[]` tightened** — removed `packages/cli/src`, `packages/mcp-server/src`, `backend/src`, `frontend/src` from the published tarball. These directories had no corresponding clean export paths and added ~1 MB of raw TypeScript to the npm package without benefit to consumers.
- **`RELEASE_CHECKLIST.md` version-bump count** corrected from 6 to 8 — `packages/cli/package.json` and `packages/mcp-server/package.json` were omitted from the bump target list.
- **Script file modes** — restored executable permission (`chmod +x`) on `scripts/health-check.sh`, `scripts/migrate.sh`, and `scripts/release.sh`; normalized line endings to LF.

### Added

- **"Option 2: npm SDK" section** in `README.md` — makes it explicit that `bun add @hiai-gg/hiai-docs` installs a programmatic API client, not a deployable server. Includes `DocsClient` quickstart and a table of supported import paths.
- **"For Builders: Extension Points" section** in `README.md` — documents the stable integration surfaces (REST API, MCP server, Drizzle schema import, webhooks) and a "core vs. downstream" boundary table.
- **Extension Guide** in `CONTRIBUTING.md` — code examples for all three integration surfaces and an explicit list of what should not be added to core.
- **`bin` entries** in `package.public.json` — CLI (`hiai-docs`) and MCP server (`hiai-docs-mcp`) are now properly exposed as runnable binaries:
  - `bunx --package @hiai-gg/hiai-docs hiai-docs <command>` — terminal CLI (search, list, read, create, update, delete, folders, history, snapshot, restore, export, config)
  - `bunx --package @hiai-gg/hiai-docs hiai-docs-mcp` / point a source-checkout MCP client at `packages/mcp-server/src/index.ts` — stdio MCP server with 10 tools for AI agents

## [0.1.5] - 2026-07-02

### Fixed

- **npm `files` whitelist** in `package.public.json` now lists explicit per-package source directories (`packages/db/src`, `packages/cli/src`, `packages/mcp-server/src`, `backend/src`, `frontend/src`) instead of the non-recursive glob `packages/*/src`. The glob was silently omitting `packages/db/src`, which broke the `./db` and `./schema` subpaths in the published tarball.
- **Added `./auth` export** pointing to `backend/src/lib/auth.ts` so consumers can import the configured Better Auth instance directly. _(Reverted in 0.1.6 — the export was non-functional due to an unresolvable `@hiai-docs/db` workspace reference.)_

### Changed

- **Version synchronization** — all workspace packages, CLI, MCP server, Swagger/OpenAPI spec, and `docs/openapi.json` now report `0.1.5`.

## [0.1.4] - 2026-07-02

### Changed

- **Frontend UI migration** — migrated the frontend to consume `@hiai-gg/hiai-ui` as the shared UI component library, replacing direct local shadcn-svelte imports where the design system provides equivalent components.
- **Version synchronization** — all workspace packages, CLI, MCP server, Swagger/OpenAPI spec, and `docs/openapi.json` now report `0.1.4`.

## [0.1.3] - 2026-07-02

### Changed

- **Publishable package manifest** (`package.public.json`) now exposes `./db`, `./schema`, `./backend/*`, and `./frontend/*` subpaths, plus wildcard exports for `./packages/*`.
- **SDK dependency cleanup** — removed the `zod` dependency from `packages/sdk` (it was unused; runtime types remain pure TypeScript interfaces).
- **Version synchronization** — all workspace packages, CLI, MCP server, Swagger/OpenAPI spec, and `docs/openapi.json` now report `0.1.3`.

## [0.1.2] - 2026-07-02

### Performance

- **HNSW vector index now used in semantic search** — the inner query finds top-k chunks by vector distance (using the HNSW index), and the outer query joins + deduplicates. Previously, `ORDER BY d.id, distance` put the document ID first, preventing the planner from using the HNSW index. Fixes **G3** from the GraphRAG audit.
- **AGE search-expansion uses `client.unsafe()`** — Cypher queries in `search-expansion.ts` now use `client.unsafe()` with dollar-quoting instead of postgres-js bind parameters. Fixes **G7** from the GraphRAG audit.
- **Frontend Dockerfile optimization** — multi-stage Dockerfile now separates dependency stages from runtime, reducing final image size and attack surface. Fixes **Item 16** from the production audit.

### GraphRAG

- **AGE shared library auto-loading** — `postgres/init.sql` now adds `ALTER DATABASE current_database() SET session_preload_libraries = 'age'` to load the AGE library on every session. Remaining graph-discoverable issues tracked in GRAPHRAG_AUDIT.md.
- **Entity extraction refactored** — `extract-entities.ts` rewritten for cleaner error handling, Ollama-compatible endpoint path construction, and more robust entity parsing.
- **Graph migration `001_init.sql`** — updated with AGE library preloading and index improvements.

### Config & Security

- **Config schema hardening** — `BETTER_AUTH_SECRET`, `CSRF_SECRET`, and `WEBHOOK_SECRET` now have explicit `.min(1)` guards to reject empty strings in any environment, complementing the existing production-only `refine()` guards.
- **`docker-compose.yml` DB port default** — changed from `5433` to `5437` for consistency with `.env.example` and dev-compose. CSRF/WEBHOOK_SECRET now have `${:-default}` fallbacks in compose.

### Documentation

- **Full documentation audit sweep** — all documentation files updated to reflect v0.1.1+ reality:
  - Ports unified across AGENTS.md, design-spec.md, DEPLOYMENT.md, PRODUCTION_STATUS.md (DB: 5437, Redis: 6384, MinIO console: 9021, Caddy: 80/443).
  - Editor references updated from Tipex → svelte-tiptap + TipTap v3 in design-spec.md.
  - PRODUCTION_AUDIT.md fully translated from Russian to English; all 19 audit items annotated with resolution status.
  - GRAPHRAG_AUDIT.md banner added; G2 and G8 marked as fixed.
  - DEPLOYMENT.md gained full env var tables for GraphRAG, hybrid search, chunking, re-embed batch caps, and attachments; secret hygiene policy documented.
  - README.md added GraphRAG health caveat.
  - AGENTS.md Docker services table updated to reflect current images and ports; secret management rules confirmed.
  - CHANGELOG cross-check verified and confirmed.

### Changed

- **`backend/src/lib/config-schema.ts`** — added `.min(1)` guards to BETTER_AUTH_SECRET, CSRF_SECRET, WEBHOOK_SECRET.
- **`backend/src/api/routes/search.ts`** — `semanticSearch` now uses a two-stage query for HNSW index utilization.
- **`backend/src/lib/graph/extract-entities.ts`** — major refactoring for robustness and Ollama-compatible endpoints.
- **`backend/src/lib/graph/search-expansion.ts`** — switched to `client.unsafe()` for Cypher queries.
- **`docker-compose.yml`** — DB_PORT default 5437; CSRF/WEBHOOK_SECRET compose defaults; frontend Dockerfile updated.
- **`packages/db/src/schema.ts`** — schema refinements.
- **`postgres/init.sql`** — AGE session_preload_libraries added.
- **`backend/src/__tests__/config.test.ts`** — expanded test coverage for config schema.

## [0.1.1] - 2026-07-01

### Security & Config

- **Dependency pinning** — replaced all ~80 `"latest"` specifiers with pinned semver ranges across all package.json files. `bun.lock` is now checked into version control for reproducible builds.
- **Production hardening** — `docker-compose.yml` now defaults `NODE_ENV` to `production` (overridable via `${NODE_ENV:-production}`). All hardcoded config values (graph, chunk, batch params) are now `${VAR:-default}` parameterized at the compose level.
- **Secrets hygiene** — `.env.example` no longer contains real cryptographic secrets. All keys replaced with `change-me` placeholders and `# CHANGE-ME` comments.
- **Caddy auto-TLS** — port mapping changed from `50708:80`/`50709:443` to standard `80:80`/`443:443`. Custom Dockerfile builds Caddy with `caddy-ratelimit` module via xcaddy.
- **Config schema guards** — `CSRF_SECRET` and `WEBHOOK_SECRET` now have production-only `refine()` guards (like `BETTER_AUTH_SECRET`), rejecting default values in production.
- **Cookie compatibility** — explicit `"cookie": "^0.6.0"` dependency pinned in frontend for SvelteKit build compatibility.
- **Port alignment** — `scripts/health-check.sh` defaults corrected: `REDIS_PORT` → 6384, `DB_PORT` → 5437 (matching compose defaults).
- **CI registry fix** — Docker Hub push target is `vgalibov/hiai-docs` (the `hiai-gg/hiai-docs` registry does not exist yet on Docker Hub; `RELEASE_CHECKLIST.md` documents this as the working fallback until the `hiai-gg` org is created).
- **MinIO image pinning** — `minio/minio:latest` → `minio/minio:RELEASE.2025-06-26T16-23-29Z` in both compose files.

## [0.1.0] - 2026-06-28

### Highlights

- **Unified PostgreSQL image (`hiai-postgres:18-custom`)** — pgvector + pgvectorscale + Apache AGE now live in a **single** PostgreSQL 18 database. Replaces the previous split between `pgvector/pgvector:pg18` (port 5437) and `apache/age:release_PG18_1.7.0` (port 5438). The custom image is defined in `postgres/Dockerfile` and the migration is idempotent (`postgres/init.sql`).
- **pgvectorscale (StreamingDiskANN)** — vector index upgrades. The image now ships `vector 0.8.3`, `vectorscale 0.9.0`, and `age 1.7.0` together. Switching index access method is a one-line DDL change (`USING diskann (embedding vector_cosine_ops)`) for >100k row corpora. Binary quantization (`SbqCompression`) is enabled by default in the index build.
- **Simplified deployment** — no more `age-postgres` service, `age_pgdata` volume, or `AGE_DATABASE_URL` env var. `docker compose up -d` brings up one image, one volume, one connection string.

### Added

- `postgres/Dockerfile` — multi-stage build: `builder` (pgvector from source, pgvectorscale via cargo pgrx 0.16.1) → `age_src` (prebuilt Apache AGE binaries from `apache/age:release_PG18_1.7.0`) → runtime (`postgres:18.1` base). AGE 1.7.0 is built against PG 18.1, so we pin the runtime to the same major to keep the glibc ABI aligned.
- `postgres/init.sql` — installs `vector`, `vectorscale`, `age`, `pg_trgm`, creates the `docs_graph` property graph, and sets `search_path = ag_catalog, public` so application code can call `cypher('docs_graph', $$ ... $$)` without schema-qualifying.
- `idx_document_embeddings_diskann` — StreamingDiskANN index on `document_embeddings.embedding` with `SbqCompression`. Co-exists with the existing HNSW index; choose per workload.
- `backend/src/lib/db.ts` — exports the raw `client` (`postgres.Sql`) alongside the Drizzle wrapper, so `lib/graph/*` can call raw `cypher()` while everything else still uses the typed Drizzle API.
- `backend/src/lib/graph/init.ts` — rewritten to use the shared Drizzle client. The module-level AGE-specific connection pool and `closeGraph()` lifecycle are gone; the lazy `getGraphDb()` still memoizes the init result so the migration only runs once per process.

### Changed

- **`backend/src/lib/graph/extract-entities.ts`** and **`search-expansion.ts`** — removed the `if (!config.AGE_DATABASE_URL)` early-return guards. The shared client is always available, so graph code paths now run as long as `GRAPH_*_ENABLED` is true and the `age` extension is installed.
- **`backend/src/api/routes/admin.ts`** — `graph/stats` no longer branches on `AGE_DATABASE_URL`. It reports `available: false` only when `GRAPH_*_ENABLED` is false or `getGraphDb()` returns `null` (extension missing).
- **`backend/src/api/routes/admin.ts`** — fixed the Cypher `graph/stats` query that was quoting Cypher bodies with `'' ''` (illegal in a bun-tagged SQL template). Now uses `$$ ... $$` dollar-quoting, the form AGE accepts.
- **`docker-compose.yml`** — `age-postgres` service and `age_pgdata` volume removed. The `postgres` service now builds from `postgres/Dockerfile` (`build: { context: ./postgres }`) and exposes the unified image. The `api` service's `environment` block drops `AGE_DATABASE_URL` and the dead `AGE_DB_*` env vars and gains `AGE_DATABASE_URL` removed.
- **`Dockerfile.backend`** — copies `backend/src/lib/graph/migrations/001_init.sql` into the runtime image so the AGE migration can be found relative to `lib/graph/init.ts` in the compiled bundle.
- **`.env`** and **`.env.example`** — `AGE_DATABASE_URL`, `AGE_DB_PORT`, `AGE_DB_NAME` removed. The GraphRAG config block now documents the unified-DB layout.
- **`postgres/init.sql`** — the `ALTER DATABASE ... SET search_path` is no longer enough on its own; the script also issues a session-level `SET search_path = ag_catalog, public` so the very first `docker-entrypoint-initdb.d` invocation can call `create_graph()` and resolve `agtype` / `graphid_ops` without a `DROP EXTENSION` workaround.
- **`backend/src/__tests__/graph-init.test.ts`** — rewritten to assert the new contract (`getGraphDb` returns the shared client or `null`).
- **`backend/src/scripts/benchmark-graph.ts`** — updated the AGE-availability check message to reflect the unified-DB layout.

### Removed

- `docker-compose.dev.yml` / `docker-compose.yml` — `age-postgres` service, `age_pgdata` volume, and `AGE_DATABASE_URL` env propagation.
- `backend/src/lib/config.ts` — `AGE_DATABASE_URL` Zod field.
- `backend/src/lib/graph/init.ts` — `closeGraph()` and the `GraphSqlClient` re-export (callers now import `postgres.Sql` directly when they need the type).

### Migration notes

- The previous two-container layout (`pgvector/pgvector:pg18` + `apache/age:release_PG18_1.7.0`) is gone. Single volume `pgdata` now holds the unified database; restore from a pre-migration `pg_dump` is fine — the table schema is unchanged.
- For a fresh deployment, `docker compose up -d` will build the unified image, run the migrations, and seed the AGE graph automatically.
- If you are upgrading an existing deployment: `docker compose down`, `docker volume rm hiai-docs_pgdata hiai-docs_age_pgdata` (after backing up with `pg_dump`), then `docker compose up -d`. The 5438 port is no longer used.

## [v0.1.0] - 2025-06-28

### Highlights

- **Smart Re-embed System** — automatic vector refresh on metadata changes (tags, folders, categories) with Redis-deduplicated batch processing to prevent embedding storms
- **Incremental Chunk Updates** — hash-based chunk comparison ensures only changed content is re-embedded; overlap regions maintain semantic continuity
- **GraphRAG with Apache AGE** — optional entity extraction and graph-based search expansion for discovering related documents beyond vector similarity
- **Chunk Versioning** — `embedding_model` column tracks which model produced each vector, enabling targeted reindex operations when models change
- **Admin Tooling** — comprehensive `/api/admin/*` endpoints for reindexing, embedding stats, provider health checks, and AGE inventory queries
- **Security & Performance** — tenant scoping controls (`ADMIN_CROSS_TENANT`, `?ownerId=`) and batch caps prevent resource spikes

### Added

- **`document_embeddings.embedding_model` column** (migration `0006_embedding_model_column.sql`). Records which model produced each vector and is indexed for fast targeted reindex. Existing rows default to `""` (model unknown) and are treated as candidates for reindex once a model is configured.
- **`POST /api/admin/reindex/model?dryRun=true`** — targeted re-embed for documents whose stored `embedding_model` does not match the currently configured `EMBEDDING_MODEL`. After upgrading embedding model, run with `?dryRun=true` first to preview the affected count, then commit with `?dryRun=false`.
- **`GET /api/admin/graph/stats`** — Apache AGE inventory (node and edge counts). Returns `{ available: false, reason: "..." }` when GraphRAG is disabled or unreachable.
- **`POST /api/admin/reindex/folder/:folderId?dryRun=true`** — bulk re-embed every document in a folder (operator-scoped, bypasses per-user filter).
- **`POST /api/admin/reindex/tag/:tagId?dryRun=true`** — bulk re-embed every document carrying a tag.
- **Search query parameters**: `graph` (boolean, default `false`), `graphHops` (1-3, default `2`), and deprecated ignored `graphBoost` (0-2). `graph=true` is a no-op when `GRAPH_SEARCH_ENABLED=false`.
- **New environment variables**:
  - `FOLDER_REEMBED_BATCH_SIZE` (default `100`)
  - `CATEGORY_REEMBED_BATCH_SIZE` (default `100`)
  - `TAG_REEMBED_BATCH_SIZE` (default `500`)
  - `GRAPH_EXTRACT_ENABLED` (default `false`)
  - `GRAPH_SEARCH_ENABLED` (default `false`)
  - `GRAPH_EXTRACT_MODEL`, `GRAPH_EXTRACT_BASE_URL`, `GRAPH_EXTRACT_API_KEY`
  - `GRAPH_EXTRACT_FALLBACK_BASE_URL`, `GRAPH_EXTRACT_FALLBACK_API_KEY`, `GRAPH_EXTRACT_FALLBACK_MODEL`
  - `GRAPH_EXTRACT_MIN_CONFIDENCE` (default `0.5`)
  - `AGE_DATABASE_URL` (optional)
  - `HYBRID_TEXT_WEIGHT` (default `0.4`)
  - `HYBRID_SEMANTIC_WEIGHT` (default `0.6`)
  - `CHUNK_TARGET_TOKENS` (default `500`)
  - `CHUNK_OVERLAP_TOKENS` (default `50`)
- **`backend/src/lib/reembed.ts`** — shared re-embed helper (`enqueueReembed`, `reembedDocsInFolder`, `reembedDocsInCategory`, `reembedDocsByTag`) used by every metadata-triggered path. Coalesces rapid PATCH / toggle storms via a Redis `SET NX EX 5` dedup slot.
- **`reembedDocsInFolderAdmin(folderId)`** in `backend/src/lib/reembed.ts` — operator-scope variant of `reembedDocsInFolder` that does not filter by `owner_id`. Used by the admin folder reindex endpoint so cross-user reindex actually fires.
- **Unit tests** at `backend/src/__tests__/reembed.test.ts` covering dedup semantics, Redis SET-NX behavior, best-effort fallback when Redis is unavailable, and a smoke test for `reembedDocsInFolderAdmin`.

### Changed

- **Re-embed on metadata changes is now system-wide.** Tag rename, tag delete, category rename, category delete, folder delete — all trigger a re-embed of every affected document through the shared helper. Previously several of these paths silently left stale embeddings that referenced old metadata names in their preamble.
- The embedding worker now writes `embeddingModel: config.EMBEDDING_MODEL ?? ""` on every new chunk row, so subsequent targeted reindex has a precise signal. The local `rows` type annotation in the worker transaction includes `embeddingModel: string` to match.
- `PATCH /api/documents/:id` re-embed path uses `enqueueReembed` (with Redis SET-NX dedup) instead of going straight to `enqueueEmbedding`. A rapid PATCH storm on the same document now coalesces into a single worker tick.
- GraphRAG uses the bounded `SEARCH_GRAPH_MAX_CONTRIBUTION` ranking input. Deprecated `graphBoost` remains accepted as an ignored compatibility input.
- `reembedDocsInCategory` unions documents directly attached to the category AND documents in folders attached to the category, because the embedding preamble resolves category name from either path. The `CATEGORY_REEMBED_BATCH_SIZE` cap applies to the merged set.

### Fixed

- **B-1** — category rename left stale embeddings referencing the old category name. Now triggers re-embed via the shared helper.
- **B-2** — category delete left stale embeddings. Now triggers re-embed via the shared helper.
- **B-3** — folder delete left stale embeddings. Now triggers re-embed via the shared helper.
- **B-5** — tag rename left stale embeddings (the prior "Wave 1b" claim was never merged into HEAD). Now triggers re-embed via the shared helper.
- **B-6** — tag delete left stale embeddings. Now triggers re-embed via the shared helper.
- **B-7** — `POST /api/admin/reindex/folder/:folderId` (non-`dryRun` branch) passed an empty `owner_id` to the user-scoped `reembedDocsInFolder(folderId, ownerId)` helper, which matched zero documents and queued nothing — a silent failure with HTTP 200 and `{ success: true, affected: 0 }`. Fixed by adding a dedicated operator-scope helper `reembedDocsInFolderAdmin(folderId)` in `backend/src/lib/reembed.ts` that bypasses the `owner_id` filter and re-uses the same batch cap + Redis dedup semantics.

### Removed

- Local `reembedDocumentsInFolder` helper in `backend/src/api/routes/folders.ts` — superseded by the shared `reembedDocsInFolder` in `backend/src/lib/reembed.ts`.

### Migration notes

- Apply `packages/db/src/migrations/0006_embedding_model_column.sql` (idempotent — `ADD COLUMN ... DEFAULT '' NOT NULL` is safe on populated tables).
- After changing `EMBEDDING_MODEL` in `.env` and restarting the API, run `POST /api/admin/reindex/model?dryRun=true` to preview affected docs, then commit with `dryRun=false` (or omit the flag).
- Operators who relied on tag / category / folder mutations NOT triggering re-embed will see new behavior — this is intentional, but the batch caps (`*_REEMBED_BATCH_SIZE`) keep the per-tick cost bounded.
- After upgrading to this release, `POST /api/admin/reindex/folder/:folderId?dryRun=false` finally enqueues documents as the API surface advertises. Operators who worked around the previous silent failure by using `POST /api/admin/reindex/model` directly can switch back to the folder-scoped endpoint.

### Validation status at close

- `tsc --noEmit` clean across all touched packages (and across `reembed.ts`, `admin.ts`, `worker.ts`, `reembed.test.ts` in particular).
- One pre-existing error remains in `backend/src/lib/graph/extract-entities.ts(585,1)` — a stray `\t` literal that pre-dates this work. Tracked separately.
- `bun test` not executed in the development environment (no Bun runtime available); run locally before commit.