Skip to content

Latest commit

 

History

233 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Scry

CI

Scry is the consumer product: Remember everything. It helps people learn and memorize anything through a quiz-driven review loop. This repository contains Scry's Rust engine, not a separate product category or a generic agent-memory store.

The product has five faces over one capability system:

  • PWA — the primary, phone-first human surface
  • CLI — direct operator and power-user access
  • skill — a product-facing agent workflow
  • MCP — typed tools for agents and applications
  • API — the service boundary used by the PWA and other clients

Beta access is invite-gated with a visible waitlist. Human sign-in uses magic links only; there is no OAuth path. Machine faces use operator-gated service sessions. Subscription is the intended business model. Public signup remains closed until generation costs are bounded and privacy, reliability, and Stripe billing are proven. Fast and smooth are product bars: p95 acknowledgement below 100 ms, p95 graded-visible feedback below 300 ms, and first quiz visible below 20 s. See VISION.md for the canonical product contract.

Scry keeps a pure Rust learning kernel and explicit boundary crates. The kernel owns deterministic scheduling, grading, progression, queue selection, and learning invariants. Boundary crates own persistence, generation, sessions, identity, API routes, rendering, deployment, and QA.

The current production proof surface is the native Rust memory-engine-api process on Misty Step's isolated DigitalOcean public application host, backed by Neon Postgres and served at https://scry.study. Deployment, environment, auth, storage, rollback, and smoke-test details live in docs/runbook.md.

What It Owns

  • Canonical learning-domain types
  • FSRS state transitions
  • Deterministic grading
  • Progression and queue primitives
  • Recitation grading
  • Async rubric grading contracts
  • Vendor-neutral rubric adapter interfaces
  • Fixture corpora for contract and interface tests
  • Evals and benchmarks for learning-behavior regressions
  • Experimental clients that consume the API outside the reusable kernel

The core runtime in crates/memory-engine-core stays framework-free: no filesystem, network, UI, logging, model clients, or persistence. Service, storage, UI, auth, content parsing, and deployment experiments live in dedicated boundary crates until dogfood evidence proves a stable reusable contract.

Status

The Rust migration is complete for the main runtime:

  • canonical types
  • FSRS scheduler wrapper
  • deterministic grader
  • progression metadata and eligibility helpers
  • queue candidate filtering and selection
  • deterministic recitation grading
  • async rubric grading surface
  • facade adapter/testkit modules
  • service, persistence, generation, study, and local HTTP app hosts
  • Rust QA and benchmark receipt runners

The sole current production dogfood surface is the native memory-engine-api process on the isolated public application host, backed by Neon Postgres and served at https://scry.study. Agent-facing deployment, environment, auth, storage, rollback, and smoke-test details live in docs/runbook.md.

Current strategy and verification docs:

Historical extraction packets, retained as boundary evidence rather than active delivery oracles:

The active GitHub Issues queue tracks Scry production dogfood usefulness, service hardening, learning-science quality, input capture, and capability-boundary work on top of the Rust stack.

Usage

Rust consumers should use the facade crate:

use memory_engine::{next, ExactPrompt, ExactPromptKind, GradeContext, Grader, Prompt, ReviewUnitId};

let prompt = Prompt::Exact(ExactPrompt {
    kind: ExactPromptKind::ShortAnswer,
    review_unit_id: ReviewUnitId::new("latin-1"),
    prompt: "Translate poena".to_owned(),
    accepted_answers: vec!["punishment".to_owned()],
    equivalence_groups: Vec::new(),
    ignored_tokens: Vec::new(),
});

let grade = Grader::new().grade(
    &prompt,
    "Punishment",
    GradeContext {
        response_time_ms: 3_200,
        prior_reps: 3,
    },
);

let next_state = next(None, grade.rating, 1_779_465_600_000).expect("schedule");

Rubric grading stays adapter-backed; the Rust core owns normalization and dispatch, while callers own any model client:

use memory_engine::{
    AsyncGrader, GradeContext, GradeablePrompt, RubricAssessment, RubricCriterion,
    RubricCriterionResult, RubricCriterionVerdict, RubricDefinition, RubricPrompt,
    ReviewUnitId, StaticRubricGrader,
};

let prompt = RubricPrompt {
    review_unit_id: ReviewUnitId::new("rubric-1"),
    prompt: "Continue the prayer.".to_owned(),
    rubric: RubricDefinition {
        answer_guide: vec!["Continue with the next line.".to_owned()],
        passing_score: 1,
        criteria: vec![RubricCriterion {
            name: "continuation".to_owned(),
            description: "Gives the next line.".to_owned(),
            required: true,
        }],
    },
};
let grader = AsyncGrader::with_rubric_grader(StaticRubricGrader::new(RubricAssessment {
    model: Some("fixture".to_owned()),
    confidence: 1.0,
    feedback: "Strong answer.".to_owned(),
    criterion_results: vec![RubricCriterionResult {
        name: "continuation".to_owned(),
        verdict: RubricCriterionVerdict::Pass,
        evidence: "Supplied the continuation.".to_owned(),
    }],
}));
let grade = grader.grade_prompt(
    GradeablePrompt::Rubric(&prompt),
    "Strong answer.",
    GradeContext {
        response_time_ms: 6_000,
        prior_reps: 0,
    },
).expect("rubric grade");

Test fixtures for contract and interface tests:

use memory_engine::testkit::{grading_fixtures, scheduler_fixtures};

Quickstart

Prerequisites: the pinned Rust toolchain from rust-toolchain.toml and Bun for the fast gate. Dagger is required for the full/ship parity handoff; it uses the same Rust 1.94 line through the Dagger image.

Set the repository hook and run the local Rust verification loop:

git config core.hooksPath .githooks
cargo fmt --all --check
cargo test --workspace
cargo clippy --workspace --all-targets -- -D warnings
cargo doc --workspace --no-deps
bun run ci
bun run ci:local # compatibility alias for bun run ci

Run the Dagger-backed full gate before handoff:

bun run ci:full

Run the production-shaped API locally with a file store:

MEMORY_ENGINE_ENVIRONMENT=development MEMORY_ENGINE_ENABLE_FILE_STORE=true MEMORY_ENGINE_API_STORE_DIR=.tmp/api-dev MEMORY_ENGINE_AUTH_ALLOWED_EMAILS=owner@example.com MEMORY_ENGINE_RETURN_UNSUBSCRIBE_SECRET=local-dev-secret MEMORY_ENGINE_AUTH_LINK_OUTBOX_PATH=.tmp/api-dev/outbox.tsv HOST=127.0.0.1 PORT=18080 cargo run -p memory-engine-api

From another shell, verify the local health route:

curl -fsS http://127.0.0.1:18080/healthz

License

MIT

About

Shared learning engine kernel: canonical domain types, FSRS reference scheduler, deterministic grader. Pure, framework-free.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages