Skip to content

Recording the Why: canonical intents & memories, attestations, and W3C PROV - #107

Merged
geekgonecrazy merged 21 commits into
devfrom
feat/recording-the-why
Jul 15, 2026
Merged

Recording the Why: canonical intents & memories, attestations, and W3C PROV#107
geekgonecrazy merged 21 commits into
devfrom
feat/recording-the-why

Conversation

@graywolf336

@graywolf336 graywolf336 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

What

The Recording-the-Why foundation (rebased onto dev 0.9.1): markdown-authored intents and memories lifted into canonical, signed, gated JSON-LD nodes, plus a W3C PROV projection over the provenance atomic already captures.

atomic-canonical (new crate)

  • Lift: markdown frontmatter + container directives → typed canonical JSON-LD nodes (Intent with acceptance criteria / tasks / scope / constraints / refs as typed sub-nodes; Memory with kind, about, revision chain). Closed vocabulary; presence enforced, content never graded; single authoring site.
  • Directives: block, leaf, and the inline :name[label]{attrs} form; registered directives embedded mid-prose are rejected (an edge silently lost otherwise); unregistered colon-patterns stay prose.
  • Canonicalization + proofs: JCS (RFC 8785, UTF-16 key ordering) + BLAKE3 content hash; eddsa-jcs-2022 Data Integrity proofs with base58btc proofValue; did:atomic (fingerprint) with did:key accepted for interop. Hash and signature share one canonicalization path.
  • Gate: the in-process shape validator (closed status/kind sets, authorship, proof, why/text presence, met-acceptance-criterion-requires-verifiedBy+evidence, memory directionality). The formal SHACL engine deliberately does not live here — per the team decision it runs as a Circuit-Breaker workflow (see docs/shacl-oxirs-spike-findings.md for the oxirs evaluation that informed this; shapes ship with the CB validator).
  • PROV projection (prov.rs): a change's provenance graph projected as a W3C PROV-O named subgraph — change-primary (urn:atomic:provgraph:<changeid>), turn + turnParent hash-linking, used/generated edges, SoftwareAgent as a urn: label with rdfs:label (a keyless agent is not a DID), Person as the real did:atomic. Unsigned by default ("signable, not signed"); attest_prov/verify_prov produce the standalone signed artifact on demand.
  • Real @context (ns/ctx.jsonld + context.rs): every emitted term resolves to a prov:/atom:/sec:/rdfs:/xsd: IRI, with a coverage test — the JSON is genuine, offline-processable RDF.

atomic-cli

  • atomic intent / atomic memory: new (directive-scaffolded templates), show (render or --json), validate (gate + evidence-URN resolution against the change store), attest (sign into a tracked vault attestation entry; storage hashing untouched), verify, attestation-aware list.
  • atomic provenance trace|show: compute-on-demand projection of a change's flywheel chain; show --sign emits the signed artifact. REV_DEPS lookup with a disk-scan fallback.
  • Deprecates atomic vault intent in favor of the canonical atomic intent family: [DEPRECATED] help-text prefixes on the parent + every subcommand, plus a one-line runtime warning: steering users to the replacement (vault intent createintent new, listintent list, showintent show). Additive only — behavior unchanged, nothing removed. This matters because vault intent create makes bare, title-only intents (no acceptance-criterion/why scaffold), whereas intent new scaffolds the full template.

Storage (additive only)

  • VaultEntryType::Attestation (append-only enum addition); attestations are ordinary tracked vault entries — no content-hash redefinition, no merkle/manifest changes, capture path untouched.

