Scaffold cargo workspace + heph-core foundation
Kick off Phase 1 (v1 prototype) per tech-spec §11.1. Sets up the Cargo
workspace and the first TDD slice of heph-core:
- Migration runner + §4.5 SQLite schema (nodes, tasks, links, aliases,
users, oplog, sync_state, conflicts), versioned via PRAGMA user_version.
- Clock-injected `Clock` trait (no ambient wall-clock reads; §2).
- `Store` trait + `LocalStore` SQLite backend with node create/get,
bootstrapping the single local user (oidc_sub NULL, §13).
- Node model (kinds: doc/task/project/tag/journal).
Repo housekeeping: fill AGENTS.md Project Structure (last template TODO),
ignore /target, add self-bootstrapping .forgejo/scripts/build that runs
cargo fmt/clippy/test in CI (§9), changelog fragment.
Tests green: 4 unit tests (migration version, local-user idempotency,
create/get round-trip, missing-node None).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 18:52:15 -07:00
|
|
|
[workspace]
|
|
|
|
|
resolver = "2"
|
heph CLI + export
Slice 7 (tech-spec §1, §5, §9).
- Export (heph-core): render each non-tombstoned node to `<kind>/<id>.md`
with YAML frontmatter (id, kind, title, timestamps, task scalars,
aliases, outgoing links) + body. One-way snapshot; `Store::export`
writes the tree; tombstones excluded. Added `export` RPC method and
Error::Io.
- `heph` CLI (clap): thin client of hephd over the socket — `next`
(concise ranked rows), `task`, `doc`, `get`, `export`. Never touches
SQLite directly.
Tests: 3 export render unit + 2 export round-trip integration + 3 CLI
process tests driving the real `heph` binary against a real daemon
(task→next, empty-store message, export writes files). 70 tests green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 20:33:59 -07:00
|
|
|
members = ["crates/heph-core", "crates/hephd", "crates/heph"]
|
Scaffold cargo workspace + heph-core foundation
Kick off Phase 1 (v1 prototype) per tech-spec §11.1. Sets up the Cargo
workspace and the first TDD slice of heph-core:
- Migration runner + §4.5 SQLite schema (nodes, tasks, links, aliases,
users, oplog, sync_state, conflicts), versioned via PRAGMA user_version.
- Clock-injected `Clock` trait (no ambient wall-clock reads; §2).
- `Store` trait + `LocalStore` SQLite backend with node create/get,
bootstrapping the single local user (oidc_sub NULL, §13).
- Node model (kinds: doc/task/project/tag/journal).
Repo housekeeping: fill AGENTS.md Project Structure (last template TODO),
ignore /target, add self-bootstrapping .forgejo/scripts/build that runs
cargo fmt/clippy/test in CI (§9), changelog fragment.
Tests green: 4 unit tests (migration version, local-user idempotency,
create/get round-trip, missing-node None).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 18:52:15 -07:00
|
|
|
|
|
|
|
|
[workspace.package]
|
|
|
|
|
edition = "2021"
|
|
|
|
|
version = "0.0.0"
|
|
|
|
|
license = "LicenseRef-Proprietary"
|
|
|
|
|
publish = false
|
|
|
|
|
authors = ["Erich Blume <blume.erich@gmail.com>"]
|
|
|
|
|
rust-version = "1.85"
|
|
|
|
|
|
|
|
|
|
[workspace.dependencies]
|
|
|
|
|
rusqlite = { version = "0.32", features = ["bundled"] }
|
|
|
|
|
ulid = "1"
|
|
|
|
|
thiserror = "2"
|
|
|
|
|
anyhow = "1"
|
2026-05-31 18:56:59 -07:00
|
|
|
pulldown-cmark = { version = "0.13", default-features = false }
|
2026-05-31 19:14:22 -07:00
|
|
|
rrule = "0.13"
|
2026-06-01 09:06:17 -07:00
|
|
|
yrs = "0.26"
|
2026-05-31 19:14:22 -07:00
|
|
|
chrono = { version = "0.4", default-features = false, features = ["clock"] }
|
2026-05-31 20:28:15 -07:00
|
|
|
serde = { version = "1", features = ["derive"] }
|
|
|
|
|
serde_json = "1"
|
|
|
|
|
tokio = { version = "1", features = [
|
|
|
|
|
"rt-multi-thread",
|
|
|
|
|
"net",
|
|
|
|
|
"io-util",
|
|
|
|
|
"macros",
|
|
|
|
|
"sync",
|
|
|
|
|
"time",
|
|
|
|
|
] }
|
|
|
|
|
tracing = "0.1"
|
|
|
|
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
|
|
|
|
clap = { version = "4", features = ["derive"] }
|
|
|
|
|
fs4 = "0.12"
|
2026-06-01 15:14:20 -07:00
|
|
|
axum = "0.8"
|
hephd: OIDC hub authentication — verification side (auth 10a)
Authenticate op exchange at the network boundary (tech-spec §13). The hub
now requires a valid OIDC bearer token on /sync/* and /rpc; local mode is
unchanged (no auth).
- heph-core: Store::authorize_owner_sub — single-tenant gate that claims the
owner's oidc_sub on first sight, then authorizes only that sub (403 for any
other identity). LocalStore impl over users.oidc_sub; RemoteStore stub.
- hephd auth module: TokenVerifier trait (mockable seam) + OidcVerifier
(jsonwebtoken, rust_crypto). Strict validation: RS256 pinned, exact iss +
aud, exp/nbf, required sub; JWKS discovered + cached, refetched on unknown
kid (rotation). Claims/AuthError.
- Hub router takes Option<verifier>; an axum middleware on every route
extracts the Bearer token, verifies it off the async worker, and runs the
owner gate — 401 missing/invalid, 403 wrong identity, 503 IdP-unreachable.
Open (no auth) when unconfigured, for local dev.
- main: --oidc-issuer/--oidc-audience enable the hub verifier (server mode).
- Security tests, all offline: stub-verifier middleware (missing/bad/valid +
owner gate) and an adversarial battery driving OidcVerifier against an
in-process mock IdP — rejects expired, wrong iss/aud, unknown kid, tampered
signature, alg confusion (HS256/none), and missing sub. The RSA key + JWKS
are generated at runtime (rsa/rand/base64 dev-deps) so no key is committed.
- tech-spec: add an end-of-v1 dependency-refresh pass to the roadmap.
108 tests green; clippy -D warnings + fmt + prek clean. Next: client-side
device-code login + keyring (10b).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 15:58:20 -07:00
|
|
|
jsonwebtoken = { version = "10", features = ["rust_crypto"] }
|
2026-06-01 16:27:36 -07:00
|
|
|
keyring = { version = "3", features = [
|
|
|
|
|
"apple-native",
|
|
|
|
|
"sync-secret-service",
|
|
|
|
|
"crypto-rust",
|
|
|
|
|
"vendored",
|
|
|
|
|
] }
|
|
|
|
|
ureq = { version = "3", features = ["json"] }
|
2026-06-01 15:14:20 -07:00
|
|
|
reqwest = { version = "0.13", default-features = false, features = [
|
|
|
|
|
"json",
|
|
|
|
|
"query",
|
|
|
|
|
] }
|
Scaffold cargo workspace + heph-core foundation
Kick off Phase 1 (v1 prototype) per tech-spec §11.1. Sets up the Cargo
workspace and the first TDD slice of heph-core:
- Migration runner + §4.5 SQLite schema (nodes, tasks, links, aliases,
users, oplog, sync_state, conflicts), versioned via PRAGMA user_version.
- Clock-injected `Clock` trait (no ambient wall-clock reads; §2).
- `Store` trait + `LocalStore` SQLite backend with node create/get,
bootstrapping the single local user (oidc_sub NULL, §13).
- Node model (kinds: doc/task/project/tag/journal).
Repo housekeeping: fill AGENTS.md Project Structure (last template TODO),
ignore /target, add self-bootstrapping .forgejo/scripts/build that runs
cargo fmt/clippy/test in CI (§9), changelog fragment.
Tests green: 4 unit tests (migration version, local-user idempotency,
create/get round-trip, missing-node None).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 18:52:15 -07:00
|
|
|
|
|
|
|
|
[profile.release]
|
|
|
|
|
lto = "thin"
|