eidetic-memory: refresh wrappers (eidetic 0.10) + memory-discipline convention#3
Merged
Merged
Conversation
- **Memory-discipline "Conventions and workflow" section in `CLAUDE.md`** — a per-task *recall-before / remember-after* convention (scope localized to this repo's nick) so the vendored `remember` / `recall` skills are actually used, not just present: `/recall` before non-trivial work to build on prior decisions instead of re-deriving them, and `/remember` when a non-obvious decision, constraint, fix-and-why, or hard-won gotcha surfaces. The section documents this repo's memory as **in-repo and public** — records resolve to `<repo-root>/.eidetic/memory` (committed, team- and mesh-shared). Inserted idempotently (skipped if already present), slotted under an existing "Conventions and workflow" heading when one exists, else appended. ### Changed - **Refreshed the `remember` + `recall` wrappers from eidetic-cli 0.10.0** (cite-don't-import) — picks up eidetic's **project-local store default**: the files backend now resolves per record by visibility — PUBLIC records inside a git repo go to `<repo-root>/.eidetic/memory` (committed, team-shared), PRIVATE records (or any record outside a repo) go to `$HOME/.eidetic/memory` (never committed), an explicit `EIDETIC_DATA_DIR` still wins, and recall reads both stores and merges. Also carries the 0.9.3 hardening (interactive-stdin guard, `help` as a search term, SIGPIPE-safe suffix parsing). **Recipe policy override (the wrappers here are NOT byte-verbatim):** the injected default visibility is flipped from eidetic's `private` to **`public`**, so a plain `/remember` lands the note in `./.eidetic/memory` in this repo, kept as part of the repo — pass `--visibility private` to route a record to `$HOME` instead. `remember` drives `eidetic remember` (idempotent upsert of one JSON record or an NDJSON batch on stdin); `recall` drives `eidetic recall` with four search modes (exact / approximate / keyword / hybrid). Each `SKILL.md` is localized only in the illustrative `--scope <nick>` examples (Provenance keeps "First-party to eidetic-cli"). Runtime dep: the `eidetic` CLI on PATH (else a local eidetic-cli checkout with `uv`) — **`eidetic >= 0.10.0`** for the in-repo routing; on an older CLI the public records still work but are stored in `$HOME/.eidetic/memory` instead of in-repo. Propagated by rollout-cli's `eidetic-memory` recipe.
Looking for bugs?Check back in a few minutes. Qodo's review agents are on it. |
|
OriNachum
added a commit
that referenced
this pull request
Jul 6, 2026
1. Recorded vectors gain a model tie-out (Qodo #1): recorded_vectors.json is now {metadata, vectors} — the refresh script stamps the embedding model/ endpoint it actually ran against, the committed fixture is wrapped post-hoc with its known 2026-07-04 provenance (vector values unchanged), and the loader exposes load_recorded_metadata() with legacy-format fallback. 2. --json placement no longer matters (Qodo #2): verb-level --json flags use default=argparse.SUPPRESS via a shared helper so they never clobber a noun-level --json; applied to all six noun groups including meaning. 3. signal collect rejects non-object measurements (Qodo #3): valid JSON that is not an object raises SeriesError(collect_measurement_not_an_object) naming the offending file — exit 1, never an AttributeError. 4. Duplication: the per-noun file-error guard, remediation strings, and reference-date parsing move to cli/_commands/_artifact_io.py; the five noun modules keep only their domain-specific branches. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SmwUt5WBBbrUc1vt2RdQYk
OriNachum
added a commit
that referenced
this pull request
Jul 6, 2026
…iture, frames (closes #8 #9 #10 #11) (#14) * t1: shared measurement envelope — coherence/schema.py + docs/envelope.md Adds the stdlib-only shared measurement envelope (domain, score_type, scores, frame, diagnostics) that every new domain noun (quality, signal, investiture, assess) will emit from day one. build_envelope/validate_envelope round-trip a valid envelope unchanged; every violation (missing key, non-dict scores, non-numeric score value, malformed diagnostic entry, etc.) raises the dedicated EnvelopeError with a machine-readable code. An absent frame is representable explicitly via frame=None (paired with a diagnostic) or the null_frame() helper dict — never a missing key. docs/envelope.md documents all five fields and the two-speed adoption rule: new nouns emit the full envelope; existing meaning verbs keep their pinned v0.5.0 shape and only gain additive top-level keys (domain, score_type, frame), with the scores-nesting migration deferred to an explicitly versioned future change. 20 new tests in tests/test_schema.py, all offline. Full suite: 146 -> 166 passed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SmwUt5WBBbrUc1vt2RdQYk * t2: frame provenance core Add coherence/frames/{__init__.py,provenance.py} — build_frame() assembles the frame provenance block (embedding_model, embedding_endpoint, anchor_set, axis/axes, projection_method, score_type) for embedding-derived measurements. embedding_model/embedding_endpoint are resolved at call time by reusing coherence.meaning.embed's own COHERENCE_EMBED_URL/COHERENCE_EMBED_MODEL resolution functions directly (not duplicated default literals), satisfying t2's acceptance criterion that a monkeypatched env changes the emitted block and defaults only appear when the env is unset. Absent provenance re-exports coherence.schema.null_frame verbatim (asserted via identity in tests) rather than reinventing the null-frame shape. 17 new offline tests in tests/test_frames_provenance.py; full suite 166 -> 183 passing. * t3: signal series schema + robust loader Add coherence/signal as the source-agnostic series analysis layer's input contract. coherence/signal/schema.py defines the series shape (optional domain + ordered points; per point id/index/timestamp/values + optional per-point frame) and load_series(), a robust loader that normalizes into typed Series/SeriesPoint records plus a mutable diagnostics list. - values are arbitrarily named numerics (caller-defined, never enumerated); missing/null/non-numeric values and booleans are skipped WITH a diagnostic, never a crash. bool is not numeric. - per-point frames are surfaced on the normalized point and diagnostics is left appendable, so a later mixed-frame guard plugs in cleanly. - only top-level structural failure raises SeriesError (machine-readable code), mirroring coherence.schema.EnvelopeError. - series_from_meaning_trend() converts a real meaning-trend result into a valid series dict, proving source-agnosticism (same loader as hand-written). - documented in docs/signal-series.md, referenced from the module docstring. Tests: tests/test_signal_schema.py (37 tests, fully offline; the trend JSON is built by driving the real trend engine with the synthetic embed_fn over the recorded series fixtures). Full suite 166 -> 203, green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SmwUt5WBBbrUc1vt2RdQYk * t11: quality domain engine — offline heuristics First honest implementation of the "quality" coherence domain: fully offline, deterministic, rule-based scoring of freshness/provenance/fidelity. Emits the shared measurement envelope (coherence/schema.py) with domain=quality, score_type=rule_based_heuristic, and an explicit null-frame (rule_based_no_embedding_frame) — never a fabricated embedding frame. Honesty contract: - diagnostics NAME what rules could not verify (source_liveness_unverified, publication_date_unverified, quote_accuracy_unverified); - absent signals lower per-component confidence with a diagnostic (no_dateable_statements / no_source_attribution / no_verbatim_signal), never fabricating a score; - confidence is visible in the scores map as <component>_confidence. - coherence/quality/heuristics.py: rule-based detectors + component scorers - coherence/quality/score.py: assess() raw breakdown + score_text() envelope - tests: 43 new, fully offline (socket-blocked fixture proves zero network) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SmwUt5WBBbrUc1vt2RdQYk * t12: quality compare — signed component deltas Implement coherence/quality/compare.py mirroring the shape of coherence/meaning/compare.py: before/after full quality envelopes plus a delta map with signed floats for all score components (freshness, provenance, fidelity and their _confidence entries). Delta = after - before for each component. - Fully offline: reuses score_text engine, threaded with reference_date - Open component registry: delta keys mirror scores map keys - Comprehensive test suite: 13 tests covering shape, delta arithmetic, edge cases, socket blocking (zero network access), and string/Path handling All 276 tests pass (263 existing + 13 new). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SmwUt5WBBbrUc1vt2RdQYk * t9: signal collect — measurements to series Add coherence/signal/collect.py with shape-driven extraction that builds valid series from N measurement JSONs of any domain (meaning, quality, investiture). Extraction rule: if measurement has dict-valued `scores` → extract those (full envelope path); otherwise harvest numeric leaves generically (top-level numeric keys + numeric entries from any top-level dict like subdimensions). API: - collect(measurements: list[Mapping], *, ids: list[str] | None = None) -> dict - collect_files(paths: list[str]) -> dict Output per point: id, index, timestamp (None), values (extracted numerics), frame (carried from measurement verbatim or None). Series-level domain: set when all inputs agree on one domain string, else None (no error). Zero numeric leaves in an input → raises SeriesError with code "collect_no_numeric_values" (matches schema error convention). All 25 new collect tests pass; full suite 288 tests green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SmwUt5WBBbrUc1vt2RdQYk * t7: signal resonance engine — signed alignment Add coherence/signal/resonance.py: pairwise Pearson alignment between a series' numeric fields, reported as ONE signed metric. Positive alignment is labeled "resonance" (streams reinforce), negative is "interference" (streams conflict) — both derived from the sign of the same computation, never two separate code paths. A neutral band (NEUTRAL_BAND = 0.1) around zero labels weak alignment as neither. Pairs with fewer than MIN_COMMON_POINTS (3) shared points, or with a constant (zero-variance) field, are excluded with a diagnostic rather than producing a NaN or fabricated correlation. A defensive non-finite-result guard (CODE_NON_FINITE_CORRELATION) covers any other source of a non-finite value. Tests (tests/test_signal_resonance.py, 15 new, offline/numpy-only) cover sign-carries-meaning (co-rising -> resonance, co-falling -> interference, sign-symmetry under negation), exact +-1 correlation cases, the neutral band, and every exclusion path (too-few-points, one/both constant fields, disjoint fields, NaN-poisoned values bypassing the loader). * t4: signal trend engine * t6: signal pattern engine Add coherence/signal/pattern.py: motif detection over a loaded Series, per numeric field. Six motifs (increasing, decreasing, plateau, spike, reversal, stair_step), each a deterministic, tolerance-gated rule against the field's own observed range — no learned/tuned parameters. Sparse fields are analyzed over their present values only (gaps get a diagnostic, never interpolated); series/fields with fewer than 3 usable points get an explicit insufficient-points diagnostic instead of motifs. tests/test_signal_pattern.py covers all 6 motifs on synthetic + counterexample series (12+ assertions), short-series guards, sparse-field gaps, per-field insufficiency, multi-field independence, and JSON-serializability. * t14: frames inspect/diff + mixed-frame guard * t10: meaning outputs gain additive envelope keys Score/compare/trend JSON gains three ADDITIVE top-level keys — domain, score_type, frame — while every pre-existing key stays byte-identical (the two-speed envelope rule; docs/envelope.md). meaning keeps its pinned v0.5.0 shape and only grows. - score.py: DOMAIN/SCORE_TYPE constants; meaning_frame() resolves the frame from the runtime embed config at call time via frames.provenance.build_frame (axes = meaning + the five subdimensions); score() = clean v0.5.0 core (_score_v050) + the three keys; offline_result() is the offline-diagnostics path — an explicit null_frame (code embed_endpoint_unreachable), never a fabricated frame. score() still raises EmbedUnavailable (exit-2 path unchanged). - compare.py: one shared top-level frame; before/after stay clean v0.5.0. - trend.py: one shared top-level frame added; difference math untouched. - CLI unchanged (it dumps the engine dict verbatim in --json mode). - New tests/test_meaning_envelope_keys.py (9): runtime-resolved frame, golden subset byte-identity on recorded vectors, offline null-frame. - Narrow additive-tolerance relaxations to existing meaning shape assertions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SmwUt5WBBbrUc1vt2RdQYk * t8: signal forecast — labeled extrapolation * t5: meaning trend delegates difference math to signal layer Point coherence/meaning/trend.py's f'/f'' differencing at the generic coherence.signal.trend.first_difference / second_difference functions so meaning trend is a dimension-specific wrapper (embed, label, assemble) rather than a private reimplementation. Output is byte-identical: pinned via full-result JSON goldens captured from the pre-refactor code (recorded-vector + synthetic-embed series) in the new tests/test_meaning_trend_delegation.py. Removed the private _first_difference and _slot helpers; retained _cosine_distance (drift distance), _second_unavailable_reason (labeling), and the _derivatives_from_* helpers (imported by test_meaning_envelope_keys). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SmwUt5WBBbrUc1vt2RdQYk * t13: investiture engine — estimated micro-investiture Add coherence/investiture/{__init__,score,compare}.py: the MVP measures estimated micro-investiture (meaning that becomes causal, issue #8) as meaning_score * agency * future_constraint * affordance, reusing coherence.meaning.score.score() for every embedding/axis computation (no duplicate embed path, same EmbedUnavailable exit-2 behavior). score() output satisfies both the shared measurement envelope (domain, score_type, scores, frame, diagnostics) and the issue-#8 JSON contract (investiture_score, mode="estimated", components with the unmeasured persistence_signal/integration_signal/behavioral_effect explicit nulls, evidence) in one dict, since validate_envelope tolerates extra top-level keys. compare() mirrors quality/compare.py's shape: before/ after are full score() results (each independently validating as an envelope, frame passed through verbatim from meaning), delta is a signed investiture_score plus the four numeric component deltas. 34 new tests in tests/test_investiture_{score,compare}.py, fully offline via the shared synthetic hash embedder; full suite 423 -> 457 green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SmwUt5WBBbrUc1vt2RdQYk * t15: assess engine — multi-domain report with honest availability Adds coherence/assess.py: one verb (assess) that runs every applicable domain (quality, meaning, investiture) against an artifact and returns a single report. assess itself ships the full shared envelope (domain, score_type, scores={}, frame=None, diagnostics) per the two-speed adoption rule for new nouns, with domains/unavailable/artifact layered on top. Quality always runs offline. Meaning/investiture need the embedding endpoint; when it's down, both are listed in `unavailable` with a machine-readable code + reason (investiture is skipped rather than re-attempted, since it derives from meaning), and meaning's offline rule-based diagnostics are still surfaced under unavailable["meaning"]["offline_diagnostics"] — partial availability is a normal, honest result, never silently dropped. tests/test_assess.py adds 19 fully-offline tests (synthetic embed_fn) for both acceptance criteria: endpoint down (quality + offline diagnostics, meaning/investiture unavailable with reasons) and endpoint up (all three domains present, unavailable empty). Full suite: 490 -> 509 passing. * t17: README + docs — five-domain positioning Rewrite README.md so coherence-cli is positioned as a five-domain coherence engine (quality, meaning, signal, investiture, frames): new lead tagline, a "why agents need coherence" intro, a five-domain overview with quality named as the first practical domain (not the whole product), the shared envelope + two-speed adoption rule (linking docs/envelope.md), verb-level CLI examples for every domain, a planned-extensions list naming what is explicitly not built yet (issues #4/#6/#8/#9/#10), and a language/falsifiability section. The Meaning Gradient section, its consumer map, and the scaffold-verb CLI table are preserved; the consumer map gains colleague as the first wired consumer of `meaning score --json`. Add docs/domains.md as the one-page per-domain reference (question / verbs / output shape / honest limitations), and tests/test_docs_language.py as a grep-able, word-boundary-sensitive banned-terms guard over README.md and the domain/envelope/series docs (excluding docs/specs/**, docs/plans/**, and .devague/**, which quote the spec's non-goals verbatim). Rewrote the README/domains.md non-goals language itself to avoid the banned substrings ("soul", "mystical", "literal physics", "universal meaning") rather than negate them in place, since a grep-based guard can't distinguish a claim from its own disclaimer. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SmwUt5WBBbrUc1vt2RdQYk * t16: CLI wiring for quality/signal/investiture/frames/assess + explain catalog Wires the five merged domain engines into the CLI, mirroring the existing meaning noun's pattern: quality (score/compare), signal (trend/pattern/ resonance/forecast/collect), investiture (score/compare, sharing meaning's EmbedUnavailable exit-2 path), frames (inspect/diff, where absent/partial provenance is a normal exit-0 result), and assess (a global verb; partial domain availability is exit 0, never an error). Extends the explain catalog with an entry per new noun/verb plus the eight frame-vocabulary concept terms, and extends cli overview/learn to list all five domains. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SmwUt5WBBbrUc1vt2RdQYk * docs: README examples section reflects wired CLI (post-t16 integration touch-up) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SmwUt5WBBbrUc1vt2RdQYk * t18: additive-compatibility + structure verification Deliverable 1 (tests/test_additive_compatibility.py): additive-only pre/post diff proof. meaning score/compare/trend, driven offline with the synthetic embedder, have {domain, score_type, frame} stripped and the remainder asserted byte-identical to an independent v0.5.0 reconstruction; before/after and per-point blocks carry no new keys. Scaffold verbs (whoami/learn/explain/ overview/doctor/cli overview) pin their established --json key sets unchanged. Deliverable 2 (tests/test_five_domain_structure.py): a package home per domain (quality/meaning/signal/investiture/frames + assess/schema) is importable; quality/signal/investiture/frames/assess are registered CLI nouns (top-level help, -h, explain); and the offline nouns never dial the embed endpoint (localhost:8002) — proven by a socket guard plus the green offline suite. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SmwUt5WBBbrUc1vt2RdQYk * chore: bump version to 0.6.0 + build-session memory Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SmwUt5WBBbrUc1vt2RdQYk * fix(ci): black-format four agent test files; make trend-delegation goldens float-tolerant across CPU/BLAS (structure still exact) The golden literals were captured pre-refactor and reproduced byte-for-byte on the capture machine; CI CPUs shift the last float ulp, so the assertion is now a deep compare — exact keys/strings/nulls, floats at 1e-9 rel tol. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SmwUt5WBBbrUc1vt2RdQYk * fix(ci): black-format quality/compare.py and signal/collect.py (missed in previous commit) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SmwUt5WBBbrUc1vt2RdQYk * fix(ci): backtick the assess <file> placeholder in CHANGELOG (MD033) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SmwUt5WBBbrUc1vt2RdQYk * refactor: address SonarCloud findings on PR #14 new code - merge implicit string concatenations (S5799) in overview/quality CLI verbs - constants for duplicated literals in signal CLI (S1192) - drop redundant JSONDecodeError from except clause (S5713) - split validate_envelope and _extract_values into per-field helpers to cut cognitive complexity below the threshold (S3776); codes, messages, and extraction semantics unchanged (suite-pinned) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SmwUt5WBBbrUc1vt2RdQYk * chore: eidetic memory — CI gotchas from the workforce build Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SmwUt5WBBbrUc1vt2RdQYk * fix: address Qodo review findings + CLI boilerplate duplication (PR #14) 1. Recorded vectors gain a model tie-out (Qodo #1): recorded_vectors.json is now {metadata, vectors} — the refresh script stamps the embedding model/ endpoint it actually ran against, the committed fixture is wrapped post-hoc with its known 2026-07-04 provenance (vector values unchanged), and the loader exposes load_recorded_metadata() with legacy-format fallback. 2. --json placement no longer matters (Qodo #2): verb-level --json flags use default=argparse.SUPPRESS via a shared helper so they never clobber a noun-level --json; applied to all six noun groups including meaning. 3. signal collect rejects non-object measurements (Qodo #3): valid JSON that is not an object raises SeriesError(collect_measurement_not_an_object) naming the offending file — exit 1, never an AttributeError. 4. Duplication: the per-noun file-error guard, remediation strings, and reference-date parsing move to cli/_commands/_artifact_io.py; the five noun modules keep only their domain-specific branches. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SmwUt5WBBbrUc1vt2RdQYk * refactor: split collect() point-building into helpers (S3776, complexity 17 -> under 15) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SmwUt5WBBbrUc1vt2RdQYk --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Added
CLAUDE.md— aper-task recall-before / remember-after convention (scope localized to this
repo's nick) so the vendored
remember/recallskills are actually used,not just present:
/recallbefore non-trivial work to build on priordecisions instead of re-deriving them, and
/rememberwhen a non-obviousdecision, constraint, fix-and-why, or hard-won gotcha surfaces. The section
documents this repo's memory as in-repo and public — records resolve to
<repo-root>/.eidetic/memory(committed, team- and mesh-shared). Insertedidempotently (skipped if already present), slotted under an existing
"Conventions and workflow" heading when one exists, else appended.
Changed
remember+recallwrappers from eidetic-cli 0.10.0(cite-don't-import) — picks up eidetic's project-local store default: the
files backend now resolves per record by visibility — PUBLIC records inside a
git repo go to
<repo-root>/.eidetic/memory(committed, team-shared), PRIVATErecords (or any record outside a repo) go to
$HOME/.eidetic/memory(nevercommitted), an explicit
EIDETIC_DATA_DIRstill wins, and recall reads bothstores and merges. Also carries the 0.9.3 hardening (interactive-stdin guard,
helpas a search term, SIGPIPE-safe suffix parsing). Recipe policyoverride (the wrappers here are NOT byte-verbatim): the injected default
visibility is flipped from eidetic's
privatetopublic, so a plain/rememberlands the note in./.eidetic/memoryin this repo, kept as partof the repo — pass
--visibility privateto route a record to$HOMEinstead.
rememberdriveseidetic remember(idempotent upsert of one JSONrecord or an NDJSON batch on stdin);
recalldriveseidetic recallwithfour search modes (exact / approximate / keyword / hybrid). Each
SKILL.mdislocalized only in the illustrative
--scope <nick>examples (Provenance keeps"First-party to eidetic-cli"). Runtime dep: the
eideticCLI on PATH (else alocal eidetic-cli checkout with
uv) —eidetic >= 0.10.0for thein-repo routing; on an older CLI the public records still work but are stored
in
$HOME/.eidetic/memoryinstead of in-repo. Propagated by rollout-cli'seidetic-memoryrecipe.