Verified

  • Full round-trip suites (lift → gate → attest → verify → render) for intents and memories; gate rules covered individually incl. the deliberate no-forward-edge memory rule.
  • CLI integration tests: attest/verify/list flows and an end-to-end provenance show/trace against a real recorded graph (unsigned default asserted; --sign verifies against the resolved key).
  • Exercised end to end by the noname pipeline (atomicdotdev/noname#13): agent turn → hook-captured provenance → canonical emission → SHACL gates → insert.
  • Workspace tests and clippy clean; cargo fmt --check clean.

Relationship to #102

Converged with feat/canonical-standards where the designs agreed: its spec-conformance fixes (base58btc, UTF-16 JCS, did:key), inline directives, embedded-directive rejection, and evidence-URN resolution are incorporated here (the two directive commits cherry-picked, the rest adapted); its atomic-shapes.ttl seeds the CB validator's shapes. The in-binary pyshacl tier and the session-keyed PROV export were superseded by the CB-workflow decision and the change-primary projection, respectively.

Known follow-ups

  • Populating the PROV used edge requires the capture path to record structured inputs (intents/memories a turn pulled) — field and projection are ready, capture change is separate.
  • Recording acceptance-criterion evidence (evidence=urn:atomic:change:<hash>) at agent-record time, so the met-AC rule can bind automatically.
  • Key-at-rest encryption before attestations are trusted outside dev.

@graywolf336
graywolf336 force-pushed the feat/recording-the-why branch from 06a2f65 to f2f0b23 Compare July 10, 2026 16:59
graywolf336 and others added 19 commits July 14, 2026 15:50
…e (M0)

Introduces the canonical-record layer that proves the "record the why" round
trip in isolation, without yet touching the vault store:

  author (frontmatter + container directives)
    -> lift -> canonical JSON-LD node
    -> JCS (RFC 8785) + BLAKE3 content hash
    -> Ed25519 Data Integrity proof (did:atomic, eddsa-jcs-2022)
    -> SHACL-style gate -> render projection

Modules: vocab (closed registry, single source of truth), jcs (single
canonicalization entry point for hash + sign), hash, did, proof, directive
(container/leaf parser — type from name, not heading position), lift, gate
(IntentShape: presence enforced, content honest, closed-world), render (pure
projection; status regenerated from the spine — single authoring site).

21 tests (13 unit + 8 integration) green; clippy clean. Signing uses a
non-production dev identity (plaintext keys — see crate docs). Vault wiring,
CLI verbs, Memory, W3C PROV, and a real SHACL engine are later milestones.

Spec: docs/recording-the-why.md. Plan + adversarial critique:
docs/recording-the-why-plan.md.
…he Memory node (P1+P2)

Builds on the M0 engine. Two phases, plus fixes from an adversarial review pass.

P1 — generalized attestation + full collections:
- Attestation now flows through ONE Value-based path (proof::attest_value /
  verify_value); Intent and Memory sign/verify through the same code and the
  single jcs entry point, so hash and signature can never fork.
- Lift/gate/render the remaining collection sub-nodes: scope-in, scope-out,
  constraint, and :::ref dependency edges. The gate requires an explicit
  scope-out when scope is declared (presence, not content).
- Registry closure test: every lift-handled directive is a known vocab member.

P2 — Memory node type:
- MemoryNode with closed memoryKind {constraint,preference,lesson,context} and
  status {active,superseded,retracted}, about[] input edges, and an append-only
  revision chain (supersedes / previousRevision). lift_memory + MemoryShape gate.
- Directionality: a memory names its inputs, never its consumers.

Adversarial-review fixes (2 blockers, 1 major, 3 minor), each with a regression test:
- BLOCKER: add #[serde(deny_unknown_fields)] to every deserialized node/sub-node
  so an injected key on a signed record is rejected on load instead of being
  silently stripped before verification.
- BLOCKER: drop the "superseded => supersedes present" gate rule — it inverted
  directionality (forced a retired node to point forward at its successor).
- MAJOR: lift_memory no longer runs the closed-vocabulary parser over the open
  memory body (a lenient :::memory fence scan), so prose containing :: / :::
  (a Rust turbofish, or discussing :::why) is valid content, not a parse error.
- MINOR: :::ref edge= is restricted to a dependency subset {depends, blockedBy}.
- MINOR: verify_value enforces the proof's declared cryptosuite/purpose/type.
- MINOR: parse_markdown normalizes CRLF.

51 tests pass (33 unit + 18 integration); clippy clean. Still crate-level only —
vault wiring and CLI verbs remain a later milestone.
…ical (M1a)

Wires the Recording-the-Why engine to the CLI, ADDITIVELY: the attested
canonical node + proof are written as a sidecar under `.atomic/canonical/`,
and nothing in atomic-core / VaultEntry / content_hash / the manifest merkle /
vault_scan is touched. Verified with `git diff` + the additivity audit.

Verbs (top-level, coexisting with `atomic vault intent`):
- intent validate <ID|path>  lift + SHACL-style gate; nonzero if non-conforming
- intent show <ID>           render the canonical projection (status from spine)
- intent new <TITLE>         scaffold a directive-based intent (why/AC/task/scope/constraint)
- intent attest <ID>         gate, sign (did:atomic Ed25519), write the sidecar
- intent verify <ID>         read the sidecar, check freshness + verify hash/signature

Adversarial-review fixes folded in (each verified end-to-end):
- MAJOR: the sidecar was write-only. validate/show/verify now read it back
  (fresh -> gate/render the attested node; stale -> warn + fall back), so
  attest -> validate actually reports `conforms: yes`. Added the `verify` verb
  and a freshness check keyed on a recorded source hash.
- MINOR: `validate --json` no longer prints the diagnostic Hint to stdout (the
  error-path hint is routed to stderr, aligning with the error itself); a
  path-shaped argument that does not exist reports FileNotFound rather than
  "invalid ID"; the feature scaffold now includes the `:::task` stub the doc
  names; the `new` positional is documented as the title (id is vault-allocated).

Signing uses a non-production dev identity (plaintext keys). Storing the
canonical hash AS the record hash (redefining content_hash + re-plumbing the
merkle/scan) remains the deliberately-deferred invasive M1b.

Verified: end-to-end new -> validate(no) -> attest -> validate(yes) -> verify(ok)
with an isolated HOME; sidecar under .atomic/; atomic-cli builds, clippy clean,
1543 atomic-cli tests pass, atomic-canonical's 51 tests stay green.
…g hashing, additive)

