All notable changes to franken_snowflake are recorded here. The format follows
Keep a Changelog, and the project will
adopt Semantic Versioning once it ships a
tagged release.
This is the development history of franken_snowflake to date. As of this
writing the repository holds 166 non-merge commits from 2026-06-24 to
2026-06-29, with no git tags and no GitHub Releases. There is no published
crate and no tagged release yet, so there is no version timeline to reconstruct;
everything below sits under a single Unreleased heading.
The record is organized by landed capability wave rather than raw commit order, with representative commit links so another agent can navigate from a theme to the evidence. Chronology is preserved through the timeline table below and the dates noted in each section. The sources used to build this changelog are:
- the git history (
git log --reverse --no-merges) - the design documents (
COMPREHENSIVE_PLAN_FOR_FRANKEN_SNOWFLAKE.md,docs/asupersync_leverage.md, and the rest ofdocs/) - the executable task graph in
.beads/issues.jsonl, tracked with Beads (br) - the release-readiness checklist in
RELEASE.md
A note on commit subjects: many early commits are tagged "code-first, batch-test pending." That reflects the project's working style, where a swarm lands the implementation first and the test/hardening pass follows in a later wave. The "Hardening and fresh-eyes review" section captures that follow-up.
- Package version:
0.0.0across the workspace; all crates inheritpublish = false. - Releases: none yet. No git tag, no GitHub Release, no crates.io publish.
- Live Snowflake transport is enabled with the
livefeature (default-off) and is gated at runtime by credential availability. Reads (query run,catalog scan,profile doctor --online) and writes (query write) both run through it.
| Window | Theme |
|---|---|
| 2026-06-24 | Architecture plan, workspace scaffold, lint policy, and the first pass at core, auth, http, sqlapi, catalog, cache, frame, export, graph, testkit, and CLI |
| 2026-06-25 | Hardening wave: MCP serve adapter, optional TUI, redaction and safety fixes across every crate, write-intent ladder types, cross-platform CI |
| 2026-06-26 | Live proof lanes, opt-in live transport wired into query run / catalog scan / profile doctor --online, and the agent-ergonomics CLI pass (onboard, fsnow alias) |
| 2026-06-29 | Hero illustration and GitHub social preview image |
| 2026-06-29 | Live writes: write-intent ladder executor (frictionless-by-default), query write/write, default-profile env + installer --live |
The repository opened with the architecture plan, the task graph, and the design
docs, then a Phase 0 commit established the Cargo workspace (resolver = "3",
edition 2024), the minimal crate skeletons, and the governance docs. The
workspace-wide lint policy is load-bearing: forbid(unsafe_code) plus deny on
clippy::unwrap_used, expect_used, panic, todo, and dbg_macro, inherited
by every crate via [lints] workspace = true. CI gates were added in the same
window: a toolchain and single-Asupersync-version gate, a per-crate
forbidden-dependency admissibility scan, and a cross-platform check matrix for
Linux, macOS, and Windows.
Representative commits
1b5bed6Initial commit: architecture plan, task graph, and design docs95b4965Phase 0: Cargo workspace, minimal-five crate skeletons, governance docsdf2b0aaci: enforce toolchain and asupersync gatesb1466f2ci: add dependency admissibility cargo-tree gatecc353cbci: establish cross-platform support
Notes for agents: the forbidden list (Tokio, reqwest, hyper, axum, tower,
sqlx, diesel, sea-orm, third-party Snowflake drivers) is enforced by
scripts/check-dependency-admissibility.py. Run the gates listed in RELEASE.md
before assuming a change is admissible.
franken-snowflake-core is the contract hub. It defines the deterministic,
versioned JSON envelope, the central error-code registry (each FSNOW-<code>
maps once to a default recovery path), the capability registry, the exit-code
dictionary, and the id newtypes. It then adopted the Asupersync Outcome,
Budget, CancelReason, and capability primitives so the connector's
four-valued result and cost-quota model come straight from the runtime. Security
and cost guardrails, the redactor, and the write-intent ladder types landed here
too. Later fixes tightened the read guard against block-comment evasion,
projected policy refusals and statement timeouts as typed outcome kinds, and
added the SurfaceReserved code (FSNOW-9002, an exit-2 refusal).
Representative commits
82b1a7ecore: shared types, error registry, JSON enveloped086813core: adopt Asupersync Outcome/Budget/CancelReason/capabilities2b01739core: add security and cost guardrailsac83c11core: fix redactor token-boundary so secrets after=/:are redactedf16c117Add write-intent ladder typesb137675fix(core): close read-guard fail-open on nested block comments1a33396feat(core): add SurfaceReserved error code (FSNOW-9002, exit 2 refusal)
Notes for agents: exit codes are coarse and stable (0 success, 2 safety
refusal, 3 credential error, 4 upstream, 5 network/budget, 6 still running, 7
local cache, 64 usage, 74 I/O). The richer signal is the envelope's
outcome_kind and FSNOW- code.
Authentication landed in lane order. The RS256 key-pair JWT signer came first,
then a secret-safe PAT and OAuth bearer model. The compile-time credential
Debug-leak gate fails the build if a credential-shaped field derives Debug;
follow-up commits hardened it, tightened credential-field leak detection,
rejected secret-shaped auth source handles, and normalized Snowflake JWT locator
accounts. Profiles reference env-var names, never raw token values.
Representative commits
cbd8129auth: implement RS256 key-pair JWT signer501d3c4auth: add secret-safe PAT OAuth auth model14cae15auth: add credential debug leak gate379334fTighten credential field leak detectione46e88bReject secret-shaped auth source handles
Notes for agents: the secret needle lists used by the redactor and the cache
are shared on purpose; if you add a credential prefix, update the shared list so
every surface redacts it. See docs/security_model.md.
franken-snowflake-http is the native transport, built on Asupersync HTTP/1.1
plus TLS plus gzip with no injected Tokio transport. It owns retry policy and the
subtleties around it: a 408 statement-timeout is terminal rather than retryable,
unsafe submit retries are blocked, child budgets bound transport work, the
idempotent cancel route is retried, and Retry-After is parsed (including the
HTTP-date form, measured against the real wall clock). Hardening hid HTTP body
bytes from Debug, redacted transport error messages, encoded submit query
parameters, and tightened Snowflake URL boundaries.
Representative commits
012a9f6http: implement Asupersync native transport8734101http: block unsafe submit retries1d89de0http: treat 408 statement-timeout as terminal (not retryable)e8a8b1dhttp: parse Retry-After HTTP dates627abb8fix(http): measure HTTP-date Retry-After against the real wall clock96825a3Hide HTTP body bytes from Debug
Notes for agents: retry ownership is split. The submit POST is not blindly
retried; idempotency is the SQL API requestId plus retry=true contract. See
docs/transport_design.md and docs/asupersync_leverage.md.
franken-snowflake-sqlapi carries the protocol. The request/response/status
schemas landed with golden fixtures and round-trip proofs, including a fix for
the jsonv2 codec decoding negative pre-1970 fractional timestamps. The statement
lifecycle is a state machine driving submit, poll, partition stream, and cancel;
later fixes preserved poll cancellation attribution, closed the lifecycle machine
on terminal failure, preserved terminal-failure projection, and hardened
partition and cancel integrity (including rejecting invalid partition stream
seeds).
Representative commits
d5e08d3sqlapi: SQL API request/response/status protocol schemas (kx6)b67b393sqlapi: no-account golden fixtures + round-trip proofs (kx6)149ff13sqlapi: fix jsonv2 codec negative pre-1970 fractional timestamp decode0685e1esqlapi: complete statement lifecycle driver89ed6b3fix(sqlapi): close lifecycle machine on terminal failure8219eb6Harden SQL API partition and cancel integrity
Notes for agents: the jsonv2 cell codec is golden-pinned. Changes to decoding
must keep test(sqlapi): pin jsonv2 codec cell golden green.
franken-snowflake-catalog covers INFORMATION_SCHEMA discovery, the dataset
model, the operator catalog, and the safe query planner. The manifest discovery
and the dataset query planner landed first, then a series of correctness fixes:
discovery scope filters are bound, raw SQL scanning is literal-aware, time-travel
timestamps render as cast literals, unsupported predicate operators are refused,
operator schemas accept singleton arrays, dataset ids are collision-resistant,
and time-index enum boundaries are pinned.
Representative commits
cfed05bcatalog: implement information schema manifest discovery959e899catalog: implement safe dataset query planner1c7dc94fix(catalog): make raw SQL scanning literal-awared131968fix(catalog): refuse unsupported predicate operators9938375fix(catalog): make dataset ids collision-resistant
Notes for agents: filters are a dumb predicate AST validated against the
column and operator catalogs, not free-form SQL. See
docs/dataset_manifest_contract.md and docs/catalog_graph_design.md.
The lineage graph (franken-snowflake-graph) models catalog containment and
renders Mermaid/SVG; fixes escaped Mermaid labels per the Mermaid rules, locked
the cycle loop-order, rebuilt graph indexes after deserialize, rejected
conflicting output formats, and excluded a seed node from its own neighborhood.
Frame materialization (franken-snowflake-frame, via the focused fp-columnar
and fp-types crates) preserved scaled NUMBER decimals and i64 boundary
fidelity, and emits VARIANT/OBJECT/ARRAY cells verbatim to preserve precision.
Export (franken-snowflake-export) added content-addressed result exports, fixed
CSV correctness against its goldens, and rejected COPY INTO injection inputs.
The cache (franken-snowflake-cache) added the local repository layer, fails
closed on an unknown content-address algorithm, and aligns the in-memory backend
with the SQLite append-only contract. Text-indexing (franken-snowflake-text-indexing)
planned and hardened the optional frankensearch lane (hash/lexical only).
Representative commits
ecd4696graph: model catalog lineage output0d9d492graph: escape Mermaid labels per Mermaid rules; lock in cycle loop-order1e86495fix(export,frame): emit VARIANT/OBJECT/ARRAY cells verbatim to preserve precisiond1d1ba8export: add content-addressed result exports5d0af38fix(export): reject COPY INTO injection inputsc234120cache: fail closed on unknown content-address algorithm
Notes for agents: local export is CSV/JSONL only; fp-io is forbidden (its
orc-rust dependency pulls Tokio). Large export goes through Snowflake-side
COPY INTO. See docs/cache_repository_design.md.
franken-snowflake-testkit is the deterministic proof substrate. It provides a
shared harness (a golden framework, a JSON-line logger, a deterministic clock,
and a canary guard), determinism and schema-stability self-tests, a deterministic
Snowflake SQL API mock with replay, a deterministic cancel/retry race suite, and
a deterministic mock e2e harness. Hardening made the DPOR race suite fully
deterministic (treating step-budget truncation as inconclusive), avoided a panic
when truncating long multi-byte diff values, and redacted replay packet
recordings, recorded mock request paths, and mock HTTP Debug surfaces.
Representative commits
f88883btestkit: shared harness (golden framework, json-line logger, deterministic clock, canary guard)16add23testkit: add deterministic Snowflake SQL API mock replayc6a4ae0testkit: add deterministic cancel retry race suitedcaea80test: add deterministic mock e2e harnessf734acefix(testkit): make the DPOR cancel/retry race suite deterministic
Notes for agents: the two test lanes are a deterministic codec lane under the
lab runtime (over virtual TCP, with DPOR coverage) and an integration lane
against the mock server. See docs/proof_lanes.md.
franken-snowflake-cli owns the public command contract and produces both the
canonical franken-snowflake binary and the short fsnow alias. The draft
command surface, required-argument enforcement, offline profile
diagnostics, and the initial command contracts landed first, with live query
surfaces mapped to clean safety refusals. The agent-ergonomics pass added the
onboard mega-command, the fsnow alias with accurate compiled feature_flags,
exit-code precision, query-error pedagogy, and a catalog graph rendered from a
live scan. A long tail of parser fixes hardened flag handling: equals-style flag
values, rejecting missing or ambiguous flag values, keeping help positional
values parseable, gating the toon feature, and reporting the mcp feature in
capabilities.
Representative commits
29e2cd9cli: draft agent command surface90c27aacli: integrate MVP command contractsd08f600feat(cli): addfsnowshort bin alias + report accurate compiled feature_flags90e7485feat(cli): addonboardmega-command (one-call agent orientation)3f687f5fix(cli): exit-code precision + query error pedagogy + feature-aware tests69a6fc3feat(cli): rendercatalog graphfrom a live catalog scan
Notes for agents: read commands default to --json; --toon needs the
default toon feature. There is no completions subcommand; discover the
surface through fsnow capabilities --json. See docs/agent_cli_contract.md.
The MCP serve adapter (franken-snowflake-mcp) exposes the read verbs as MCP
tools over shared CLI handlers, so the CLI and MCP share one envelope contract.
The crate skeleton went in first to unblock the workspace check, then the serve
adapter, the query cancel parity tool, redaction of invalid-parameter errors,
a fix to strip exactly one http: tag from the serve address, and a
single-version dependency-gate fix. The optional FrankenTUI surface
(franken-snowflake-tui) landed behind its own feature (default-off), with a fix
to make the query-pane keys executable and a combined MCP/TUI review-defect pass.
Representative commits
1b31bd0feat: implement MCP serve adapter49d0b73fix(mcp): expose query cancel parity toolcc46bddfix(mcp): strip only onehttp:tag from the serve addressb2d987efeat: add optional FrankenTUI surface21beeecFix MCP and TUI review defects
Notes for agents: mcp serve exposes the read and discovery verbs and is
stdio-first by design; data writes go through the CLI query write ladder. The
tool roster mirrors the CLI read verbs (capabilities, onboard, doctor,
agent_handbook, robot_docs_guide, selftest, profile_validate, profile_doctor,
catalog_scan, catalog_graph, dataset_inspect, dataset_profile,
dataset_describe_operator, query_plan, query_run, query_cancel, receipt_show,
export_plan).
The opt-in live lane is the live feature. Live proof lanes landed first, then
two rounds of live-protocol decode fixes (each guarded by regression goldens so
the offline build still proves the change). The CLI live wiring went in as three
slices: query run, catalog scan, and the profile doctor --online probe. The
runtime contract is strict: with the feature compiled and credentials present,
the command runs and the envelope carries data_source = "live" and the real
statement handle; with the feature compiled but a credential handle absent, the
command returns a typed credential error (exit 3); without the feature, the
command refuses cleanly rather than substituting fixture or empty data.
Representative commits
1e48db8Add opt-in Snowflake live proof lanes7a50a0efix(sqlapi): land live-testing protocol decode fixes (hij)0b30bc6test(sqlapi): no-account regression guards for the live partition decode fixes (ko8)71cff91feat(cli): wire live SQL API transport intoquery run(9o1, slice 1/3)4a0b791feat(cli): wire live transport intocatalog scan(9o1, slice 2/3)99dfb10feat(cli): wire liveprofile doctor --onlineprobe (9o1, slice 3/3)
Notes for agents: live read results are capped into the envelope with a
truncated flag and a warning; full extraction uses a Snowflake-side LIMIT or
COPY INTO. Live session parameters are pinned (UTC, fixed date/time formats,
result cache disabled) for stable output. See docs/live_proof.md.
This wave turned the write-intent ladder from a set of core types into a live
executor on the CLI. query write runs a mutation in two rungs. A --dry-run
classifies the statement (statement_kind, safety_class), plans it without
executing anything, and returns a required_confirmation_token (for example
confirm:insert:<idempotency-id>) bound to the (profile, SQL) pair; a re-run
with --confirm <token> authorizes the ladder and submits the statement through
the live SQL API transport, returning a data_source = "live" execution receipt
with the statement handle and rows affected. Data writes
(INSERT/MERGE/UPDATE/DELETE/COPY INTO/PUT) execute once a profile sets
FRANKEN_SNOWFLAKE_<PROFILE>_WRITE_ENABLED=true; DDL
(CREATE/ALTER/DROP/TRUNCATE/GRANT/REVOKE) needs the additional
FRANKEN_SNOWFLAKE_<PROFILE>_WRITE_ALLOW_DDL=true. The refusals are typed:
FSNOW-3007 (writes not enabled), FSNOW-3008 (confirmation required or
mismatched), FSNOW-3009 (DDL not opted in), and FSNOW-2003 (credential
missing). write is a top-level alias for query write. Without the live
feature or without credentials the command refuses cleanly and never fakes an
execution.
A follow-up made writes frictionless by default: once a profile sets
WRITE_ENABLED, a bare query write (no --dry-run, no --confirm) executes
directly, and the dry-run to confirm ceremony is now opt-in per profile via
WRITE_REQUIRE_CONFIRM=true. A further change added a
FRANKEN_SNOWFLAKE_DEFAULT_PROFILE fallback (so --profile is optional) and an
installer --live / -Live flag that builds the live-capable binary.
Representative commits
ee54952Live writes: the write-intent ladder executor (query write/writealias)8c4a860Execute writes directly by default onceWRITE_ENABLED;WRITE_REQUIRE_CONFIRMopt-in restores the dry-run to confirm gate34f5440AddFRANKEN_SNOWFLAKE_DEFAULT_PROFILEfallback and the installer--liveflag
Notes for agents: the confirmation token only authorizes a re-run of the same
statement on the same profile, so a plan cannot be replayed against different
SQL. query run is the read path; route any mutation through query write.
Several waves were dedicated to review rather than new features. The open-source-readiness prep, the downstream adapter contract fixtures, and repeated fresh-eyes review rounds landed verified bug and chore fixes across the workspace (recorded in Beads). Dependency-lane coverage was extended to the graph and toon lanes. A recent commit added the hero illustration and the GitHub social preview image.
Representative commits
2680b71release: prepare open-source readinessfab86f5Add downstream adapter contract fixtures6f0851afix: land stalled fresh-eyes-review fix round to verified greenfcf049dCover graph and toon dependency lanes8bacec5docs: add hero illustration to README + GitHub social preview image
Notes for agents: the gate that decides whether the tree is releasable is
RELEASE.md. A SemVer version and the first tagged release come once RELEASE.md is
satisfied and publish = false is flipped deliberately.
- Start from
br ready --jsonfor actionable work andbr dep cyclesfor graph health. Beads is the task source of truth, not GitHub issues. - The full rationale lives in
COMPREHENSIVE_PLAN_FOR_FRANKEN_SNOWFLAKE.mdand the Asupersync leverage contract indocs/asupersync_leverage.md. - Live Snowflake use is enabled with the
livefeature. Do not treat local fixtures as live data; every live lane either provides explicit credential evidence or emits a typed skip/refusal. - Once the first public release is tagged, this file gains a dated, versioned
entry with the commit range and the proof evidence from
RELEASE.md.