Releases: lilcipherx/drift
Release list
Drift v0.3.0 — Docs, Hardening & Live E2E
Changed
- GitHub Action runs the CLI from its own checkout (
node packages/drift-cli/dist/cli.js,dist/committed,npm cifor workspace links) instead ofnpx -y @drift/cli— the Action works today, before any@drift/*package is published. - Code of Conduct (Contributor Covenant v2.0, enforcement contact = the repo owner) added and linked from README + CONTRIBUTING.
- New docs:
docs/quickstart.md(5-minute start),docs/api.md(full CLI reference: commands, flags, exit codes, JSON schemas, config.toml, env + MCP tools),docs/architecture.md(packages, storage, encryption at rest, webhook app, security model) — surfaced from the README top. - CONTRIBUTING/SECURITY/PR template refreshed: layout lists
drift-app, security scope includes the webhook server,drift-cryptomisnomer fixed (crypto lives indrift-core). drift-app dev/starthonorGITHUB_API_BASE_URLfor local-mock testing.
Fixed
- CLI fuzz hardening:
drift <unknown> --jsonemits a machine-readable JSON error instead of leaking the plain-text usage banner; all JSON output parses, no stack traces on any input (spaces, quotes,$(), unicode, tabs, newlines, long paths, garbage--line/--limit). - Path containment extended to symlinks/junctions: the realpath guard in
drift blame/contextalso blocks a link inside the repo pointing outside — before any filesystem read. Positive cases keep working. drift-app dev --dry-runactually dry:readOnlyon the handler builds the summary (action: "dry-run") with zero writes; previously it posted the comment and created a check run.
Added
- Live webhook-server E2E suite (
tests/app/live-server.test.mjs): real server + real GitHubAppClient (RS256 JWT) against a local mock GitHub API — opened/reopened, Link-header pagination (150 commits, trailer only on page 2), synchronize idempotent PATCH, repeated-delivery idempotency, missinginstallation.id, missing intent object → commit-subject fallback, PR withoutDrift-Intenttrailers, bad HMAC, 9 MB body → 413,/health. scripts/publish-npm.sh— one command to publish the@drift/ast → @drift/core → @drift/cli → @drift/mcpchain, confirm each version, and verify thenpx -y @drift/mcphandshake from an empty directory.- Fixed
@drift/climainfield and added themcpbin entry to@drift/mcpsonpx -y @drift/mcpresolves once published.
Tests
95/95 green (unit, temp-git-repo integration, MCP e2e, app unit + live webhook E2E).
Drift v0.2.3 — Wave-2 Audit Fixes
Fixed
doctor --fixno longer fails withFOREIGN KEY constraint failedwhen
deleting an intent that has children —deleteByIdnow reparents the
dependants to the deleted intent's parent first (transactional, with
rollback on error).- CLI usage errors stay machine-readable under
--json— an empty prompt
(-p "") or missing arguments previously printed plain-text usage to
stdout, which broke MCP tool callers. They now emit
{ "status": "error", "type", "message", "exitCode" }like every other
failure. drift blame/drift contextreject paths that escape the repository
root —../traversal, absolute and cross-drive paths (and symlinks
escaping the repo, via realpath) are rejected with a clean error before
any filesystem read. Previouslyblameread the file first, leaking
absolute paths in error messages and probing arbitrary files.
Tests
81 passing tests (was 77): +4 — deleteById reparenting (FK no longer fails),
the MCP JSON error contract (empty prompt / unknown intent), and path
containment coverage (absolute path, ../ traversal, --function, context).
Drift v0.2.2 — Production-Readiness Audit
Fixed
- AST parser no longer rejects valid code with regex literals — a regex containing
{/}//(e.g.const re = /}/) previously broke the brace-balance check and aborted the commit withParseError: Unexpected }(exit 2). Regex literals are now masked like strings and comments (escapes and[...]classes handled), and/used for division is not mistaken for a regex. drift log/drift contextno longer crash on non-finite--limit(Infinity,NaN,--limit 1e999): limits are clamped to a safe positive integer instead of being interpolated into SQLLIMIT Infinity.drift versionreads the real version frompackage.jsoninstead of a hardcoded string.- GitHub App (
@drift/app) hardening:- PR commits are paginated — pull requests with more than 100 commits are now fully scanned (cap 5000).
- Intent-object fetching stops as soon as every referenced intent is loaded.
- Webhook requests get a 30-second timeout.
- Oversized request bodies are rejected with 413 up to an 8 MB cap (was 1 MB / 500), so GitHub stops redelivering instead of retrying forever.
PORTis validated (0–65535).- Summary-table cells escape
|so untrusted paths/summaries cannot break the PR comment's markdown. - The response writer is guarded against
ERR_HTTP_HEADERS_SENTwhen a request is terminated mid-handling.
config.tomlinline#comments are now honored (outside strings).- SECURITY.md documents the trust boundary of
drift verify/--verify-cmd(shell execution).
Tests
77 passing tests (was 69): +8 — regex-literal masking (braces, char classes, escapes, division vs regex), non-finite --limit clamping in log/context/store (Infinity, NaN, negative, fractional), config.toml inline comments, and the app-server 413 path for oversized webhook bodies.
Removed
- GitHub Actions removed from the repository:
.github/workflows/ci.ymlandrelease.ymldeleted, all workflow runs deleted — no CI, no failing checks.
Drift v0.2.1 — Idempotent Summary Comments
Changed
- Idempotent summary comments in
@drift/app: the PR summary comment now embeds an invisible<!-- drift:summary -->marker. On any PR action (opened/synchronize/reopened) the handler finds the existing Drift comment and updates it in place (PATCH) instead of posting a new one — comments never accumulate on webhook retries or force-pushes. - Adds paginated
listIssueComments(Link-header walk, cap 10 pages) andupdateCommentGitHub API methods so the marker is found even on heavily-commented PRs.
Tests
69 passing (was 67): two new handler tests — synchronize updates the marker comment and leaves human comments untouched; synchronize without a prior Drift comment posts a fresh one.
Drift v0.2.0 — Encryption at Rest + GitHub App
Drift v0.2.0 — Encryption at Rest + GitHub App
Added
- AES-256-GCM encryption at rest (PRD §7.4, §17.1–17.2): with
[encryption] enabled = truein.drift/config.toml, intentpromptandagentStateare encrypted before storage (encv1:marker, random 12-byte IV per value, AAD bound to the intent id). Key comes fromDRIFT_MASTER_KEY(64-hex verbatim, otherwise SHA-256 passphrase). E_KEY(exit 4) when encryption is enabled but the key is missing, and when replaying encrypted state without it;drift log/blamedegrade to a[encrypted]placeholder so history stays readable.drift doctorgains anencryption-keycheck when encryption is on.@drift/appGitHub App (PRD §16):pull_requestwebhook handler that readsDrift-Intenttrailers from PR commits, hydrates intent objects from.drift/objects/at the PR head, and posts a semantic intent summary comment plus a check run. HMAC webhook signature verification, GitHub App JWT → installation-token auth, optional prompt decryption withDRIFT_MASTER_KEY,drift-app start/drift-app dev <payload> [--dry-run], mock payload fixture and smee.io webhook proxy script.- Backward compatible: legacy plaintext intents pass through untouched; the Ed25519 signature covers the stored (encrypted) canonical form, so signature verification never needs the master key.
Fixed
- Signature verification now uses the object file (source of truth) instead of DB rows, so row order can never invalidate a signature.
if/for/whileare no longer misreported as added "methods" by the parser.drift-appGitHub client sends aUser-Agent(GitHub rejects token requests without one) and caches installation tokens per installation (multi-tenant safe); client-side webhook errors are acked with 200 so GitHub stops redelivering.
Tests
54 passing tests: unit (encryption roundtrip/tamper/AAD, redaction, AST, config), integration (encrypted objects on disk, no plaintext leaks, E_KEY paths, legacy passthrough), MCP JSON-RPC e2e, and 13 drift-app tests (trailers, HMAC, JWT, handler with a fake GitHub client, HTTP server e2e).
Drift v0.1.0 — Intent-Driven Versioning
Drift v0.1.0 — Intent-Driven Versioning
Git tracks what changed. Drift tracks why it changed and who (or what) decided.
What's new
drift init— scaffolds.drift/: SQLite DAG store,config.toml, Ed25519 keypair.drift realize -p "<prompt>"— intent commit with AST delta, secret redaction, Ed25519 signature and aDrift-Intent:trailer; rejects broken syntax (exit 2) before any history is created.drift log,drift blame --line|--function,drift context,drift verify,drift replay --checkout,drift doctor,drift export.- Semantic parser for TypeScript/JavaScript and Python: symbol extraction plus ADDED / MODIFIED / DELETED / MOVED / RENAMED deltas, with a real syntax gate.
- MCP server (
@drift/mcp):drift_realize,drift_context,drift_replay,drift_blame,drift_verify,drift_logfor AI agents. - SDK (
@drift/sdk) with Zod intent schemas. - GitHub Action (
action.yml) for intent checks in CI. - Test suite: 40 tests (unit, temp-git-repo integration, MCP JSON-RPC e2e).
- Demo repo generator (
scripts/seed-demo.sh) — dogfoods the CLI.
Security
- Ed25519 signing of every intent; verification via object-file canonical JSON.
- Default secret redaction patterns (AWS, OpenAI, GitHub, Slack, JWT, PEM…).
- Keys are never committed (
.drift/keys/gitignored) except throwaway demo keys.
Quickstart
npm install && npm run build
drift init && drift realize -p "Add login flow" --agent
drift log