Attestations become a first-class TRACKED vault entry instead of a local
`.atomic/` sidecar, so signed "why" is durable and travels via the ordinary
change graph — with ZERO change to the vault's hashing. This is the additive
path chosen after reverting the M1b content_hash redefinition.

- New append-only `VaultEntryType::Attestation` (index 6; postcard encodes
  discriminants positionally, so appending is back-compatible with existing
  rows — never reorder/delete). `infer_entry_type` maps `attestations/` → it;
  `vault_triples.rs` gets explicit (non-`_`) arms emitting no KG nodes/edges;
  the embedding path already skips it — signed blobs never pollute search.
- `atomic intent attest` writes the signed JSON-LD node to
  `attestations/<intent-id>/attested.md` via the existing `vault_store`
  (storage hash stays blake3(body); the node's own contentHash + eddsa-jcs-2022
  proof live inside the opaque body — two hashes, two jobs). A trailing newline
  is appended so materialize is a byte-identity transform and the first scan
  sees Unchanged (no false-Modified, no double-merkle-advance). It does NOT
  route through intent_dir_for (avoids the collapse bug) and does NOT auto-record.
- `validate`/`show`/`verify` read the tracked entry; staleness reuses the
  existing `source_content_hash`. During transition, attest dual-writes the
  legacy sidecar and readers fall back to it — probing BOTH the normalized-id
  and the raw-arg legacy path so pre-upgrade M1a sidecars still resolve.
- content_hash semantics, hash.rs, the manifest merkle, and vault_scan's
  comparison are UNTOUCHED (verified).

Verified end-to-end (isolated HOME): attest → tracked `attestation` entry at
attestations/REPO-1/attested.md → validate conforms → verify passes. Tests:
atomic-canonical 51, atomic-cli 1538+9 (incl. tracked/legacy/raw-arg-fallback/
staleness bridge tests), atomic-core + atomic-repository green; clippy clean
(only pre-existing provenance_summary warnings). Plan + adversarial critique
drove the design (GO-WITH-CHANGES; the trailing-newline + dual-read fixes were
the required changes).
Mirrors `atomic intent` for memories: `atomic memory {new,show,validate,attest,
verify}`, driving the atomic-canonical engine (lift_memory / validate_memory /
verify_memory / render_memory) and REUSING the tracked-attestation entry
mechanism from d63713c. The raw `atomic vault memory {list,show,write}` is left
untouched as the legacy layer (preserves the agent stdin write flow); this is
the two-layer design decided for the CLI surface.

