mirror of
https://github.com/olehomelchenko/astrolabe.git
synced 2026-08-08 02:02:33 +00:00
Copy: state the AI-free stance as a confidentiality benefit; record the exploration
This commit is contained in:
@@ -37,7 +37,9 @@ npm test # Vitest
|
|||||||
- **Theming & fonts** — custom chart themes with a visual Theme Builder, a curated font roster,
|
- **Theming & fonts** — custom chart themes with a visual Theme Builder, a curated font roster,
|
||||||
and your own uploaded font faces.
|
and your own uploaded font faces.
|
||||||
- **Local-first** — your library lives in the browser (IndexedDB); offline-capable and installable
|
- **Local-first** — your library lives in the browser (IndexedDB); offline-capable and installable
|
||||||
(PWA), with import/export for backup and transfer. No account, no server.
|
(PWA), with import/export for backup and transfer. No account, no server, no AI — with no
|
||||||
|
backend to send it to, your library stays on your device, so it's safe for confidential work
|
||||||
|
from the first chart.
|
||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
|
|||||||
@@ -28,8 +28,10 @@ data lives in one place and the specs stay lean.
|
|||||||
### 1. Local-Only by Default
|
### 1. Local-Only by Default
|
||||||
|
|
||||||
Everything runs in the browser. Snippets, datasets, and settings never leave the machine.
|
Everything runs in the browser. Snippets, datasets, and settings never leave the machine.
|
||||||
No accounts, no uploads, no tracking. The only outbound requests are user-created
|
No accounts, no uploads, no tracking, and the app contacts no third party on its own —
|
||||||
URL-dataset fetches.
|
including an AI model. The only outbound requests are user-created URL-dataset fetches.
|
||||||
|
Because your work stays on the machine, confidential and work data are safe in Astrolabe
|
||||||
|
from the first chart.
|
||||||
|
|
||||||
### 2. Vega-Lite Native, Not Vega-Lite Hidden
|
### 2. Vega-Lite Native, Not Vega-Lite Hidden
|
||||||
|
|
||||||
@@ -71,6 +73,9 @@ clever.
|
|||||||
- **Not a collaboration platform.** No multi-user, no sync, no comments. Import/export
|
- **Not a collaboration platform.** No multi-user, no sync, no comments. Import/export
|
||||||
moves data between machines.
|
moves data between machines.
|
||||||
- **Not a server app.** No backend, no rendering service, no account system.
|
- **Not a server app.** No backend, no rendering service, no account system.
|
||||||
|
- **Not an AI tool.** No model authors, edits, or critiques charts, and nothing is sent to
|
||||||
|
one. The chart builder's recommendations are deterministic and rule-based, computed
|
||||||
|
locally — chosen over an LLM so results are explainable and nothing leaves the machine.
|
||||||
|
|
||||||
## Technical Philosophy
|
## Technical Philosophy
|
||||||
|
|
||||||
|
|||||||
@@ -15,3 +15,4 @@ snapshots, not live numbers.
|
|||||||
- `chart-builder-enhancement-scope.md` — consolidated Tier-B → Tier-C forward plan for the Chart Builder.
|
- `chart-builder-enhancement-scope.md` — consolidated Tier-B → Tier-C forward plan for the Chart Builder.
|
||||||
- `chart-theming-scope.md` — chart theming plan and slice breakdown.
|
- `chart-theming-scope.md` — chart theming plan and slice breakdown.
|
||||||
- `monetization-and-sync-exploration.md` — monetization + BYO-cloud-sync direction memo.
|
- `monetization-and-sync-exploration.md` — monetization + BYO-cloud-sync direction memo.
|
||||||
|
- `ai-augmentation-exploration.md` — why Astrolabe stays AI-free, and the key-storage security analysis behind it.
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
# AI Augmentation — Exploration
|
||||||
|
|
||||||
|
> **Status:** Exploration, not a commitment. Captured 2026-06-27 from a strategy
|
||||||
|
> conversation. The conclusion is folded into [`SOUL.md`](../../SOUL.md) (_Local-Only by
|
||||||
|
> Default_ and _Not an AI tool_); this memo keeps the _reasoning_ — including the security
|
||||||
|
> analysis behind rejecting browser-stored keys — so a future "should we add AI?" session
|
||||||
|
> doesn't re-derive it.
|
||||||
|
>
|
||||||
|
> **Question:** Most tools shipping in 2026 carry some AI/LLM augmentation. Should
|
||||||
|
> Astrolabe?
|
||||||
|
>
|
||||||
|
> **Short answer:** No — and the user benefit, not purity, is the reason. With no server,
|
||||||
|
> no account, and no AI, nothing the user makes is handled by a third party, so Astrolabe
|
||||||
|
> is safe for confidential and work data from the first chart. "Everyone ships AI in 2026"
|
||||||
|
> is the weakest possible reason to add it: ubiquity makes AI table-stakes noise, not
|
||||||
|
> differentiation, and a tool that demonstrably keeps your data on your machine is
|
||||||
|
> differentiated _because_ it resists the trend.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Where AI would genuinely fit, if ever
|
||||||
|
|
||||||
|
Two spots where Vega-Lite is actually painful and rules can't help but a model could:
|
||||||
|
natural-language authoring (NL → spec) and explaining/decoding the editor's opaque
|
||||||
|
validation errors. The obvious third — "recommend a chart from my data" — is **already
|
||||||
|
solved deterministically** by the Chart Builder's rule-based inference, and the rule-based
|
||||||
|
version is better here because it's explainable and runs locally. So the genuine surface is
|
||||||
|
narrow.
|
||||||
|
|
||||||
|
## 2. Why browser-stored BYO keys were rejected
|
||||||
|
|
||||||
|
The only AI model consistent with "no server, no account" is bring-your-own-key, called
|
||||||
|
direct browser → provider (never proxied through a server we run, which would put us back in
|
||||||
|
the data-custody business). The blocker is key storage:
|
||||||
|
|
||||||
|
- A browser has **no secure vault for a secret you must read back**. localStorage,
|
||||||
|
IndexedDB, cookies — all readable by any same-origin JS, devtools, and extensions. Client
|
||||||
|
encryption only helps if the unlock secret isn't _also_ stored, i.e. a passphrase typed
|
||||||
|
each session; a key kept beside its ciphertext is theater.
|
||||||
|
- The dominant threat is therefore **same-origin script execution (XSS)**, and Astrolabe is
|
||||||
|
unusually exposed to it: it renders arbitrary user specs through vega-embed, whose
|
||||||
|
expression evaluator and data loader are a real script-execution / exfiltration surface.
|
||||||
|
Holding a secret in that origin upgrades any spec-driven bug from "annoying" to "steals
|
||||||
|
the user's key." **Introducing a stored secret raises the threat level of the whole app,
|
||||||
|
the chart renderer included** — the opposite of what the privacy posture exists to do.
|
||||||
|
- The one mitigant: LLM keys are revocable and spend-cappable, so the blast radius is "bill
|
||||||
|
abuse until you rotate it," not data loss. That's why the industry tolerates browser BYOK
|
||||||
|
at all — but it doesn't undo the origin-coupling above.
|
||||||
|
|
||||||
|
**If AI is ever revisited:** the only acceptable form is a **session-only** key (held in
|
||||||
|
memory, never persisted, re-entered each session) called browser → provider direct, with the
|
||||||
|
core staying fully functional and offline for anyone who never engages it. Persisting the
|
||||||
|
key is the specific part that compromises the posture.
|
||||||
@@ -6,6 +6,10 @@
|
|||||||
<link rel="mask-icon" href="/icon-mono.svg" color="#0e7490" />
|
<link rel="mask-icon" href="/icon-mono.svg" color="#0e7490" />
|
||||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
content="A local-first studio for Vega-Lite charts. Author specs as JSON, see them render live, and keep a searchable library in your browser. No account, no server, no AI — with no backend to send it to, your data stays on your device, so confidential work is safe here from the first chart."
|
||||||
|
/>
|
||||||
<title>Astrolabe — a local Vega-Lite studio</title>
|
<title>Astrolabe — a local Vega-Lite studio</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* Rendered inside ModalShell — no backdrop, close button, or focus trap here;
|
* Rendered inside ModalShell — no backdrop, close button, or focus trap here;
|
||||||
* the shell owns all of that (docs/architecture/03 → Layer 3). This component
|
* the shell owns all of that (docs/architecture/03 → Layer 3). This component
|
||||||
* is pure content: app identity, keyboard shortcuts (§01D), privacy posture
|
* is pure content: app identity, keyboard shortcuts (§01D), privacy posture
|
||||||
* (SOUL.md — local-only, no accounts, no telemetry), and acknowledgements of
|
* (SOUL.md — local-only, no accounts, no telemetry, no AI), and acknowledgements of
|
||||||
* the projects Astrolabe is built on and shaped by.
|
* the projects Astrolabe is built on and shaped by.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -74,10 +74,15 @@ export function AboutModal() {
|
|||||||
<h3 className={styles.heading}>Privacy</h3>
|
<h3 className={styles.heading}>Privacy</h3>
|
||||||
<p className={styles.body}>
|
<p className={styles.body}>
|
||||||
Astrolabe runs in your browser. Your snippets, datasets, and settings are stored locally
|
Astrolabe runs in your browser. Your snippets, datasets, and settings are stored locally
|
||||||
on your device — there’s no server to send them to.
|
on your device — there’s no server to send them to. Work that has to stay
|
||||||
|
confidential is safe here.
|
||||||
</p>
|
</p>
|
||||||
<ul className={styles.list}>
|
<ul className={styles.list}>
|
||||||
<li>No account or sign-in.</li>
|
<li>No account or sign-in.</li>
|
||||||
|
<li>
|
||||||
|
No AI. No model authors, edits, or critiques your charts, and nothing is sent to one.
|
||||||
|
The chart builder’s suggestions are computed locally from your data.
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
The app itself runs no analytics or tracking. Its host (Cloudflare) records standard,
|
The app itself runs no analytics or tracking. Its host (Cloudflare) records standard,
|
||||||
aggregate traffic like any web server — not your library or the charts you build, which
|
aggregate traffic like any web server — not your library or the charts you build, which
|
||||||
|
|||||||
@@ -598,16 +598,18 @@ export function Landing(): ReactNode {
|
|||||||
Your charts are <b>yours.</b>
|
Your charts are <b>yours.</b>
|
||||||
</h2>
|
</h2>
|
||||||
<p className={styles.creedLede}>
|
<p className={styles.creedLede}>
|
||||||
Astrolabe runs in your browser, and what it makes is ordinary Vega-Lite JSON — read it,
|
Astrolabe runs in your browser, and your charts and data stay there — no account, no
|
||||||
edit it in other tools, or take it elsewhere whenever you want.
|
server, no AI behind it to send them to — so work that has to stay confidential is safe
|
||||||
|
here from the first chart. And what it makes is ordinary Vega-Lite JSON: read it, edit
|
||||||
|
it in other tools, or take it elsewhere whenever you want.
|
||||||
</p>
|
</p>
|
||||||
<div className={styles.creedGrid}>
|
<div className={styles.creedGrid}>
|
||||||
<div>
|
<div>
|
||||||
<span className={styles.creedKey}>private</span>
|
<span className={styles.creedKey}>private</span>
|
||||||
<h3>Local to your browser</h3>
|
<h3>Local to your browser</h3>
|
||||||
<p>
|
<p>
|
||||||
Charts, data, and themes are saved in this browser, and it keeps working offline
|
Charts, data, and themes are saved in this browser and nowhere else — there is no
|
||||||
once installed.
|
server behind Astrolabe to receive them. It keeps working offline once installed.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
Reference in New Issue
Block a user