Add sibling publish.yaml jobs (scoop-bucket, homebrew-tap) that render a
manifest from the release .sha256 sidecars and idempotently push it to the
org-level lazyeval/scoop-bucket and lazyeval/homebrew-tap repos, using the
scoped lazyeval-ci bot token (LAZYEVAL_PKG_TOKEN).
Render logic lives in dependency-free bash (the CI image has no jq/ruby):
scripts/render-scoop-manifest.sh and scripts/render-homebrew-formula.sh.
scripts/test-package-renders.sh exercises both: it validates the Scoop JSON
with node and asserts fields on both manifests, and additionally runs
`ruby -c` on the formula where ruby is present (dev box), skipping it
gracefully otherwise.
A new ci.yaml `manifests` job runs that test on every push so a render
regression surfaces immediately, not at the next manual publish dispatch.
The CI image has no ruby, so in CI the gate covers the Scoop JSON (node) and
field assertions for both manifests; the formula's Ruby syntax is checked
dev-side only (the static heredoc's variable parts cannot introduce syntax
errors).
- Scoop: x64 (gnu) + arm64 (gnullvm); #/-rename fragment so the bin shim is
version-stable; checkver, no autoupdate (the pipeline is the updater).
- Homebrew: on_macos/on_linux x arch bare-binary formula; no Windows.
Docs: ADR-0056 Amendment 2 (+ README index, requirements D3).
Unverified pending real use: scoop/brew install, the HEAD:main branch
assumption, macOS Gatekeeper-via-brew on the ad-hoc-signed binary.
The persisted User PATH only reaches newly-started processes, so the old
"restart your shell" advice was wrong — a sign-out/in was actually needed
(observed on Windows 11). Update the current session's $env:Path as well
so the command works right away in the same window, and reword the notice.
Also refresh the header: verified on ARM64 Windows 11 under Windows
PowerShell 5.1 and PowerShell 7.6 against the live v0.2.0 release.
The in-box Windows shell (5.1, .NET Framework) is the baseline we must
support; PowerShell 7 is an opt-in install most users don't have.
- arch detection: read PROCESSOR_ARCHITECTURE/ARCHITEW6432 from the
environment instead of RuntimeInformation::OSArchitecture, which
resolves from a .NET Framework facade lacking that property under 5.1
and throws under StrictMode (the reported failure).
- force TLS 1.2 before any web request (5.1 may default to TLS 1.0/1.1).
- pass -UseBasicParsing to Invoke-WebRequest (5.1 otherwise uses the IE
engine and can fail when it is absent).
All three are no-ops on PowerShell 7. Relates to ADR-0055.
d3af1c4 described the manual publish workflow and updated ADR-0056, but
`git commit -am` doesn't stage new untracked files, so publish.yaml
itself was left out. Add it here.
A workflow_dispatch publish.yaml (mirrors release-macos.yaml) with a `tag`
input, run by hand once the automated release builds exist. Publishing
stays manual and keeps the registry token off every tag push: it's
irreversible (yank-only), 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. The crates.io job is
idempotent (crates.io API pre-check + cargo publish as backstop) and
independent (no inter-job needs), so future Scoop/Homebrew/winget jobs can
be added alongside without interfering or breaking re-runs. Token via the
CARGO_REGISTRY_TOKEN secret. ADR-0056 Amendment 1 + README index also
record 0.2.0 published + binstall verified.
The prune step's profile path $HOME/.cache/rdbms-ci/toolchain had no
parent dir, so `nix develop --profile` errored ("cannot read directory")
and — swallowed by `|| true` — never created the profile/gc-root. With
nothing rooting the toolchain, nix-collect-garbage deleted the whole
closure every run (~3.8 GiB re-downloaded each dispatch; confirmed in the
run-74 log). Add `mkdir -p` for the parent and drop the `|| true` on the
profile realization so a future breakage fails loudly. The VM stays
bounded as before, but the toolchain now persists across runs.
release-macos.yaml is workflow_dispatch (runs from main's definition), so
this takes effect on the next dispatch — the already-published v0.2.0
macOS binaries are unaffected.
The ADR-0054 version guard piped `nix develop -c cargo metadata` to node,
but the flake devShell prints a banner to stdout — corrupting the JSON
pipe, so the guard aborted under `set -e` and the v0.2.0 release failed
there (before building anything). Replace it with a toolchain-free
`grep -m1 '^version = ' Cargo.toml` (the anchor excludes dependency
`version =` keys). No real version mismatch occurred — the tagged commit
has version 0.2.0.
First release carrying the version surfaces (--version / -V / the in-app
version command, ADR-0054), the curl|sh + PowerShell installers
(ADR-0055), crates.io/binstall readiness (ADR-0056), the verified hint
corpus, the Ctrl-G demo F1 alias, and the cargo fmt gate (#35). The
release guard checks this equals the v0.2.0 tag.
Adds `cargo fmt --check` (stock defaults) to ci.yaml's gate, now that the
tree is rustfmt-clean (commit 41b7e9a). Records that reformat in
.git-blame-ignore-revs so `git blame` skips it. Amends ADR-ci-002 (the
deferred "revisit on main" fmt decision) + the ci ADR index.
Closes#35.
One-time, mechanical reformat — no functional changes. The tree was not
rustfmt-clean (~1800 hunks across ~100 files); this brings it to stock
`cargo fmt` defaults so a `cargo fmt --check` CI gate can follow.
Behaviour-preserving: 2509 pass / 0 fail / 1 ignored (unchanged baseline),
clippy clean. A .git-blame-ignore-revs entry follows so `git blame`
skips this commit.
Distribution prep on the road to public availability (plan steps 2–3a).
- Cargo.toml: publish-ready (drop publish=false; homepage/keywords/
categories/exclude) + [package.metadata.binstall] with per-target
overrides (linux-gnu->musl, windows-msvc->gnu/gnullvm). dry-run clean.
- scripts/install.ps1: Windows `irm | iex` one-liner — written but
untested here (no PowerShell; validate on Windows). README Windows block.
- README.md (new); LICENSE-MIT + LICENSE-APACHE (dual, (c) Lazy
Evaluation Ltd); CONTRIBUTING.md (inbound=outbound dual-license note).
- ADR-0055 Amendment 1 (install.ps1), ADR-0056 (crates.io/binstall),
README index + plan updates.
The actual `cargo publish` remains a gated maintainer step (token,
irreversible) at a new tagged release; real cargo-binstall validation
pending.
scripts/install.sh — POSIX sh, shellcheck-clean: detects uname OS/arch ->
target triple (Linux uses the static musl build; Windows rejected with a
Scoop/winget pointer), resolves the latest release (or RDBMS_VERSION),
downloads the asset + its .sha256 and verifies it, installs to
~/.local/bin with a PATH hint. RDBMS_OS/RDBMS_ARCH + --print-target are
testing seams. Verified end-to-end against the live public v0.1.0 (all
mappings, pinned + latest, checksum incl. tamper-rejection, install+run).
ADR-0055 + README index; plan-doc step 2 done + decisions recorded
(crates.io=yes, releases public, tracking via doc+ADR).
Cargo.toml version is the single source of truth, surfaced by a
--version/-V CLI flag and an in-app `version` command (both via
cli::version_text -> cli.version_line). release.yaml gains a guard that
fails the release unless the v* tag equals v<CARGO_PKG_VERSION>, keeping
--version, the release name, and the asset in lockstep. New app command
wired across grammar/REGISTRY/dispatch/usage/help/hint-corpus/keys; 6
test-first tests. Also fixes a stale "macOS deferred" comment in
release.yaml. ADR-0054 + README index + plan-doc step 1.
Post-merge documentation accuracy pass (CI and website branches both
merged to main; website deployed).
- CLAUDE.md: rewrite the stale repository-layout tree; add a Website &
docs-site decision bullet (Astro+Starlight, Cloudflare Pages via Gitea
Actions, ADR-website-001, the website branch stays open); update the CI
note (merged to main; release-macos dispatchable + verified working).
- requirements.md: D1 — macOS targets now runtime-verified (release-macos
dispatched end-to-end); DOC1 — canonical user docs now live on the
deployed website.
- ADR-ci-003 (+ docs/ci/adr README): Amendment 2 — CI on main,
release-macos dispatched + verified; macOS runtime-verified.
- docs/website/adr README: drop the stale "no CI yet".
- .gitignore: ignore .wrangler/ (Cloudflare Wrangler cache) and .vscode/;
remove the tracked website/.vscode/ an Astro template had added.
D3 (package-manager manifests) + some install instructions remain open.
The previous take pressed F1 after a complete command, which no one does.
Now the cast starts `add column `, pauses, presses F1 (Ctrl-G→[F1]) to recall
the syntax, then finishes the command from the example — the real reason you
reach for a hint. The `hint`-on-an-error half is unchanged.
Completes the preceding empty-rename commit: the getting-help "Hints"
section — F1 for a tier-3 teaching hint on the live input, `hint` to
explain the most recent error — with the real rendered block and a cast
showing both (the live-input hint via the demo-mode Ctrl-G→[F1] alias,
since autocast can't send F1, then `hint` on an error). the-assistive-editor
points at F1; CtrlG added to the cast generator's key map.
getting-help gains a "Hints" section — F1 for a tier-3 teaching hint on the
live input, `hint` to explain the most recent error — with the real rendered
block and a cast showing both: the live-input hint (via the demo-mode
Ctrl-G→[F1] alias, since autocast can't send F1) and `hint` on an error.
the-assistive-editor points at F1. Page converted to .mdx to embed the cast;
CtrlG added to the cast generator's key map.
The contextual hint overlay (ADR-0053) opens on F1, but F1 is an escape
sequence the autocast recorder can't emit — so casts (and presenter /
teacher sessions) couldn't trigger the most teaching-relevant overlay.
In demo mode only, Ctrl-G now aliases F1: it runs the same hint logic and
badges AS [F1], so a recording is visually identical to a real F1 press.
Ctrl-G is the only fit — Ctrl+digit (e.g. Ctrl-1) isn't encodable in a
legacy terminal (arrives as a bare `1`), and the kitty protocol that would
encode it needs escape sequences autocast can't send (and the app doesn't
enable keyboard-enhancement flags). Demo-gated, so the shipped keymap
stays F1-only; outside demo mode Ctrl-G is inert.
- app.rs: hint_key guard gains the demo-gated Ctrl-G disjunct;
demo_badge_label maps Ctrl-G -> [F1]; 3 Tier-1 tests + badge assertion.
- ADR-0047 Amendment 1 + README index; also removed two stray
</content> / </invoke> lines accidentally committed in the ADR file.
docs: drop three more stale "deferred" entries from CLAUDE.md — readline
shortcuts (I1b, ADR-0049), tab completion (I3), and syntax highlighting
(I4) are all implemented; only multi-line input (I1) remains open.
pnpm casts refresh so every cast reflects the merged app — the
context/state-aware keybinding strip, the readline keys, year/choice-set
seeding, and the DDL-confirmation changes. The .cast files are
regenerable artifacts.
Hide the splash hero's redundant <h1> (kept in the DOM for SEO/a11y,
landing-scoped via a title-only hero) and render the Wordmark + tagline +
buttons in the body, so the brand lockup sits where the heading was and
the content rises above the fold (it was nearly hidden on an iPad).
Styles in global.css; doc-page headings are unaffected.
The Gitea Actions → Cloudflare Pages pipeline shipped; update §4 from
"No CI yet" to the implemented workflow, the `relplay` project, the
branch→environment mapping, and the required secrets.
Add website/** and the website workflow to ci.yaml's paths-ignore, so a
push confined to the website subproject (built + published by
website.yaml) no longer runs clippy+test. A push that also touches crate
code still gates (paths-ignore skips only when all files match).
New .gitea/workflows/website.yaml: on a push to main or website that
touches website/**, build the Astro site with pnpm and deploy
website/dist to the `relplay` Cloudflare Pages project via wrangler —
--branch selects production (main) vs preview (website). Runs on the
bare ci-public runner (node present; pnpm via corepack). Pin pnpm with
package.json's packageManager for deterministic corepack installs.
Requires repo Actions secrets CLOUDFLARE_API_TOKEN + CLOUDFLARE_ACCOUNT_ID.
Seed page reflects #33/#34: year-as-int columns, built-in value sets
(priority/severity/rating), advisory now status-only; output blocks
re-captured and the seed cast re-recorded. Assistive-editor documents
the #29 readline shortcuts (Ctrl-A/E/W/K/U, Esc) and #30 cross-mode
history recall; multi-line stays the only planned item.
Semantic verification pass over the tier-3 `hint` corpus (ADR-0053).
Four content errors corrected in src/friendly/strings/en-US.yaml:
- cmd.create_table: the example `with pk id(serial), name(text),
email(text)` declares a 3-column COMPOUND primary key, not a PK
plus regular columns (every `with pk` column is a key member,
ADR-0005). Rewritten to a single-column PK + `add column` for the
rest; what/concept aligned.
- cmd.save: `save as my-shop` does not parse — `save as` takes no
inline name, it opens a path-entry prompt. Example -> `save as`;
what no longer implies inline naming; added a temp-vs-named concept.
- cmd.import: target `shop-copy` does not parse — the `as <target>`
slot is a NewName ident that rejects hyphens. -> `shop_copy`.
- err.foreign_key.child_side: dropped the bogus `on delete set
null/cascade` remedy — that governs the parent direction; a
child-side violation is fixed by inserting the parent first
(matches the tier-1 hint).
Adds every_cmd_hint_example_parses_in_its_mode — a catalog-driven
guard that parses every hint.cmd.* example in its taught mode,
backstopping syntactic drift (it caught the save and import errors).
Registers the new hint.cmd.save.concept key.
docs: drop two stale "deferred" entries from CLAUDE.md — project
storage (export/import, --resume, input history, migration scaffold)
and m:n convenience (C4) are all implemented (ADR-0015/0045); record
the verification pass on requirements.md H2.
User smoke-test found hint.cmd.create_table is semantically wrong: the
example `create table Customers with pk id(serial), name(text),
email(text)` reads as a 3-column table but actually declares a compound
PK (id, name, email) — everything after `with pk` is the PK column list
(ADR-0005). Root cause: Phase C examples were syntax-checked but some
were extrapolated, not verified to *do* what what/concept claims. Handoff
specifies a full per-block semantic pass (run each example / check the
ADR) + a ready-to-apply create_table fix.
main independently wrote its own docs/handoff/20260615-handoff-70.md the
same day, so my global-sequence handoff-70 was an add/add conflict waiting
to merge. Relocate it to docs/ci/handoff/20260615-handoff-ci-01.md (its own
namespace, like docs/ci/adr) + a README index. main's handoff-70 is
untouched; the merge becomes conflict-free.
Final /runda found the rendered block was three bare unlabelled lines,
deviating from the approved exemplar format. Fix:
- emit_tier3_block now renders a `Hint` heading + aligned `What:` /
`Example:` / `Concept:` lines (hint.block.* labels); concept stays muted
- lock the format with an insta snapshot (hint_block_insert)
- amend ADR-0053 D2/D4 + exemplars: drop the `Next:` line (tier-2 ambient
already owns live position-awareness — user-confirmed), align exemplars
to the shipped format
2499 pass / 1 ignored, clippy clean.
Completes H2:
- comprehensiveness coverage tests: every REGISTRY command form has a
hint_id resolving to a hint.cmd.* block, and every runtime error class
resolves to a hint.err.* block (enforces ADR-0053 D6)
- ADR-0051 keybinding strip advertises F1 in the editing (leads) and
default states; +shortcut.hint label; 12 full-panel snapshots
re-accepted (status-bar line only)
- flip ADR-0053 -> implemented, requirements H2 + A1 -> [x], README
2498 pass / 1 ignored, clippy clean.
Phase C scope decision: Diagnostic carries no class key, so the F1
diagnostic route would need a class field threaded through every
diagnostic site (broad change) for marginal value — tier-2 already
surfaces diagnostics and many duplicate the runtime error classes. Defer
the route + the ~33 diagnostic.* tier-3 blocks to issue #38. v1 ships
command-form hints + 9 runtime error-class hints (comprehensive for
those). Updates ADR-0053 D2/D6/Status/OOS + README.
Distinct SQL-syntax hints for the 11 advanced-mode forms: sql create
table / alter table / create index / drop index / drop table / insert /
update / delete, select, with, explain. hint_ids wired on all 11 nodes.
Hardened hint_key_for_input_in_mode for shared entry words: a bare
multi-form entry word defers to tier-2; when the second token isn't a
form word (insert into / update … set), it falls back to the
mode-primary key — so advanced mode resolves to the SQL form and simple
mode to the DSL form. catalogue + keys.rs registered. +2 spot tests +
grammar mode-disambiguation asserts; 2495 pass / 1 ignored, clippy clean.
Bring main's latest (ADRs 0049-0053 + their features) onto the CI branch so
the gate runs against current main before CI lands on main. Clean merge —
ci and main touched disjoint files.
macOS is no longer deferred — built natively on a Tart (Apple-Silicon)
runner (real hardware → licensed SDK, no grey area). Amendment documents
release-macos.yaml (dispatch-only, needs main), the libiconv de-nix +
ad-hoc re-sign, the runner-label `:host` backend nuance, generation-based
cache pruning, and D2-on-macOS (system libs only). All six D1 targets now
produce artifacts. Updates the deferred list + index entry.
The first exemplar (`add 1:n relationship`) showed per-node keying is
too coarse for multi-form commands, so revise the mechanism to per-form.
- CommandNode `hint_id: Option<&str>` -> `hint_ids: &[&str]` (mirrors
usage_ids); hint_key_for_input_in_mode reuses a factored-out
pick_form_key (shared digit/m:n/suffix form disambiguation with
usage_key_for_input_in_mode)
- wire INSERT + ADD (all four forms) with hint_ids
- author the three approved exemplars: hint.cmd.insert,
hint.cmd.add_relationship, hint.err.foreign_key.child_side
(what/example/concept) + keys.rs registration
- revise ADR-0053 D3 to per-form; record clause-concept hints as a
deferred extension (issue #37); update README + plan
- +5 tests; 2488 pass / 1 ignored, clippy clean
The mechanism for the contextual hint, with tier-2 fallback; the
tier-3 corpus lands in later phases.
- new CommandNode `hint_id` field (all None for now)
- AppCommand::Hint + HINT grammar node + REGISTRY + dispatch
- F1 read-only overlay in handle_key (buffer/cursor/memo untouched)
- note_hint* renderers; hint_id_for_input_in_mode (shared selection
helper refactored out of usage_keys_for_input_in_mode)
- last_error_hint_key + friendly::error_hint_class classifier
- catalogue: help.app.hint / parse.usage.hint / hint.getting_started
- +12 tests; 2483 pass / 1 ignored, clippy clean
Phased build plan: mechanism skeleton with tier-2 fallback first
(hint_id field, AppCommand::Hint, F1 read-only overlay, last_error_hint_key,
note_hint* renderer), then catalogue + the three approved exemplars,
then comprehensive content in batches, then polish. Reuses the existing
command_for_entry_word / usage_keys_for_input_in_mode lookups for
command identification. Test spine includes the comprehensiveness
coverage test that gates "comprehensive for v1".