From 6d4364666a88e8b5cdd58ec4fd0b9d490e926688 Mon Sep 17 00:00:00 2001 From: "claude@clouddev1" Date: Tue, 23 Jun 2026 20:09:36 +0000 Subject: [PATCH] docs(adr): finalize ADR-0058 number for clause-concept-hints Rename the placeholder draft to its reserved number (0058, allocated reserve-first via the new dev-workflow flow), drop the ADR-XXXX placeholders, and add the README index row. --- ...ncept-hints.md => 0058-clause-concept-hints.md} | 14 +++++++------- docs/adr/README.md | 1 + 2 files changed, 8 insertions(+), 7 deletions(-) rename docs/adr/{draft-clause-concept-hints.md => 0058-clause-concept-hints.md} (97%) diff --git a/docs/adr/draft-clause-concept-hints.md b/docs/adr/0058-clause-concept-hints.md similarity index 97% rename from docs/adr/draft-clause-concept-hints.md rename to docs/adr/0058-clause-concept-hints.md index 810e6b3..91831a1 100644 --- a/docs/adr/draft-clause-concept-hints.md +++ b/docs/adr/0058-clause-concept-hints.md @@ -1,13 +1,13 @@ -# ADR-XXXX: Clause-concept hints — a `hint.concept.*` layer surfaced by cursor position (issue #37) +# ADR-0058: Clause-concept hints — a `hint.concept.*` layer surfaced by cursor position (issue #37) ## Status -Draft — **implemented 2026-06-23** on branch `feat/clause-concept-hints` -(pending merge). Number assigned at merge-to-`main` per ADR-0000 -"Numbering discipline" (drafted under `draft-clause-concept-hints.md` / -`ADR-XXXX`; README index entry added at merge). Extends **ADR-0053** -(contextual `hint`, D3/D4) additively; does not supersede it. Closes the -deferred extension tracked as Gitea issue **#37**. +Accepted — **implemented 2026-06-23** on branch `feat/clause-concept-hints` +(pending merge). Number **0058**, reserved up front via the reserve-first +flow (ADR-0059) rather than the older placeholder-until-merge default — +this ADR is the first to carry a number stable from creation. Extends +**ADR-0053** (contextual `hint`, D3/D4) additively; does not supersede it. +Closes the deferred extension tracked as Gitea issue **#37**. Implementation: `Node::Concept { topic, inner }` (`dsl/grammar/mod.rs`) + the span-recording driver arm (`dsl/walker/driver.rs`) + diff --git a/docs/adr/README.md b/docs/adr/README.md index 47fd168..2346d47 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -70,3 +70,4 @@ This directory contains the project's ADRs, recorded per - [ADR-0055 — `curl | sh` install script (`scripts/install.sh`)](0055-curl-sh-install-script.md) — **Accepted + implemented 2026-06-17** (plan: `docs/plans/20260616-public-availability.md`, step 2; tracked by plan + ADR, no Gitea issue — user decision). A one-line installer (`curl -fsSL /scripts/install.sh | sh`) so beginners don't hand-pick an asset + `chmod +x`. **POSIX `sh`** (shellcheck-clean), detects `uname` OS/arch → target triple (**Linux → the fully-static `*-musl`** build, macOS → `*-apple-darwin`; `amd64`/`arm64` aliased; **Windows rejected** → Scoop/winget/releases page), resolves the version from the **`releases/latest`** API (or `RDBMS_VERSION` to pin), downloads the asset **and its `.sha256` and verifies it** (mismatch aborts), installs to `~/.local/bin` (`RDBMS_INSTALL_DIR` override) with a PATH hint. Testing seams: `RDBMS_OS`/`RDBMS_ARCH` + `--print-target`. macOS note: `curl` downloads aren't Gatekeeper-quarantined so the ad-hoc binary runs as-is (Developer-ID + notarization is the postponed signing task). **Verified end-to-end against the live public `v0.1.0`** (all platform mappings, pinned + latest, checksum incl. tamper-rejection, install + run). Rejected: website-domain hosting (extra moving part; Gitea raw is simplest); deferred: uploading the script as a release asset, and a **shellcheck CI gate** (shellcheck isn't in the flake — touches ADR-ci-002). **Amendment 1 (2026-06-17):** added a Windows **`scripts/install.ps1`** (`irm | iex`; maps host CPU → our `*-windows-gnu`/`-gnullvm` `.exe`, SHA-256-verifies, installs to `%LOCALAPPDATA%\Programs\…` + user PATH) — user chose both a one-liner *and* Scoop/winget; **written but untested from this env** (no PowerShell — validate on Windows). - [ADR-0056 — crates.io publish-readiness + `cargo binstall` metadata (D3)](0056-crates-io-and-cargo-binstall.md) — **Prepared 2026-06-17** (plan step 3a; tracked by plan + ADR). Makes the crate **ready to publish** to crates.io (user decision) and adds `cargo-binstall` metadata; the actual `cargo publish` is a **gated, irreversible maintainer step**. Manifest: drops `publish = false`; adds `homepage` (relplay.org), `keywords`, `categories`, and an `exclude` (`/website`,`/docs`,`/.gitea`,`/.codegraph`) trimming the crate from 585 files/8.3 MiB → **353/913 KiB compressed** (code-only). Authors **`README.md`** (engine-neutral, simple/advanced-mode wording; install via curl|sh/binstall/source/prebuilt) and **`LICENSE-MIT`** (© Lazy Evaluation Ltd — *confirm holder*); the canonical **`LICENSE-APACHE`** is deferred to the maintainer (don't ship retyped legal text) — the SPDX `license` field already satisfies crates.io. **binstall** (syntax verified vs cargo-binstall SUPPORT.md): `pkg-fmt = "bin"` (bare binaries), `pkg-url` spelled `v{ version }` (the placeholder omits the `v`), plus per-target **`overrides`** mapping the common host triples to the assets we ship — `*-linux-gnu` → the static `*-linux-musl` build, `*-pc-windows-msvc` → `*-gnu`/`-gnullvm` `.exe` (macOS matches directly; the docs promise no automatic fallback). **Ordering:** publish at a **new tagged version whose release exists**, after the release — **not `0.1.0`** (diverges from the already-released 0.1.0 binaries that predate `--version`). Verified: `cargo publish --dry-run` packages + verify-builds; `cargo metadata` confirms the binstall block + 4 overrides. **Unverified:** a real `cargo binstall` run (not a dep; nothing on crates.io yet) — validate at first publish. Rejected: cargo-dist (GitHub-centric). Maintainer follow-ups: confirm © holder, add canonical `LICENSE-APACHE`, real binstall validation. **Amendment 1 (2026-06-18):** `0.2.0` **published live** (crates.io; `cargo install` + `cargo binstall` verified — the unverified-overrides caveat is resolved), via a new **manual `workflow_dispatch`** workflow `.gitea/workflows/publish.yaml` (mirrors `release-macos.yaml`; `tag` input; `cargo publish` with a crate-scoped `CARGO_REGISTRY_TOKEN` secret). Publish stays **manual** by decision — irreversible (keeps the token off every tag push), the split release (tag Linux/Windows + dispatched macOS) makes a human the "all assets up" gate, and crates.io has no Gitea-Actions trusted-publishing path. Each registry is its **own idempotent job** (crates.io job no-ops if the version exists) so Scoop/Homebrew/winget can be added as sibling jobs without interfering. **Amendment 2 (2026-06-19):** **Scoop + Homebrew wired** (D3 §3b/§3c) as sibling `publish.yaml` jobs (`scoop-bucket`, `homebrew-tap`) that render manifests from the release `.sha256` sidecars and push to **org-level, multi-package** repos `lazyeval/scoop-bucket` + `lazyeval/homebrew-tap`. Credential: a scoped bot user **`lazyeval-ci`** (Gitea PATs scope by permission-category, not per-repo, so an `oli` token would over-reach to the main repo) on a `lazyeval` org team with Write to the package repos only; its PAT is the `LAZYEVAL_PKG_TOKEN` secret on `oli/rdbms-playground`. Render scripts (`scripts/render-{scoop-manifest,homebrew-formula}.sh`) are **dependency-free bash** (CI image `node:22-slim` has no jq/ruby), tested by `scripts/test-package-renders.sh`. Scoop: `#/`-rename fragment + `checkver`, no `autoupdate`. Homebrew: `on_macos`/`on_linux`×arch bare-binary formula, no Windows. **Unverified:** real `scoop`/`brew install`, the `HEAD:main` branch assumption, macOS Gatekeeper-via-brew (ad-hoc sign). **Remaining D3:** winget. **Amendment 3 (2026-06-19):** **Scoop + Homebrew validated end-to-end** on real Windows + macOS (install + run). Found + fixed a **presigned-URL/HEAD gotcha**: Gitea (≥1.25) 303-redirects release downloads to a **method-bound SigV4 presigned S3 URL**; Homebrew resolves via HEAD, captures the HEAD-signed URL, then GETs it → 403 (GET-only tools unaffected). Fix is a **server-side Caddy rule** (lives in the Gitea edge config, NOT this repo — record it: lost on a rebuild → brew 403s again) answering HEAD on `…/releases/download/…` directly (200, no redirect) so brew's download GET re-runs the redirect fresh. ad-hoc mac signature **runs** via brew; Developer-ID + notarization still parked on the Apple org conversion. **Remaining D3:** winget only. **Amendment 4 (2026-06-20):** **winget wired** (D3 §3d) — the 4th `publish.yaml` sibling job opens a PR to the central, human-gated `microsoft/winget-pkgs` via **komac** (pinned 2.16.0; `LazyEvaluation.RdbmsPlayground`, `portable`, x64+arm64). Async + Microsoft-validated, unlike the bucket/tap. Auth: a **classic `public_repo` PAT** (fine-grained can't open the cross-fork PR, komac #310) on a **dedicated GitHub bot** → `WINGET_GITHUB_TOKEN`, job-scoped, passed via curl config file (not argv). Idempotent via **two guards** (already-merged version + already-open PR) so re-dispatch is safe. Unsigned is fine to submit (portable; only MSIX needs signing) — may earn an AV/SmartScreen manual-review label first time. **One-time `komac new` bootstrap is manual** (interactive); CI `komac update` handles releases after. Completes the D3 package-manager set. - [ADR-0057 — Non-functional-requirement verification strategy](0057-nfr-verification-strategy.md) — **Accepted 2026-06-22.** How NFR-1..7 are verified now that public binaries ship. **Gated:** NFR-5/NFR-7 colour contrast — `src/theme.rs` unit tests assert every text foreground clears **WCAG-AA 4.5:1** on both themes, the advanced-mode border clears the **3:1** UI bar (plain border decorative-exempt, documented), and every syntax-token pair clears **CIEDE2000 ΔE2000 ≥ 15** (metric reference-validated). Writing these **caught two shipped light-theme defects** (`tok_string` 4.42:1, `tok_flag` 3.15:1) + two near-duplicate dark pairs — all fixed (`65eab71`); dev tool `scripts/palette-preview.py`. **Measured, generously bounded:** NFR-1 startup + NFR-3 idle RSS via the Tier-4 PTY harness (debug-binary gross-regression bounds, not a tight gate per user decision); recorded **release** figures — startup **~29 ms** (< 500 ms), idle RSS **~10 MB** (< 50 MB). **By argument:** NFR-2 off-thread responsiveness (worker thread ADR-0010 + separate input task). **Reviewer note:** NFR-4 distinctive design, NFR-6 cross-platform parity (CI matrix: Linux+macOS execute, Windows build-only; one documented divergence — true-colour quantisation on non-`Tc` terminals). Latent finding **issue #39** (fast DDL→insert vs stale schema cache) deferred. +- [ADR-0058 — Clause-concept hints (`hint.concept.*` surfaced by cursor position)](0058-clause-concept-hints.md) — **Accepted + implemented 2026-06-23 (issue #37).** The deferred ADR-0053 extension: a third tier-3 surface, deeper than the per-form `hint.cmd.*` block but narrower than it, shown by **F1** when the cursor sits **inside a recognized clause** — referential actions (`on delete`/`on update`), `1:n`/`m:n` cardinality, primary key, unique, check, foreign key (seven topics). Layered **on top of** the per-form block (an "About this clause" sub-block), never replacing it. **Mechanism:** a new transparent `Node::Concept { topic, inner }` grammar wrapper records the clause's byte-span into `WalkContext::concept_spans` (append-only, **survives the clause being fully matched** — unlike `pending_hint_mode`, which clears on match, giving only slot-boundary awareness); `concept_topic_at_cursor` walks the full buffer and returns the **innermost** span containing the cursor (so a cursor on `on delete` inside a `references … on delete` resolves to the narrower `referential_actions`). No use of the dormant `WalkBound::Position`. **Two user forks:** detection is "anywhere inside the clause" (not just the slot boundary), and **all four clause families** ship in v1. **Mode-keyed examples** (`example.simple`/`example.advanced`) honour ADR-0053 D6's mode-correct-example rule for the topics reachable in both modes (referential actions, primary key, unique, check); `emit_tier3_block` picks by live mode. `/runda` caught two design gaps before build (the clause map missed the simple-mode constraint suffix; the single-`example` model collided with D6) — both fixed. **Comprehensiveness gate:** a recursive `Node::Concept` visitor cross-checks grammar wrappers ↔ `CONCEPT_TOPICS` ↔ catalogue blocks. 21 new tests (14 resolver, 3 gates, 3 F1 integration, 1 snapshot); suite green all tiers, `fmt`/`clippy` clean. First ADR numbered **reserve-first** (stable from creation; ADR-0059).