Commit Graph

237 Commits

Author SHA1 Message Date
adlee-was-taken
68c6da4d67 chore(cli/org): silence dead_code on not-yet-consumed attachment API 2026-06-20 21:08:23 -04:00
adlee-was-taken
bccd113f55 feat(cli/org): collection-scoped attachment storage + default cap 2026-06-20 21:08:23 -04:00
adlee-was-taken
e76d7167d6 test(cli/org): grant enforcement + body/secret-stdin + key-edit coverage
Closes the minor coverage gaps from the final adversarial review:
- org add card/key/totp reject ungranted + unknown collections (pins the
  grant gate on the new write paths, which runs before any secret prompt)
- secure-note --body-stdin masks body; totp --secret-stdin round-trips
  (completes the --*-stdin matrix for the org surface)
- key-material edit accept-branch round-trip, verified via get --show
2026-06-20 20:58:26 -04:00
adlee-was-taken
04ad98973a test(cli/org): adapt grant-denial edit case to interactive org edit
B3 dropped the flat --username/--url/... flags from `org edit`, so the
ungranted-member denial test must drive the bare interactive form. The
ungranted member is now rejected at manifest lookup (filter_for_member +
resolve_org_query) before any prompt is read.
2026-06-20 20:49:12 -04:00
adlee-was-taken
290bc4e2d0 feat(cli/org): interactive per-type org edit via shared edit helpers 2026-06-20 20:43:03 -04:00
adlee-was-taken
82feb49ab4 feat(cli/org): org add parity for Card/Key/Totp via shared builders 2026-06-20 18:31:29 -04:00
adlee-was-taken
07862b8d44 test(cli/org): failing Card/Key/Totp org add round-trips (B4, pre-A-integration)
Adds run_stdin + create_collection_and_grant fixture helpers and three
acceptance tests for org add card/key/totp. Red until B1/B2 wire the
subcommands (currently: unrecognized subcommand). Asserts org get masks
card number + key material without --show. Edit round-trips land with B3.
2026-06-20 18:26:11 -04:00
adlee-was-taken
b09e0ce036 merge: feature/v0.8.1-dev-a-foundation (v0.8.1 Dev-A) — shared item_build module + personal add/edit refactor + --*-stdin flags 2026-06-20 18:24:04 -04:00
adlee-was-taken
d8b23d421e refactor(cli): tidy item_build edit helpers (simplify pass)
- edit_secure_note / edit_key now call the module's resolve_secret_multiline
  instead of open-coding the eprintln-hint + read-to-EOF pattern (the helper
  exists precisely to centralize this; build_secure_note/build_key already use it).
- drop redundant fn-local imports: `use zeroize::Zeroizing;` from the five edit_*
  helpers and the re-imported `TotpAlgorithm` from edit_login/build_login
  (all covered by module-level imports; leftover from the verbatim A2/A3 move).
- build_login passes the password_stdin flag through to resolve_secret_line for
  consistency with build_card/build_totp (behavior identical — that branch is
  only reached when password_stdin is true).
- restore #[allow(clippy::too_many_arguments)] on build_totp (8 args; the old
  build_totp_item carried the same allow — signature is frozen for B/C).
