lwc 0.17.11

Agent-driven proactive memory CLI for AI agents — autonomously recall, maintain, and evolve persistent, source-grounded knowledge across sessions.
# Learning Suite implementation contracts

These contracts close the six discovery items in `TASK-001`. Product behavior remains
defined by the approved Learning Suite plan; this file fixes only implementation
choices that later tests and code must share.

## Fixed runtime and package layout

- Keep the existing Cargo package. Add three bin targets: `lwc-tutor`, `lwc-book`, and
  `lwc-practice`, sharing only their learning source modules. The current package has
  no library target, so converting all of LWC into a library, a workspace, dynamic
  plugin ABI, discovery, and PATH fallback are out of scope.
- Core exposes exactly `lwc tutor ...`, `lwc book ...`, and `lwc practice ...`. It
  checks the independent global capability, installs the fixed runtime when missing,
  then forwards cwd, stdin, arguments, stdout, stderr, and exit status unchanged.
- Runtime path:
  `~/.lwc/runtime/<plugin>/<lwc-version>/<target>/lwc-<plugin>[.exe]`.
  Canonical data remains under `~/.lwc/plugins/<plugin>/` and is never removed by
  disable or runtime replacement.
- Release tag is `v<lwc-version>`. Asset names are
  `lwc-<plugin>-<lwc-version>-<target>.tar.gz` on Unix and `.zip` on Windows for the
  existing six targets. The same release's combined `SHA256SUMS` is authoritative.
- `SHA256SUMS` is at most 1 MiB and must contain exactly one strict lowercase 64-hex,
  two-space entry for the requested basename. Archives are at most 256 MiB. Missing,
  duplicate, malformed, renamed, mismatched, oversized, or wrong-tag inputs fail
  before publication.

## Enablement, Agent routing, and privacy

Graph applicability remains outside Learning Suite routing and is evaluated independently: the physical document graph requires a document-relationship task plus document or Wiki evidence in the project root.
CodeGraph requires a code-structure task and code evidence in the current working root.
No-code learning never prompts for CodeGraph.

- Tutor, Book, and Practice are independently `disabled` in the built-in global
  configuration. Enable them with `lwc --scope global config set --tutor enabled`,
  `lwc --scope global config set --book enabled`, or
  `lwc --scope global config set --practice enabled`; project/all configuration is rejected.
  Enabling changes configuration only. The first runtime-backed domain operation
  lazily installs its fixed asset.
- Canonical Skills are `using-tutor`, `using-book`, and `using-practice`. Explicit
  intent enters the matching enabled workflow, ambiguous learning intent asks one
  direct question, and ordinary factual Q&A stays outside Tutor. If a needed plugin is
  disabled, ask once before enabling unless the user explicitly requested enablement.
  Recover pending durable work before creating new work.
- Learning Skills treat plugin operations as a silent control plane: they never narrate
  routine calls, inspect private stores, probe help for known arguments, or persist a
  Skill invocation as learner content. `tutor status` preserves its count fields and
  additionally returns the complete Soul plus at most 20 active resume contexts.
- Cold entry and recovery run Tutor status once; a bound hot turn uses the cached exact binding, then begin → teach → commit → display.
- Each mutation has its own stable request ID, reused only to retry that same mutation.
- Practice is entered only for durable papers, attempts, grades, flashcards, scheduled review, mistake history, or goal evidence.
- Routine control-plane work stays silent; before a meaningful batch, phase change, or visible wait, the Agent gives one outcome-level sentence.
- Tutor teaching checkpoints may carry a hidden cognitive anchor containing the current
  node, evidenced mastered nodes, mode, clearance status, and next action. The visible
  reply never contains this raw anchor.
- The three canonical stores and Tutor/Book private Wiki projections are user-private
  and independent from the ordinary LWC Wiki. Skills transfer only exact typed IDs,
  revisions/hashes, and visible evidence; hidden reasoning is never persisted.
- Disable, runtime quarantine/replacement, archive, correction, and Sync preserve
  canonical data. V1 has no forget/clear/purge operation and never purges safe,
  unreferenced Book blobs. A future destructive purge requires its own Sync-aware
  design and explicit authorization; manual deletion is outside the contract.

