CHANGELOG.md
Rama main · réplica de lectura del repositorio original.
# 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.