2026-06-20 18:14:10 -04:00
adlee-was-taken
6eb1275710 feat(cli): --*-stdin secret flags for personal add (non-interactive secrets) 2026-06-20 17:56:45 -04:00
adlee-was-taken
751e4e9bb1 chore(cli): remove now-dead prompt/prompt_optional helpers
A3 routed personal `add` through the shared item_build builders, which use
prompt_secret / resolve_secret_*; the generic single-line prompt() and
prompt_optional() lost their last callers. read_required_line /
read_optional_line stay (used by prompt_or_flag*).
2026-06-20 17:40:52 -04:00
adlee-was-taken
65e23cfddc refactor(cli): personal add delegates to shared item_build builders 2026-06-20 17:35:18 -04:00
adlee-was-taken
d32af594e4 feat(server): grant-scope org attachment write paths in pre-receive hook 2026-06-20 17:30:49 -04:00
adlee-was-taken
b83643ee0a refactor(cli): move per-type edit helpers into shared item_build module 2026-06-20 17:27:05 -04:00
adlee-was-taken
154b984725 feat(cli): shared item_build module — secret resolution + type parsers 2026-06-20 17:21:43 -04:00
adlee-was-taken
50b5c01291 release: v0.8.0 — enterprise org vault
Bump core/cli/wasm 0.7.0 -> 0.8.0; finalize CHANGELOG v0.8.0 header. Git-native multi-user org vaults (core org module + ECIES X25519 wrap, server signature-verifying pre-receive hook, CLI admin + item CRUD); 332/0 workspace tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RXpTHcQzw1n8qjYwZqruzQ
2026-06-20 16:06:16 -04:00
adlee-was-taken
3871da383d merge(docs): A5 living-docs sweep — item-CRUD across FORMATS/CRYPTO/SECURITY/DESIGN/ARCHITECTURE, STATUS shipped, ROADMAP, CHANGELOG; dead_code de-dup 2026-06-20 15:57:38 -04:00
adlee-was-taken
44d61ae7a7 test(cli/org): add grant-denial + secure-note masking regression tests
Cover two authz gaps left by the B9-B14 org item-CRUD work:

1. Grant-DENIAL on the read/mutate-by-query commands. A second member
   added with their own device key but NOT granted `prod` is rejected by
   every one of `org get`, `edit`, `rm`, `restore`, and `purge`, and
   `org get` (with and without --show) leaks no plaintext. Previously
   only `org add` had a denial test. Also asserts the item is untouched
   afterward (owner still reads the original password/username).

2. SecureNote body masking: `org get <note>` prints `********` and not
   the body; `org get <note> --show` reveals it. Mirrors the existing
   Login-password masking assertions in org_items.rs.

New tests/org_authz.rs reuses the multi-member `Dev` harness pattern
from org_lifecycle.rs (one XDG config home + ed25519 device key per
member), so a second member joins with their own keypair.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RXpTHcQzw1n8qjYwZqruzQ
2026-06-20 15:55:25 -04:00
adlee-was-taken
0cd417ded7 docs(org): complete A5 living-docs sweep (item CRUD merged) + dead_code cleanup
Extends the A5 pre-stage now that dev-b's full B-stream (item CRUD + all 19
org subcommands) merged to main (7392795). Living docs:
- FORMATS/CRYPTO/SECURITY/DESIGN: flip the item-CRUD "pending Dev-B" markers to
  shipped; SECURITY audit vocabulary moves item-* actions to live.
- crates/relicario-cli/ARCHITECTURE.md: full 19-subcommand surface (12 admin +
  7 item CRUD), accurate OrgAddKind scope (Login/SecureNote/Identity).
- STATUS.md: enterprise-org-vault landed section (merged 7392795) + tracked
  follow-ups + honest known-limitations; correct spec citation.
- ROADMAP.md: backend-complete row + phase-2 follow-ups.
- CHANGELOG.md: finalize the enterprise-org-vault Unreleased section (item CRUD
  into Added; Card/Key/Document/Totp + extension + phase-2 into Deferred).

Code (PM-directed dead_code fixes): wire device::current_device_seed by removing
the identical duplicate private fn in org_session.rs (de-dup); #[allow(dead_code)]
+ justification on org_session org_meta_path/load_meta (API completeness, no
command consumes org.json yet). Also silence a 3rd pre-existing test-only warning
(unused relicario() helper in tests/org_init_signing.rs).

Honest deferrals kept explicit throughout: Card/Key/Document/Totp org add/edit
parity, extension org switch/read (Dev-D) + writes, phase-2 (SSO/LDAP, read
audit, per-collection subkeys, HTTP plane). Full workspace cargo test green,
zero warnings. All cited code constants pinned file:line.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TJo44YM3UbBjro2fG6NrKy
2026-06-20 15:54:51 -04:00
adlee-was-taken
8bb1d779c4 docs(org): pre-stage A5 living-docs for merged core+server+CLI-admin (item-CRUD/extension TODO)
Pre-stages the A5 living-docs sweep for the already-merged A (relicario-core org
module) + C (relicario-server pre-receive hook) + CLI admin/rotate/status-audit
work, so the final A5 sweep (after Dev-B B9-B14 merges) is fast.

