HarperFast / HarperFast/harper

RQL 2.0 conformance: divergence tracking

Open
#2,440 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
89
Forks
10
Avg merge
2d 6h
Merged PRs (30d)
200

Description

Tracking epic for converging Harper's REST query parsing/execution toward the [RQL 2.0 specification](https://github.com/HarperFast/rql/blob/kris/rql-v2/specification/rql-2.0.md) (spec PR: HarperFast/rql#4). The spec is implementation-independent; this epic is Harper's divergence ledger — each row is either a **bug** (sub-issue), a **feature gap** (sub-issue), or a **permitted representational difference** (no action; Harper conforms via an adapter per spec §8).

## Divergences (as of harper main, 2026-09)

| # | Divergence | Class | Action |
|---|---|---|---|
| 1 | Simple queries (no structural chars) skip parsing; conditions surface as raw name/value pairs (dual shape) | permitted | adapter maps to canonical model |
| 2 | Chains attach as `chainedConditions`; nameless legs (`a=ge=1&=5`) inherit the previous comparator | representational + quirk | adapter; nameless legs are a syntax error in 2.0 — deprecate |
| 3 | Strict/coercive modeled as distinct comparators (`equals`/`not_equal` vs `eq`/`ne`) | permitted | adapter normalizes to value-literal modes (§5.2) |
| 4 | `between` is a first-class comparator | permitted | spec Appendix B alias; desugars to element-scoped `ge`+`le` |
| 5 | Sort is a linked list; select is a polymorphic array with marker props | permitted | adapter |
| 6 | `(4)` on a non-list comparator is the literal string `"(4)"` | tolerance | keep; producers must not rely on it |
| 7 | `prop[]=v` repeated array params | tolerance | spec Appendix B host accommodation |
| 8 | Parse errors deferred into the pipeline (`parseError`) | permitted | §6.1 allows deferred mode |
| 9 | `group-by(...)` accepted at parse and falls through into `sort` (missing `break`) | bug | fix in flight (dispatch `harper-groupby-fallthrough`); 2.0 parse-rejects reserved call names |
| 10 | Chained legs' values never type-coerced on the REST path → mixed-type ranges, silent superset/empty results | bug | #2433 |
| 11 | Indexed `elements` attributes return one result per matching element (duplicates) | bug | #2434 |
| 12 | `contains` matches numbers via decimal-string coercion | divergence | spec §5.1.1: string comparators match only strings; decide keep-as-divergence vs align |
| 13 | No `not(...)` group/scope negation | feature gap | sub-issue below |
| 14 | Element conditions (`prop[=ge=10|=le=2]`) and scoped sub-queries per §5.3 surface | partial | Harper has `prop[cond&cond]`; elem-cond (empty relative path) not supported — fold into not() work or file separately |

Pinning tests for rows 2/10/11/12 landed in #2437. The RQL reference parser + conformance suite (surface string → canonical AST) live on the spec branch; a differential corpus harness is queued (`rql-conformance-corpus-diff`).

Contributor guide

Open the contributing guide

Research direction

Start with the RQL 2.0 specification and the divergence table, then inspect the pinning tests in #2437 and related work in #2433 and #2434. This epic is complete when each divergence has a recorded permitted difference, fix, decision, or linked sub-issue, including the queued conformance corpus harness.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, nodejs
Domain
api, backend-api-design
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.