## CLI and JSON boundary

- Plugin successes emit one UTF-8 JSON object:
  `{ "schema_version": 1, "plugin": "...", "command": "...", "result": ... }`.
  Failures use LWC's existing `{ "error": { "code", "message", "details" } }`
  shape and exit non-zero. Core never wraps either stream a second time.
- Mutation commands accept `--json JSON|-|@PATH`. Input is capped at 64 MiB, must be
  UTF-8, rejects unknown fields, and resolves `@PATH` relative to cwd. Entity creation
  requires `request_id`; mutation of existing state requires `if_revision`.
- IDs are opaque lowercase identifiers. Cross-plugin references always contain
  `kind`, exact `id`, and `revision_or_hash`; title/tag lookup never supplies identity.
- Initial command families are fixed to those listed in the architecture:
  Tutor `subject|session|turn|learner|soul|goal|plan|status`; Book
  `subject|import|prepare|status|search|show|peek|read|synthesis`; Practice
  `subject|bank|item|set|paper|attempt|response|grade|review|next|status`.

## Book conversion, blobs, and reading window

- TXT and Markdown normalize directly. EPUB and text PDF invoke the configured
  converter adapter through a shared Rust function; the Book binary never starts a
  nested `lwc` process. HTML, scanned/OCR PDF, MOBI, and AZW3 remain unsupported.
- Exact original bytes are committed first. Normalization records input hash,
  converter/arguments, output hash, UTF-8 validation, anomalies, and ordered blocks.
  Direct text removes one UTF-8 BOM and normalizes CRLF/CR to LF; converter output is
  otherwise preserved after UTF-8 and non-empty validation.
- Original and normalized bodies are content-addressed files at
  `~/.lwc/plugins/book/blobs/sha256/<first-two>/<hash>`. SQLite stores hashes,
  lengths, kinds, and references. Publication uses a private staged file, hash and
  length readback, atomic rename, then the referencing SQLite transaction. Orphaned
  unreferenced blobs are safe and are not purged in v1.
- `book read next` accepts `budget` with unit `tokens` or `utf8_bytes`. With a reported
  token budget it uses floor(55%) for source text; without one it uses a configurable
  64 KiB UTF-8-byte fallback. Every lease reports the requested unit/value, applied
  source limit, exact used bytes/chars, and block range. No model-name guessing occurs.

The Pro capacity probe wrote a 256 MiB deterministic corpus both ways. APFS copied the
external file in 3 ms (clone timing is not portable); incremental SQLite BLOB commit
took 752 ms and produced a 270,292,632-byte WAL. The decisive result is the extra
full-size SQLite/WAL surface, so content-addressed files carry large bytes while
SQLite retains transactional metadata.

## Practice scheduling

- Pin `rs-fsrs = "=1.2.1"` with Serde support. It is the Open Spaced Repetition
  project's scheduler-only Rust crate, uses the MIT license, and avoids the optimizer
  and numerical dependency surface of the `fsrs` crate.
- Persist the scheduler crate/version, parameters, complete ordered review events, and
  resulting card state. Acceptance includes the upstream rating sequence whose
  scheduled-day vector is `0,4,15,48,136,351,0,0,7,13,24,43,77`.

Primary sources:

- <https://github.com/open-spaced-repetition/rs-fsrs>
- <https://github.com/open-spaced-repetition/fsrs-rs>

## Soul and Sync boundaries

- Soul's default full-body budget is 64 KiB and configurable up to 256 KiB. The limit
  is on UTF-8 bytes, never silent truncation. Exceeding it requires an explicit
  evidence-preserving semantic revision. The entire current body is returned with its
  byte count, hash, and revision for every Tutor teaching turn.
- Sync keeps Wiki `StoreIdentity` unchanged. Protocol v2 adds three fixed plugin units,
  each with a separate `PluginStoreIdentity`, canonical manifest, bounded record
  stream, and content-addressed blob stream. Derived FTS/Wiki/graph files never cross.
- A missing runtime does not remove a unit from inventory: the destination validates
  and atomically preserves the canonical export as `preserved_not_ready`. Two changed
  stores require the exact plugin schema merge implementation and baseline; otherwise
  the session fails before any Wiki or plugin publication.