Adds org sections to docs/FORMATS.md (org repo wire formats + wrapped-key blob
layout), docs/CRYPTO.md (ECIES X25519 wrap/unwrap, no-Argon2id contrast, rotate
re-encryption), docs/SECURITY.md (signature-verifying hook, owner-only elevation,
audit vocabulary, honest limitations), DESIGN.md (org-master-key secrets row +
server org mode + deps), core/cli ARCHITECTURE.md (org module + org_session), and
an Unreleased CHANGELOG entry.

B item-CRUD (org add/get/list/edit/rm/restore/purge + main.rs wiring) and extension
parity are left as explicit TODO. STATUS/ROADMAP mark-shipped and
extension/ARCHITECTURE are deferred to the full A5 (track not yet landed; Dev-D
deferred). All cited code constants pinned with file:line per living-docs discipline.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TJo44YM3UbBjro2fG6NrKy
2026-06-20 15:23:27 -04:00
adlee-was-taken
6123d8b033 feat(cli/org): org rm/restore/purge trash lifecycle (collection-scoped) 2026-06-20 14:39:18 -04:00
adlee-was-taken
057a7defe5 feat(cli/org): org edit — flag-driven field update for login/note/identity 2026-06-20 14:12:46 -04:00
adlee-was-taken
2acd57a4a5 feat(cli/org): org get + list with per-member grant filtering 2026-06-20 14:08:22 -04:00
adlee-was-taken
87b1d166c2 feat(cli/org): org add — collection-scoped typed item create with grant guard 2026-06-20 14:00:21 -04:00
adlee-was-taken
6a16523ee0 feat(cli/org): wire Commands::Org admin subcommands + parse_org_role + transfer-ownership/delete-org 2026-06-20 13:50:11 -04:00
adlee-was-taken
cdb008c900 merge(cli): dev-b B7 (rotate-key) + B8 (status/audit) — reviewed; rotate re-encrypts all blobs, owner-only, concurrent-rotation abort 2026-06-20 13:40:36 -04:00
adlee-was-taken
053062effd feat(cli/org): status + audit (verified-signer attribution, TAMPERED flag, committer-date framing) 2026-06-20 13:24:35 -04:00
adlee-was-taken
3b6dbbe353 fix(cli/org): rotate-key writes member key blobs atomically (crash-safe) 2026-06-20 13:17:16 -04:00
adlee-was-taken
558da3bd75 feat(cli/org): rotate-key — re-encrypt every item blob + abort on concurrent rotation 2026-06-20 12:58:00 -04:00
adlee-was-taken
9c43f223f5 merge(cli): dev-b org stream B1-B6 — session, init, member/collection admin commands (dormant until B14 wiring) 2026-06-20 12:51:37 -04:00
adlee-was-taken
1c177871a7 feat(cli/org): create-collection, grant, revoke commands 2026-06-20 12:44:32 -04:00
adlee-was-taken
1ad8eb0918 feat(cli/org): add-member (owner-only escalation guard), remove-member, set-role 2026-06-20 12:38:48 -04:00
adlee-was-taken
aace6f132a harden(server): explicit verify-commit success gate + non-member/genesis hook tests
- verify_org_signer now rejects on a non-zero git verify-commit exit instead of
  relying on the stderr fingerprint regex alone (PM hardening note 1).
- org_hook_signed: add commit_signed_by_non_member_is_rejected (exercises the
  signature rejection path) and genesis_bootstrap_with_sole_owner_is_accepted.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 12:36:04 -04:00