- New command family under atomic-cli/src/commands/memory/ (mod/new/show/
  validate/attest/verify/bridge), registered top-level in main.rs + commands/mod.rs.
- Memories have no PREFIX-N id and no dedicated repository create method, so
  `memory new` writes directly via the generic vault_store + vault_materialize
  (same path as raw `vault memory write`) at `memory/<id>.md`, with a fresh
  lowercased ULID id and a STABLE `createdAt` in the spine (load-bearing: it is
  signed, so re-lift must reproduce byte-identical signing bytes). --kind and
  --status are both validated early against their closed sets.
- attest signs a MemoryNode and writes the tracked attestation entry, namespaced
  at `attestations/memory/<id>/attested.md` (avoids intent/memory id collisions),
  dual-writing the legacy sidecar; validate/show/verify read it back (tracked
  preferred, sidecar fallback), staleness via the existing source_content_hash.
  No content_hash / merkle / hashing change; no intent_dir_for (collapse bug).

Verified end-to-end (isolated HOME): memory new -> validate(no) -> attest ->
validate(yes) -> verify(ok); tracked `attestation` + `memory` entries both in
`vault list`. Tests: atomic-cli 1550 + 9 (12 new memory tests), atomic-canonical
51 unchanged; clippy clean. atomic-canonical, atomic-core, and the raw
`atomic vault memory` are untouched.
…ory list`

Rounds out the canonical CLI families with a `list` verb that surfaces what the
raw `atomic vault list --type X` cannot: canonical + attestation state.

- intent list: humanKey · status · attested(fresh|stale|–) · verifies(✓|✗|–)
- memory list: id · kind · status · about(count) · attested · verifies · (--json)

Attestation-aware via the existing bridges (no new machinery): `attested` is
classified from load_attestation (Fresh/Stale/None); `verifies` runs the engine's
verify/verify_memory against the identity resolved ONCE up front, and — to avoid
false negatives — shows `–` (not `✗`) when there's no attestation, the attestation
is stale, or the signer DID isn't the resolvable identity; `✗` only on a real
hash/signature failure. No identity resolvable ⇒ all `verifies` are `–` (the list
still renders). A single bad row degrades to `–`, never aborts the list.

Enumeration reuses the same sources as the raw verbs: vault_intent_list for
intents; vault_list("memory/", None) for memories. Attestation entries
(attestations/…) and the `memory/MEMORY.md` index scaffold are excluded.

Review fixes folded in: stale rows show the CURRENT source's kind/status/about
(matching `memory show`, drift still flagged by attested=stale), and column
widths measure chars not bytes (aligned output with multibyte ids/status).

atomic-cli only — atomic-canonical, atomic-core, and the raw `atomic vault`
commands untouched. Verified end-to-end (attested vs un-attested rows + --json);
1564 atomic-cli tests (incl. 7 intent::list + 8 memory::list), atomic-canonical
51, clippy clean.
…dentity; doc/help accuracy

Follow-ups from the acceptance-test pass (48/48 then 51/51, 0 fails):

- W1: `intent attest` / `memory attest` now `vault_materialize` the tracked
  attestation entry after storing it, so it exists in the `.vault/` working tree
  (matching the printed path) and is captured by a subsequent `atomic record`
  (i.e. it travels via the change graph). Previously the entry was in redb but
  never materialized to disk.
- W3: a missing default identity in attest/verify was wrongly wrapped in
  CliError::Internal (exit 128 + "this is a bug, report it"). It is a normal
  user-recoverable state — reclassified to CliError::InvalidArgument (exit 2)
  with the same actionable "create one first" message. Applied to intent+memory
  attest and verify.
- Docs/help accuracy: `attest` help/comments said "No VaultEntry is touched" /
  "canonical sidecar", which predated the tracked-entry change and now said the
  opposite of the behavior — corrected to describe the tracked attestation entry
  (existing blake3(body) storage hash; the source's own content_hash is never
  redefined). Added a spec note that id-based verbs read the vault DB (run
  `atomic vault sync` after hand-edits) and that `vault sync` detects changes by
  body only, so frontmatter-only edits may not be picked up.

Not changed: W2 (alleged memory stale-body/hash "bug") was a test-harness
artifact (DB-vs-disk + body-only storage hash), verified — no code change.
The frontmatter-only-sync limitation is pre-existing atomic behavior
(content_hash = blake3(body)); documented, not modified here.

atomic-cli + docs only; engine/core/raw-vault untouched. 1564 atomic-cli tests
+ 51 atomic-canonical pass; clippy clean; both fixes verified end-to-end and by
a fresh 51/51 acceptance re-run.
Project a change's ProvenanceGraph into a signed W3C PROV-O JSON-LD
subgraph on demand — the third core record ("why did this change
happen"), read-only and off the capture path.

atomic-canonical (atomic-core independent):
- prov.rs: project(ProvActivityInput) -> PROV-O @graph
  (prov:Activity / SoftwareAgent / Person, generated /
  wasAssociatedWith / actedOnBehalfOf / turnParent), named subgraph
  urn:atomic:provgraph:<changeid>; attest_prov / verify_prov over the
  Data Integrity eddsa-jcs-2022 envelope.
- Agent @id is a non-verifiable label (urn:atomic:agent:<slug>); only
  the Person's did:atomic signs. used-edge deferred (emitted empty).

atomic-cli:
- `atomic provenance {trace,show}`: trace prints the human flywheel
  chain, show emits signed JSON-LD (--json). Compute-on-demand: writes
  nothing. mapping.rs is the sole atomic-core boundary; activity id is
  graph-stable (<session>#<first-explained-change>) so turnParent joins.
- atomic-repository: find_provenance_for_change with disk-scan fallback
  for changes never made internal (invisible to REV_DEPS).

Integration test drives the real binary end-to-end: save a real graph
-> show -> parse -> verify_prov against the resolved key -> trace ->
assert nothing written. Capture path (atomic-agent) and atomic-core
content hashing untouched.
Add atomic-shacl, a feature-gated spike that runs the real oxirs-shacl 0.3.1
engine over real Turtle shapes and diffs it against the hand-coded gate
(atomic-canonical/src/gate.rs) via an adversarial differential corpus.

Verdict (see atomic-shacl/SPIKE-FINDINGS.md; all 13 tests green):
- oxirs 0.3.1 silently does NOT enforce sh:node (nested AcceptanceCriterion)
  or sh:sparql (the two conditional rules INTENT-5 / INTENT-7) — 3 of 12 rules
  become signing-path false-negatives. strict_mode does not catch it (fail-open).
- result_path is always None, so violations can't be mapped to the failing
  property and distinct violations collapse.
- The feature pulls ~432 crates (scirs2/ndarray BLAS, full icu, reqwest/rustls);
  the crate's own README calls the API "under development."

What works and is retained: sh:minCount + sh:in match the gate on every Core-rule
fixture, including the trim asymmetry (why/text trimmed; attributedTo/verifiedBy/
evidence not) and the load-bearing memory directionality ABSENCE. The .ttl shapes
and the JSON-LD->RDF shim are correct standard SHACL — only the engine is unfit.

The blocker tests assert the defects as passing tests today; if a future oxirs
release fixes them the assertions flip and the tests fail, signalling re-evaluation.

Isolation: nothing is on the signing path (the gate stays sole authority);
atomic-canonical does not depend on this crate and the oxirs stack never reaches
it; the whole stack is behind the off-by-default `oxirs-engine` feature so routine
builds/CI never compile it. Removing this crate is a no-op for atomic's behavior.
…CS, did:key

Adopt the three canonicalization/crypto spec fixes from the team's
feat/canonical-standards branch (5e4c7b8), code only — not its bundled
docs, PROV, CLI, or pyshacl work, which remain separate reconciliations.

- proof.rs: proofValue is now multibase base58btc ('z') via bs58, as the
  eddsa-jcs-2022 cryptosuite specifies (was base32-upper 'B', an M0
  shortcut). proofValue is excluded from both the signing and hashing
  views, so this is a pure output-encoding change — the ed25519 signature
  bytes and content hash are unchanged; only the string encoding differs.
- jcs.rs: object keys now sort by UTF-16 code units per RFC 8785 §3.2.3
  (was UTF-8 byte order). A no-op for the all-ASCII closed vocabulary
  (identical canonical bytes, hash, and signature), correct for any future
  supplementary-plane key.
- did.rs: add did:key (multicodec ed25519-pub + base58btc) alongside the
  in-tree did:atomic. Additive — did:atomic stays the default and still
  verifies; did:key is now also accepted, for Data-Integrity/PROV interop.

The design doc already showed base58btc proofValues, so code now matches
the doc. All canonical + cli + provenance tests green; clippy clean.
…aseline

Bring the PROV slice in line with the baseline (which is change-primary, and
treats the provenance graph as "signable, not signed"):

- Unsigned by default, signable on demand. `project()` was already unsigned;
  the CLI `show` (and `trace --json`) now emit the UNSIGNED projection by
  default and gain a `--sign` flag for the signable standalone artifact
  (top-level attributedTo/contentHash/proof). Provenance is a derived view of
  already-signed primaries whose chain integrity comes from turnParent
  hash-linking, so it carries no proof envelope unless asked.
- `used` flywheel edge is now a first-class, populated field on
  ProvActivityInput, emitted only when non-empty (unknown links omitted, never
  invented). The current atomic_core capture records no structured inputs, so
  the mapping supplies an empty set for now; full population is gated on a
  separate capture-path change. (Was hardcoded `used: []`.)
- Ship the real @context: atomic-canonical/ns/ctx.jsonld + a `context` module
  (embedded, with defined_terms/undefined_terms helpers) + a coverage test
  asserting every key the signed PROV graph emits resolves to a prov:/atom:/
  sec:/rdfs:/xsd: IRI. Closes the bare-URL gap; makes the JSON real RDF.
- Agent @id stays urn:atomic:agent:<slug> (NOT the baseline example's
  did:atomic:agent:) on W3C DID-Core grounds: a DID must resolve to a DID
  Document with verification material; a keyless SoftwareAgent has none, so a
  did:atomic:agent: label is a non-resolvable fake (and not a valid did:atomic
  fingerprint). A urn: is the honest, PROV-O-valid identifier; a real did:key
  is the future path once agents hold keys. Doc reframed accordingly.
- Agent human label emitted as rdfs:label (via the `label` ctx term), not the
  non-existent prov:label.

Change-primary addressing (provgraph:<changeid>) and the turn+turnParent
activity model are unchanged — both already match the baseline. All canonical
+ cli + provenance tests green; clippy clean.
…er, not atomic

Owner decision (Lee): the SHACL formal validation is a Circuit Breaker (CB)
workflow, not built into atomic. So no SHACL engine ships in the atomic binary.

- Delete the atomic-shacl crate (the oxirs 0.3.1 spike) and drop it from the
  workspace members + [workspace.dependencies]. This prunes the entire ~432-crate
  oxirs/scirs/ndarray/icu/rustls transitive tree from Cargo.lock.
- Preserve the spike's conclusion as docs/shacl-oxirs-spike-findings.md (why
  oxirs / an in-atomic engine was rejected), with a status banner recording the
  CB decision.

atomic keeps the fast in-process hand-coded tier-1 gate, emits canonical JSON-LD
(intent/memory/provenance) with a real @context, and will ship the shape .ttl as
data for CB to validate against. The SHACL engine choice now lives in CB, free of
atomic's hermeticity constraints.

bs58 (base58btc proofValue) stays — it is used by the spec-conformance work, not
by the removed crate. canonical + cli tests unaffected (they never depended on
atomic-shacl); clippy clean.
Completes the third directive form from Recording the Why. Inline
directives are recognized inside container prose and surface as children
of the container while the prose keeps the mention verbatim (store the
edge, render resolves it). Recognition is word-boundary + label-bracket
+ registry gated, so DIDs, URNs, and unregistered colon-patterns in a
reason stay prose instead of erroring — prose remains the unconstrained
slot. Inline and nested-leaf :ref children lift onto the intent's
dependency chain with the same to/edge validation as :::ref.
…dence URNs

Ports the two authoring/lift correctness fixes from PR #102 (canonical part of
872a070, by Vincent), adapted to our top-level `intent validate`:

- Reject registered directives embedded mid-sentence. `::file-ref{...}` inside a
  task's prose was silently kept as prose and the edge was lost; the lift now
  errors ("must start their own line"). Unregistered names stay prose (the inline
  rule), and rust paths / template comments / fenced code are exempt.
  `check_embedded_directives` in directive.rs, called from lift_intent + lift_memory.
- Resolve acceptance-criterion evidence URNs. `evidence=urn:atomic:change:<hash>`
  was presence-checked only; `atomic intent validate` now, when run inside a repo,
  requires every such URN to resolve in the change store (skipped with a note
  outside a repo). Ported into our intent/validate.rs (their version lived in the
  canonical/ CLI we don't use).

Excludes 872a070's shacl.rs touch (SHACL moved to Circuit Breaker). Canonical 54
tests, cli 1567+2+9, clippy clean.
Run rustfmt over the RtW work area (atomic-canonical, atomic-cli, and the three
vault files in atomic-core/atomic-repository the attestation-entry work touched).
The RtW code was authored with custom hand-formatting; this brings it to rustfmt
so `cargo fmt --all --check` is clean before further work. Whitespace/layout only
— no behavior change (canonical 54+18, cli 1567+2+9 tests green; clippy clean).
The rest of the workspace was already fmt-clean and is untouched.
…gate

- provenance command: sort_by → sort_by_key(Reverse) (clippy -D warnings).
- atomic-canonical lib docs: [`render`] was ambiguous (module vs re-exported
  fn) — disambiguate with mod@ (rustdoc -D broken-intra-doc-links).
- provenance integration tests: excluded on Windows — they isolate the
  identity store via the HOME env var, which dirs::home_dir() ignores on
  Windows (FOLDERID_Profile), so the store cannot be redirected from a test.
  An explicit identity-store override would lift this.
- changes.rs: qualify the find_provenance_for_change intra-doc link with Self::
  (rustdoc -D broken-intra-doc-links).
- atomic-semantic java parser: drop redundant &name refs in format! args
  (clippy redundant reference; pre-existing on dev, but CI halts the workspace
  clippy run on it).
- atomic-repository provenance_summary tests: struct-init instead of mutating
  a Default::default() instance (clippy field_reassign_with_default; also
  pre-existing on dev, surfaced once the workspace run got past atomic-semantic).

Full-workspace cargo clippy --all-targets -D warnings, rustdoc -D warnings,
and fmt --check are now clean locally; affected crates' tests pass.
CI's dtolnay/rust-toolchain@stable is rustc 1.97, whose clippy carries lints
older toolchains don't — updated the local toolchain to match and cleaned the
whole workspace in one pass:

- changestore/iterators.rs: the if-let-else-return-None over current_files in
  both next_from_files impls becomes current_files.as_mut()? (question_mark;
  clippy's own suggestion would move out of self — as_mut is the correct form).
- git/parallel.rs: drop redundant &info.short_sha refs in format! args.

Both pre-existing on dev; each failing crate halted the workspace clippy run
and hid the next, so this pass was verified with the full workspace +
--all-targets on 1.97: clippy -D warnings, rustdoc -D warnings, and fmt --check
all clean; atomic-repository/atomic-cli tests pass.
@graywolf336
graywolf336 force-pushed the feat/recording-the-why branch from f2f0b23 to e6ceea6 Compare July 14, 2026 20:55
Add the update, delete, and link verbs to the canonical `atomic intent`
command family so it fully supersedes `atomic vault intent`. Each new verb
delegates to the same atomic-repository write path as its vault counterpart
(vault_intent_update / vault_intent_delete / vault_intent_link), so behavior
is identical; the flags mirror the vault versions exactly.

Now that direct replacements exist, sharpen the vault-intent deprecation
help text and runtime warnings for update/delete/link to name the specific
new commands instead of the vague "atomic intent family".
@geekgonecrazy
geekgonecrazy merged commit 1fa92ca into dev Jul 15, 2026
8 checks passed
@geekgonecrazy
geekgonecrazy deleted the feat/recording-the-why branch July 15, 2026 22:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants