4-stream manual-pane kickoff (no tmux automation): A foundation, B
Card/Key/Totp, C Document+attachments, D server hook. Each dev prompt
mandates a relay polling cadence (read inbox between every subagent;
HOLD/RESCOPE = interrupt) so PM directives are never missed. Gitea/git
merge mechanism; C<->D attachment-path coordination baked in.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L5JvzEse4xUxLZKhofyeCD
org_audit.rs (B8 verified-signer test) + the two uncommitted org.rs diffs
(item-CRUD B9-B13, status/audit B8) from the wf_22020aea first-run worktrees.
All superseded by v0.8.0 main; also committed on the -r2 branches. Kept so
nothing is lost when the stale worktrees are removed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L5JvzEse4xUxLZKhofyeCD
Dev-A shared item_build foundation + personal --*-stdin; Dev-B org
Card/Key/Totp; Dev-C org Document + attachment storage; Dev-D server
hook grant-scoping. TDD tasks with full code; A gates B/C, D independent.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L5JvzEse4xUxLZKhofyeCD
Card/Key/Totp = CLI-only parity via shared item-build module; Document
adds org attachment storage + a relicario-server hook change that
grant-scopes attachment paths (closing the Unrestricted gap). Secrets
via interactive prompts + --*-stdin escape hatches. Four suggested dev
streams (A foundation, B Card/Key/Totp, C Document+attachments, D hook).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L5JvzEse4xUxLZKhofyeCD
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
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
The plan's pre-receive-hook pseudocode judged owner-elevation authority on the
post-change `signer.role` (so a self-promoting Admin reads as Owner in the same
commit and self-authorizes the promotion — the exact escalation the gate exists
to stop). f249395 had fixed only the skip-predicate, leaving this final check
vulnerable. Align the plan's `enforce_owner_only_elevation` to the SHIPPED fix
(relicario-server/src/main.rs, aace6f1): derive `signer_may_manage_owners` from
`signer_parent = parent_role(signer.member_id)` (the signer's PRE-commit role;
None -> reject; genesis allowed) and gate on that, never the post-change role.
The spec was already policy-correct in prose ("a member-role-change granting
owner/admin must be signed by an owner") and did NOT carry the vulnerable
implementation detail; strengthened it with an explicit pre-commit-role note so
the design record pins the property and no one re-derives the vulnerable form.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TJo44YM3UbBjro2fG6NrKy
- 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>
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>
- 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
Spot-check of the new H-C1 hook code found the owner-only-elevation gate was
bypassable: it skipped any member ALREADY privileged in the parent, but since
Admin is also "privileged", an Admin→Owner promotion was skipped and accepted —
the exact escalation the gate exists to stop, and a failure of its own paired
test. Gate now skips only UNCHANGED roles (parent role == new role), so every
change into a privileged role (Member→Admin/Owner, Admin→Owner, new privileged
member) requires an owner signer.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Path-scoped collection storage (items/<slug>/<id>.enc) for hook-enforceable
writes; signature-verifying pre-receive hook on every commit; audit actor from
verified signer (trailers advisory + TAMPERED flag); org item CRUD in scope;
rotate-key re-encrypts all items; transfer/delete-org; extension parity in
phase 1; living-docs impact section.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- queue.ts: append every posted message to relay-log.jsonl (full body,
survives the consume-once drain + restarts). gitignored.
- server.ts: bump the stdout preview from 60 to 120 chars.
- tools/relay/pm: absolute-path bash wrapper (read|pending|send) so relay
ops work from any cwd without cd or hand-built JSON escaping.
- Fold in Dev-C's Phase 6 ARCHITECTURE.md slice as a coordination artifact.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>
Adds the get_vault_status SW handler (returns cached ahead/behind/lastSyncAt
from state.gitHost + a live pendingItems count from the manifest; no network)
and the sidebar-footer status indicator (renderStatusIndicator wired into the
#vault-status-slot, refreshed on mount + a manual button, no timer polling).
Closes the last relicario-status CLI/extension parity gap.
Also nulls state.gitHost on the explicit lock handler (symmetric with the
session-expiry path) so the indicator can't show a stale lastSyncAt after a
lock then re-unlock within one service-worker lifetime.
Tasks 6.1-6.3. 423 vitest green, build:all clean. Completes the extension
restructure (Plan C); all of Phases 3/4/6 now on main.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>