adlee-was-taken
dbdb3f6ab0 refactor(cli/org): align org init main.rs wiring to OrgCommands + global --dir (B14-shaped) + assert org-init trailer 2026-06-20 12:33:07 -04:00
adlee-was-taken
7faedf8578 feat(cli/org): org init — structure + wrap + configure_git_signing + signed bootstrap commit 2026-06-20 10:27:08 -04:00
adlee-was-taken
ccb58d8bb5 feat(server): verify-org-commit — signature + path-scoped role/grant auth + owner-only elevation (parent-role authority) + schema monotonicity + generate-org-hook
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 10:21:15 -04:00
adlee-was-taken
570b0ddcd3 feat(cli/org): UnlockedOrgVault session (collection-scoped item_path, fingerprint match, signed org_git_run) 2026-06-20 09:48:15 -04:00
adlee-was-taken
7daedb33e0 feat(cli/org): org commands module stub + pub mod wiring 2026-06-20 09:43:43 -04:00
adlee-was-taken
17df315f0e feat(cli/device): current_device_seed + current_device_pubkey helpers
Read the active device's ed25519 seed/pubkey from
devices/<name>/signing.{key,pub}. Adds ssh-key (0.6) as a CLI dep
(already at 0.6.7 in the workspace lock via relicario-core) and
ed25519-dalek as a dev-dep for the round-trip test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 09:43:43 -04:00
adlee-was-taken
2dd5d79f36 refactor(server): fold in PM review notes on classify_path
- classify_path now Rejects a collection slug containing '.' (mirrors
  OrgCollections::validate, plan L317, and item_path's documented contract,
  plan L990). Unreachable today since git normalizes './' away, but keeps the
  pre-receive hook self-defensive against path traversal.
- Rename test item_write_nested_slug_takes_leading_segment_only ->
  item_write_nested_slug_is_rejected (it asserts Rejected; old name misled).
- Add dotted_slug_is_rejected covering the new guard.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M5brcDrT35r5GaJySXD5ja
2026-06-20 00:04:39 -04:00
adlee-was-taken
675b7836e1 feat(server): lib target + pure org-hook helpers (classify_path, extract_schema_version) + unit tests 2026-06-20 00:04:39 -04:00
adlee-was-taken
743a46f3d5 test(core/org): full org lifecycle integration tests
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TJo44YM3UbBjro2fG6NrKy
2026-06-19 23:44:15 -04:00
adlee-was-taken
409ddce049 feat(core/org): encrypt/decrypt_org_manifest vault wrappers
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TJo44YM3UbBjro2fG6NrKy
2026-06-19 23:24:55 -04:00
adlee-was-taken
631608e6e5 refactor(core/org): drop unreachable unwrap in unwrap_org_key; assert hex in OrgId test
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TJo44YM3UbBjro2fG6NrKy
2026-06-19 23:14:27 -04:00
adlee-was-taken
ca4936cf95 feat(core/org): org types, manifest, and X25519 key wrap/unwrap (Zeroizing KDF)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TJo44YM3UbBjro2fG6NrKy
2026-06-19 23:07:13 -04:00
adlee-was-taken
da4dc44f80 feat(core/org): add x25519-dalek dep + stub org module
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TJo44YM3UbBjro2fG6NrKy
2026-06-19 22:51:27 -04:00
adlee-was-taken
7c7efa7c43 release: v0.7.0 — extension restructure complete (Plan C Phases 3/4/6)
Completes the extension restructure begun in v0.6.0. Phases 3 (setup
wizard SW migration + step registry), 4 (vault.ts split + vault_locked
lift), and 6 (get_vault_status + sidebar status indicator) all merged to
main (9df2fee, 3b8368d, 397cc78) via three parallel worktree streams.

This commit is the release-prep wrap-up:
- Version bump to v0.7.0 across the three relicario crates + Cargo.lock,
  extension/package.json, and both extension manifests (the manifests had
  lagged at 0.5.0 — corrected here).
- CHANGELOG.md v0.7.0 entry.
- STATUS.md: extension restructure moved to shipped; Phases 3/4/6 landing
  section added.
