Skip to content
This repository was archived by the owner on May 29, 2026. It is now read-only.

retrofit: reverse-spec search partial (5 REQs / 37 methods, 111 deferred)#1791

Open
rubenvdlinde wants to merge 1 commit into
developmentfrom
retrofit/rspec-search-2026-05-24
Open

retrofit: reverse-spec search partial (5 REQs / 37 methods, 111 deferred)#1791
rubenvdlinde wants to merge 1 commit into
developmentfrom
retrofit/rspec-search-2026-05-24

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Summary

Reverse-engineer the user-facing search capability from observed code as 5 new REQs. No canonical spec existed — this PR creates openspec/specs/search/spec.md (status: implemented, retrofit: true) with the first content for the capability.

This is a partial pass over the 148-method Bucket 2a batch (/tmp/or-scan/rspec-cluster-search.json). 84 methods belong to the parallel search-index capability (Elasticsearch backend mirror of the Solr layer + SearchBackendInterface, see #1765) and are DROP'd from this scope. 27 additional methods are deferred under future-pass:next in tasks.md.

REQs introduced

  1. The system SHALL expose three file-search HTTP endpoints on FileSearchController — keyword / semantic / hybrid, all @NoAdminRequired + @NoCSRFRequired, empty-query 400, on-failure 500.
  2. Vector search SHALL support PHP cosine and Solr KNN backends with Reciprocal Rank Fusion for hybrid mode (cosineSimilarity dimension guard + zero-magnitude safety; KNN query shape {!knn f=… topK=N}[v]; RRF score weight / (60 + rank + 1)).
  3. The system SHALL log every search request as a search trail with system-param filtering and optional self-clearing (mapper filters _ keys; service-level exception wrap; selfClearing toggle gated on constructor flag; processConfig honours both bare and underscored parameter pairs).
  4. SearchTrailController SHALL expose the search-trail REST API and analytics aggregators (index / show / statistics / popularTerms / activity / registerSchemaStats / userAgentStats / cleanup / export / destroy / destroyMultiple / clearAll; controller-level paginate helper enforces consistent shape; service aggregators decorate raw counts with percentages / success_rate / trend classifiers / browser_distribution).
  5. PlaceholderResolver SHALL resolve \$now / \$startOf* / \$currentUser DSL with optional ±N[dwmy] offset arithmetic (natural-unit default per placeholder; unknown placeholders return verbatim; resolveArray recurses leaves).

Annotations

  • 37 unique methods (39 @spec references — 2 methods carry both REQ-003 and REQ-004 tags) across 5 files:
    • lib/Controller/FileSearchController.php (REQ-001)
    • lib/Service/Vectorization/Handlers/VectorSearchHandler.php (REQ-002)
    • lib/Service/SearchTrailService.php (REQ-003 + REQ-004)
    • lib/Controller/SearchTrailController.php (REQ-004)
    • lib/Service/Search/PlaceholderResolver.php (REQ-005)
  • No runtime behaviour changes — docblock-only.

Notes / drifts surfaced (not fixed)

  • SearchTrailController::destroy and destroyMultiple are stubs that return 200 with "not implemented yet" — misleading callers behind @NoAdminRequired DELETE routes.
  • SearchTrailController::clearAll reaches into the container (\OC::\$server->get(...)) instead of going through the injected SearchTrailService.
  • SearchTrailService::getSearchStatistics ships a hard-coded query_complexity = {simple: 60%, medium: 30%, complex: 10%} placeholder.
  • cleanupSearchTrails(\$_before) ignores its \$before parameter (mapper deletes by expires column only).
  • VectorSearchHandler::hybridSearch oversearches the vector half by 2x but consumes Solr-side input as-is — asymmetric merge.
  • openregister_vectors.embedding column is PHP-serialize()'d, not JSON.
  • search-index/spec.md (PR retrofit: reverse-spec search-index (5 new REQs, new capability) #1765) is the canonical home for the 84 search-index methods DROP'd here, but is still pre-merge on origin/development.

Deferred (future-pass:next)

  • 84 search-index methods → picked up by extending search-index/spec.md (PR retrofit: reverse-spec search-index (5 new REQs, new capability) #1765) to cover Elasticsearch.
  • 7 SearchTrailService analytics helper internals.
  • 2 SearchTrailController stub endpoints (destroy, destroyMultiple).
  • 6 frontend search UI methods.
  • 12 facet UI + integration test methods.
  • 1 facet cache clearing helper (FacetCacheHandler::clearDistributedFacetCaches).

See openspec/changes/retrofit-2026-05-24-search/tasks.md for the full deferred list.

Test plan

  • composer check:strict (PHPCS / PHPMD / Psalm / PHPStan) — docblock changes only, expect no new violations
  • openspec validate retrofit-2026-05-24-search --strict — verify ghost change shape
  • Manual grep — every @spec openspec/changes/retrofit-2026-05-24-search/tasks.md#task-N resolves to an existing task line

…red)

Reverse-engineer the user-facing `search` capability from observed code as
5 new REQs. No canonical spec existed — this commit creates
openspec/specs/search/spec.md (status: implemented, retrofit: true) with
the first content for the capability.

This is a PARTIAL pass over the 148-method Bucket 2a batch
(/tmp/or-scan/rspec-cluster-search.json). 84 methods belong to the
parallel `search-index` capability (Elasticsearch backend mirror of the
Solr layer + SearchBackendInterface, see PR #1765 —
retrofit-2026-05-24-search-index) and are DROP'd from this scope.
27 additional methods (frontend Vue stores/views, facet UI, facet
integration tests, FacetCacheHandler clearing internals, several
SearchTrailService analytics helpers, two stub controllers) are
deferred under `future-pass:next` in tasks.md.

New REQs:
1. The system SHALL expose three file-search HTTP endpoints on
   FileSearchController (keyword / semantic / hybrid, all
   @NoAdminRequired + @NoCSRFRequired, empty-query 400, on-failure 500).
2. Vector search SHALL support PHP cosine and Solr KNN backends with
   Reciprocal Rank Fusion for hybrid mode (cosineSimilarity dimension
   guard + zero-magnitude safety; KNN query shape `{!knn f=… topK=N}[v]`;
   RRF score `weight / (60 + rank + 1)`).
3. The system SHALL log every search request as a search trail with
   system-param filtering and optional self-clearing (mapper filters `_`
   keys; service-level exception wrap; selfClearing toggle gated on
   constructor flag; processConfig honours both bare and underscored
   parameter pairs).
4. SearchTrailController SHALL expose the search-trail REST API and
   analytics aggregators (index / show / statistics / popularTerms /
   activity / registerSchemaStats / userAgentStats / cleanup / export /
   destroy / destroyMultiple / clearAll; controller-level paginate
   helper enforces consistent shape; service aggregators decorate raw
   counts with percentages / success_rate / trend classifiers /
   browser_distribution).
5. PlaceholderResolver SHALL resolve `$now` / `$startOf*` / `$currentUser`
   DSL with optional `±N[dwmy]` offset arithmetic (natural-unit default
   per placeholder; unknown placeholders return verbatim; resolveArray
   recurses leaves).

Annotated 37 methods across 5 files with @SPEC pointers back to this
change's tasks. Notes section flags two stub controllers
(SearchTrailController::destroy / destroyMultiple), a service-layer
container leak (clearAll), a hard-coded query_complexity placeholder,
a documented `$_before`-ignored param on cleanupSearchTrails, the
hybrid-mode 2x vector oversearch asymmetry, the
PHP-serialized embedding column, and the timing of the search-index
capability merge (PR #1765 still pre-merge).

No runtime behaviour changes (docblock-only).
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/openregister @ 0fbf02f

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
composer ✅ 162/162
npm ✅ 532/532
PHPUnit ⏭️
Newman ⏭️
Playwright ⏭️

Quality workflow — 2026-05-24 19:19 UTC

Download the full PDF report from the workflow artifacts.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant