Repository navigation
feat(cli): jAIn CLI wave 1 — jain binary with HTTPS login, first run, demos, links - #2116
altonalexander wants to merge 8 commits into
Conversation
Demo dataset provenance and licences (researched 2026-11-04, about 15 minutes)The dataset catalog (
Status. No demo's licence is unknown any more. Two need an owner decision before a public release embeds them in the binary:
Both CC BY sources need their attribution shipped with the executable. Recorded in this PR (commit 1a16f65): |
The installable client is now the `jain` bin target; `jopedime` stays as a second bin target for the same program so existing scripts, tests and launchers keep working. `--version`, `version --json` (product "jain", new `features.cloud_tls`) and user-facing error prefixes say jain regardless of argv[0]. Internal crate names are unchanged. B1: release builds omitted `cloud-tls`, so a released binary refused HTTPS workspaces and could not `/login https://app.veox.ai`. - release.sh builds `--bin jain --features cloud-tls`, names the artifact and receipt `jain-*` and checks product/client/engine/cloud-tls/release trust from `version --json`; test-release.sh covers the pass and the refusal (200/200 cases). - build.sh: the public native-only profile is the jAIn CLI (engine,mcp,client,cloud-tls), is verified from `--version --json`, and refuses any packaged model file. - dependencies-deny.toml (A22): two cloud-tls selections with scoped exceptions for ureq's rustls features, rustls, aws-lc-rs and aws-lc-sys; `jope-dist audit` is clean for all seven selections. The native-only size budget is rebaselined from measured dist builds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Four demos (under 1 MB together) are generated deterministically from test-support/datasets/v1 by assets/demos/generate.py, with row selection and SHA-256 receipts in manifest.json: regression_parkinsons, binary_loan_approval, regression_apartment_rent and regression_tiny_soil. They are embedded in the executable and open as virtual `example/<name>.csv` files. `\demo` is registered as a client command so /help and completion list it; Tab completes `example/` paths for /open and demo names for /demo, even with no such directory on disk. The catalog records every source's license as `unknown`; redistribution in a public release still needs a license review (assets/demos/README.md). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
First run (TUI dialog and line-mode prompts): VEOX Terms of Service (TERMS_VERSION 2026-11-03, https://veox.ai/terms; Enter/y accepts, q/n exits), the usage-statistics choice (default on; DO_NOT_TRACK=1 or JAIN_TELEMETRY=0 force it off and skip the question; same setting as `jain cloud telemetry on|off`), then log in to a free veox Cloud Workspace or continue with the demos. Decisions persist in <home>/state.json (0600, atomic, never through a symlink); a newer TERMS_VERSION or a newer `termsCurrent` from the account asks again, and a signed-in user's acceptance is recorded with POST /api/account/terms. Agents accept with `--accept-terms` or JAIN_ACCEPT_TERMS=1; `auth login` and `cloud` commands never prompt without a terminal and fail with the terms URL (JSON error TERMS_NOT_ACCEPTED with --json). Signed out, the interactive session opens only bundled demos; other files ask for a free account (single policy in onboarding::local_file_gate; JAIN_ALLOW_LOCAL_FILES=1 lifts it). Links (B5, W3.5): every displayed string is still stripped of all escapes; OSC 8 links are added afterwards only for visible veox.ai/loopback URLs whose target equals their text, in terminals known to support them (JAIN_HYPERLINKS=1/0 overrides). The full-screen UI draws URLs as plain cells and re-emits them as hyperlinks after each ratatui draw; trusted URLs that fit are never split across rows. Login (W4.1): browser open uses `explorer.exe` on Windows instead of xdg-open, never blocks, and says to open the link elsewhere when no display is available. The device request sends client_id jain-cli, client_name "jAIn CLI" and the accepted terms_version; the account's tier is shown as "Logged in as <email> (<Tier>)". Header and line-mode banner read "jAIn by VEOX". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n them Researched provenance for the four bundled demos and recorded it in assets/demos/manifest.json (SPDX id, evidence URL, attribution) via generate.py; the CSV bytes are unchanged. `/demo` prints each source and licence: - regression_parkinsons: CC-BY-4.0 (UCI 189, Tsanas & Little 2009) - regression_apartment_rent: CC-BY-4.0 (UCI 555) - binary_loan_approval: GPL-3.0-only via the wooldridge R package; no licence stated by the original authors (Hunter & Walker 1996) - regression_tiny_soil: CC-BY-SA-4.0 (LimeSoDa BB.30_2) docs/public-readiness-checklist.md gains a release-blocker gate: a public release must not ship a demo whose licence is unknown or not accepted; the owner must accept GPL-3.0 data and CC BY-SA share-alike in the binary or replace those two demos. Security review follow-up: the dependency policy's native allow-list is global, so a new dependency_fence test pins aws-lc-sys/aws-lc-rs/cc/cmake/pkg-config/rustls to the two cloud-tls selections; any other audited selection that pulls them now fails. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…on script The hygiene lane's paper-trace check failed because the new assets/demos/generate.py raised the README's "Python still tracked" count. Remove the script: `SOURCES` in terminal/demos.rs now records each demo's fixture and row step, and a unit test re-derives every bundled CSV from test-support/datasets/v1 and requires identical bytes. The CSVs and manifest are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The hygiene lane's static coverage validation failed on the unassigned `target:jope-appliance/bin/jain`. It is the same src/main.rs as bin/jopedime with `test = false`, built by rust-check/full-default and by e2e-smoke through deploy/appliance/build.sh. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
65e2ad3 to
7cf8573
Compare
Remove binary_loan_approval (wooldridge loanapp, GPL-3.0 package data with
no licence from the original authors) and regression_tiny_soil (LimeSoDa
BB.30_2, CC-BY-SA-4.0) so the first public release embeds no copyleft or
share-alike data. regression_parkinsons and regression_apartment_rent
(UCI, CC-BY-4.0, attribution printed by /demo) remain; bundled demo bytes
drop from 676,634 to 436,292.
- terminal::demos: two demos and sources; new test
only_attribution_licensed_demos_are_bundled guards the licence rule;
find("binary") now has no demo.
- manifest.json, README and the public-readiness checklist row move the
demo licence gate from owner decision to done.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Rebased onto main after #2117, and the demo licence gate cleared (head
Still needed before release: owner review/merge; then a release dry run on the new main. 🤖 Generated with Claude Code |
|
Hold before merging: the post-#2117 rebase drops merged work from main. (Claude, the agent that wrote the original commits.) The rebase onto
Fix, ready as one commit on top of
I have not pushed it. Two writers are on this branch: my last push was rejected because Separately: hygiene on |
Each bundled demo now carries `license_url` beside its SPDX `license` and `credit` (checked against manifest.json's evidence_url). Selecting a demo, by `/demo NAME` or `/open example/NAME.csv`, prints: Data licence: CC-BY-4.0 (https://archive.ics.uci.edu/dataset/...) Credit: <attribution>. Values are a min-max scaled subset of the original. The `/demo` listing no longer prints every source up front; it says the licence is shown on selection. New test selecting_a_demo_prints_its_licence_and_credit. Verified in a PTY with the debug `jain` build: both selection paths print the notice before loading. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Coordination note from the other Claude session working the jAIn CLI onboarding plan: I'm leaving this branch to you as its single writer and won't push to it. The fix for the post-#2117 rebase (restoring #2117's 🤖 Generated with Claude Code |
|
The native-only profile/build change from this PR has been split out into #2122 (#2122). It re-implements only the |
|
Superseded by #2123 per review: TUI changes only, on current main (cloud-tls/release.sh from #2117/#2119). Dropped here: the 🤖 Generated with Claude Code |
The TUI work from #2116, resubmitted on current main per review: login uses main's existing cloud-tls path; no new bin target, no cloud login changes, nothing under deploy/. - First run (terminal/onboarding.rs, session/first_run.rs): VEOX terms (TERMS_VERSION 2026-11-03), usage-statistics choice, then log in or continue with demos; stored in <JOPEDIME_HOME>/state.json. Agents and tests accept with JAIN_ACCEPT_TERMS=1. Acceptance is local only. - Demos (terminal/demos.rs, assets/demos): two CC-BY-4.0 UCI datasets embedded as example/*.csv, derived byte-for-byte from test-support fixtures; /demo [NAME], completion, licence and credit printed on selection; `\demo` registered in jope-api so /help lists it. Signed-out sessions open only the bundled demos from /open. - Links (terminal/links.rs): full, unwrapped URLs; OSC 8 hyperlinks for veox and loopback URLs where supported. - Screen/theme: jAIn by VEOX header and splash, blue accent. - cloud/sync/telemetry.rs: crate-visible chrono_like_now and a set_telemetry setter shared with `cloud telemetry on|off` (no login change). Commands in messages and docs name the `jopedime` executable. - Tests: PTY/e2e/live-driver harnesses set JAIN_ACCEPT_TERMS=1 and JAIN_ALLOW_LOCAL_FILES=1. Supersedes #2116 (branch alton/jain-cli-wave1 kept unchanged). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Wave 1 of the jAIn CLI onboarding plan (B1, B5, W2.1–2.3, W3.1, W3.2, W3.5, W3.8 header, W4.1). Naming follows the owner ruling: what you install and run locally is jAIn (
jain, productjain,JAIN_*, client_idjain-cli, header "jAIn by VEOX", J-A-I-N splash); hosted things are veox (veox Cloud Workspace, MCP, API).What changes
Binary and release lane (W2.1, B1, W2.2)
jainbin target;jopedimestays as a second target for the samemain.rs(no argv[0] dependence).jain --version/version --jsonreport productjainand a newfeatures.cloud_tls. Internal crate names unchanged.deploy/release/release.shbuilds--bin jain --features cloud-tls(artifact/receiptjain-*) and refuses a binary whoseversion --jsonlacks product jain + client + engine + cloud_tls + release trust (APPLIANCE_FEATURES).test-release.shcovers pass and refusal.deploy/appliance/build.sh: the publicnative-onlyprofile is now the installable CLI (embedded,engine,mcp,client,cloud-tls), verified from--version --json, and refuses any file in its models dir (no weights).models.lock.jsonstill records native-only at 0 weight bytes.aws-lc-sys/cc/cmake/pkg-configapproved as native build entries. Non-TLS selections keep featureless ureq and no TLS stack. Trust-surface change: needs a security review.distbuilds ofjainon this base: 20,405,928 B without and 23,823,520 B with cloud-tls (see A22).Demos (W2.3, W3.2)
example/*.csv:regression_parkinsons,binary_loan_approval,regression_apartment_rent,regression_tiny_soil. Generated deterministically byassets/demos/generate.pyfromtest-support/datasets/v1(every k-th row + catalog headers), receipts inmanifest.json./demolists demos;/demo NAME(also/demo regression) presets target/task/objective, opens and starts a fast run./open example/<name>.csvworks with no such file on disk (a real file wins). Tab completesexample/and demo names.\demois registered injope-apiso/helplists it.First run (W3.1)
TERMS_VERSION = "2026-11-03", https://veox.ai/terms; Enter/y accept, q/n exit) → usage statistics (default on;DO_NOT_TRACK=1orJAIN_TELEMETRY=0force off and skip; same file asjain cloud telemetry on|off) → log in to a free veox Cloud Workspace or continue with demos.<JOPEDIME_HOME>/state.json(0600, atomic, refuses symlinks; unknown fields preserved). Re-prompts whenTERMS_VERSIONchanges or the account'stermsCurrentis newer; a signed-in user's new acceptance is POSTed to/api/account/terms.jain --accept-terms ...orJAIN_ACCEPT_TERMS=1(skips the dialog).auth loginandcloud sync|runs|publish|fetchnever block without a terminal: they exit 2 with the terms URL (TERMS_NOT_ACCEPTEDJSON with--json). Local commands (fit,run, ...) are not gated.Anonymous gating
onboarding::local_file_gate/ANONYMOUS_LOCAL_FILES.JAIN_ALLOW_LOCAL_FILES=1lifts it (used by the PTY/e2e tests). CLI subcommands are not gated.Links and login (B5, W3.5, W4.1)
*.veox.ai/loopback URLs whose target equals their text, in terminals known to render it (iTerm2, WezTerm, kitty, VTE ≥ 0.50, Windows Terminal, VS Code;JAIN_HYPERLINKS=1/0). Line mode writes OSC 8 inline; the ratatui screen draws plain cells and re-emits URL cells as hyperlinks after each draw (ratatui 0.29 measures escape bytes as cell width). Trusted URLs that fit are never split across rows.open(macOS),explorer.exe URL(Windows, wasxdg-open),xdg-open(others); never waits; says "open the link on any device" when there is no display.client_id=jain-cli,client_name=jAIn CLI,scope=cli, plusterms_versiononce accepted. After login: "Logged in as ()" fromtierin/api/cli/account.Test evidence (local host, Rust 1.97.1, base origin/main 8c95bdc)
cargo test --locked -p jope-appliancewith and without--features cloud-tls,cargo test -p jope-api,cargo test -p jope-dist --test dependency_fence --test closure: all pass on this head's code (jope-appliance bin unit tests 206 passed / 6 ignored default, 205 / 6 with cloud-tls; e2e 7, pty_smoke 4, resize 2 (+1 ignored), single_file 23, store_transport 1, system 6 (+1 ignored); jope-api 33 + 2 + 10 + 6; jope-dist dependency_fence 4, closure 9).cargo clippy --locked -p jope-appliance -p jope-api --all-targets [--features jope-appliance/cloud-tls] -- -D warnings: clean.bash -p deploy/release/test-release.sh: 200/200 cases.jope-dist audit: clean for 7 feature selections.jope-dist noticeswith cloud-tls: 273 crates./open data.csv,/demo regression_tiny_soilran to "Run finished";state.json0600; the telemetry file matches the choice. Full-screen run withJAIN_HYPERLINKS=1emittedESC]8;;https://veox.ai/termsand no untrusted link. Non-TTYauth loginwithout terms exits 2 with the terms message;--accept-termsrecords sourceflag.termsCurrent), DO_NOT_TRACK/JAIN_TELEMETRY, first-run key paths, demo registry/paths/manifest receipts,example/and/democompletion, tier parsing.Not done / follow-ups
unknown; confirm redistribution terms (UCI Parkinsons and apartment rent, Rdatasets/Wooldridge loanapp) before a public release ships these bytes./demo binaryopens the dataset and explains that this engine cannot start it.dist), not ~4.5 MB as the plan assumed: the TUI needs the engine (20.4 MB) and cloud-tls adds 3.4 MB (static AWS-LC). Final package length is from an unsigned stage; signing pending.main.rstwice in all-target builds (cargo warns about the shared path);jainhastest = falseso unit tests run once./demowith no name prints a list rather than an interactive picker;jain mcp(stdio) is not terms-gated yet; no QR code for SSH logins (W4.1 QR).terminal/highlight.rsandterminal/runs.rson main left untouched.Contract with the app (ai-veox-app #112)
POST /api/cli/device:client_id=jain-cli,scope=cli,client_name=jAIn CLI, optionalterms_version=2026-11-03.GET /api/cli/account: readsaccountId,email,mayPublish,tier(alsoplan/plan.name),termsCurrent(re-prompt when newer than the accepted version).POST /api/account/terms(Bearer):{"version": "...", "source": "cli"}when a signed-in user accepts newer terms.🤖 Generated with Claude Code