- ROADMAP.md: v0.7.0 row added; Up-next now command palette.
- extension/ARCHITECTURE.md: all three phases integrated (new vault-*
  modules, setup-steps.ts, get_vault_status protocol + status indicator,
  vault_locked lift, git-host sync cache).
- Plan completion checkboxes ticked.

Task 7.1 verification: done-criteria sweep all green; 423/423 vitest;
build:all clean (only the pre-existing 4MB WASM size warning).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 22:50:17 -04:00
adlee-was-taken
d717f0d4a1 refactor(cli): tighten refresh_groups_cache to pub(crate) (Plan B Phase 4 polish)
Plan B Phase 4 wanted "every mutating handler must call
refresh_groups_cache" to be a compile-time invariant, with all
callers funneled through Vault::after_manifest_change. The
mutating-handler sweep happened, but two read-side callsites
(commands/list.rs and commands/get.rs) still called the public
helper directly for opportunistic shell-completion cache freshness.

Closes the gap:
- helpers::refresh_groups_cache demoted from pub to pub(crate).
- list.rs and get.rs drop their explicit calls. Cache freshness
  between mutations is unaffected: every mutating handler still
  funnels through after_manifest_change. The minor staleness
  window (manifest changed externally via git pull, no local
  mutation since) is the trade-off the spec accepts in exchange
  for the compile-time invariant.

The Plan B done-criterion "grep refresh_groups_cache outside
session.rs returns zero" now passes apart from the function
definition itself, which lives in helpers.rs (the natural place
for a flat utility). The visibility scoping achieves the
architectural intent.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 21:26:34 -04:00
adlee-was-taken
d2d11a4c9f chore: release v0.6.0
Rolls up four weeks of post-v0.5.0 work into one tag:

- Phase 2B polish foundation + form layout (2026-05-02, 5da1e52)
- v0.5.1 Stream A — 3-column vault layout + toast + bottom sheet (2026-05-03, c16adc4)
- v0.5.1 Stream B — left-nav settings (2026-05-03, bd6a301)
- v0.5.1 Stream C — Recovery QR + setup wizard Style C (2026-05-03, 934dfe0)
- 1C-γ — Document item type + attachments + device registration + trash + history
- Plan B refactor (Cycles 1+2) — commands/ split, prompt_or_flag, core/WASM seam
- Vault-tab management surfaces revamp (2026-05-24..30) — settings split, devices fingerprint, trash countdown, history polish
- Doc-structure redesign (2026-05-30) — DESIGN/CRYPTO/docs/FORMATS rename + scope headers + Next: footers
- Lock-screen logo for parity with popup unlock
- 17 stale tests updated to match post-Stream-B / post-revamp components

Versions: relicario-{core,cli,wasm} → 0.6.0; extension/package.json → 0.6.0.
relicario-server stays at 0.1.0 (separate cadence).

Suite status at tag time: 371/371 extension + 281 Rust tests green.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 21:17:54 -04:00
adlee-was-taken
5e7023fcc1 docs: add scope headers + Next: footers to all tour docs
Each of the eight tour docs (README, DESIGN, docs/CRYPTO,
docs/FORMATS, docs/SECURITY, crates/relicario-core/ARCHITECTURE,
crates/relicario-cli/ARCHITECTURE, extension/ARCHITECTURE) now
declares its scope in a blockquote under its H1 and ends with a
single-line "Next:" pointer to the next doc in the canonical
reading order: README → DESIGN → CRYPTO → FORMATS → SECURITY →
core → cli → extension.

Also trimmed README's mid-section "Architecture" stub to a one-
paragraph pointer at DESIGN.md (was duplicating cross-codebase
content and referencing a non-existent docs/architecture/ tree).

Renamed docs/CRYPTO.md's H1 from "Relicario — Architecture" to
"Relicario — Crypto Pipeline" to match the file's renamed scope.

Spec: docs/superpowers/specs/2026-05-30-doc-structure-redesign-design.md
2026-05-30 15:36:46 -04:00