Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

1 Commit

Repository files navigation

JoyRide

StatusTestsAPILicense: MIT

Bounded typed execution cache for LUMI agent hot paths.

JoyRide accelerates repeated safe work during active coding sessions — read-only commands, workspace search, and strictly proven verification — without storing secrets, without bypassing approval boundaries, and without pretending to be durable agent memory.

JoyRide is cache, not memory. Locality and speed with explicit invalidation — not identity, narrative continuity, or long-term recall.

Repository:github.com/CardSorting/JoyRide · Contributing:CONTRIBUTING.md · License:MIT — CardSorting


Table of contents

Documentation

LayerDocumentAudience
Hubdocs/README.mdNavigation and reading paths
Briefdocs/BRIEF.mdExecutives, PM — one page
Philosophydocs/PHILOSOPHY.mdArchitects — design principles
How caching worksdocs/CACHING.mdIntegrators — inputs → hash → hit/miss
Whitepaperdocs/WHITEPAPER.mdImplementers — full specification
API referencedocs/API.mdContributors — frozen surface
Glossarydocs/GLOSSARY.mdEveryone — canonical terms
Troubleshootingdocs/TROUBLESHOOTING.mdOperators — runbook
ContributingCONTRIBUTING.mdContributors — hot path guide, PR checklist
LicenseLICENSEMIT — Copyright CardSorting
Operator guidedocs/OPERATORS.mdLUMI operators — config, disable
Release notesdocs/RELEASE-NOTES.mdRelease managers
LUMI embeddingdocs/LUMI_INTEGRATION.mdMonorepo integration

Reading paths

You are…Read in order
New to JoyRideBrief → Caching model → README quick start
Adding a hot pathCONTRIBUTING.md → Caching model → API
Reviewing designPhilosophy → Whitepaper
Opening a PRCONTRIBUTING.md §PR checklist
Debugging reuseTroubleshooting → Decision log

Status

AttributeValue
MaturityGA — production runtime infrastructure
APIModern-only; legacy boolean helpers removed
Export surfaceFrozen — 69 symbols in JOYRIDE_FROZEN_EXPORTS
Tests179+ unit tests, CI via npm run test:unit
UINone — observability via logs and snapshots
DurabilitymemoryOnly (session-scoped)

Architecture

flowchart TB
subgraph integrations [Runtime integrations]
TASK[task/index.ts]
SEARCH[SearchFilesToolHandler]
COMPLETE[AttemptCompletionHandler]
EXT[extension.ts]
end
subgraph public [Public API — @core/joyride]
HP[JoyRideHotPath]
LC[JoyRideLifecycle]
CFG[JoyRideConfig]
DIAG[JoyRideDiagnostics]
end
subgraph policy [Policy layer]
CLS[JoyRideCommandClassifier]
VER[JoyRideVerification]
CTX[JoyRideContext]
end
subgraph storage [Storage layer — internal]
CACHE[JoyRideCache]
end
TASK --> HP
SEARCH --> HP
COMPLETE --> LC
EXT --> DIAG
HP --> CLS
HP --> VER
HP --> CTX
HP --> CACHE
LC --> CACHE
Loading

Import rule: integrations touch JoyRideCache only through typed helpers — never direct .get() / .set().


How it works (30 seconds)

JoyRide uses input-hash caching (same discipline as Turbo/Nx task caches):

  1. Inputs — command, cwd, workspace fingerprints, file hashes, search dimensions
  2. Hash — SHA-256 over stable-serialized inputs → cache key
  3. Lookup — compare stored validation fingerprint vs current proof
  4. Decision — typed hit / miss / stale / rejected + fallbackBehavior
  5. Invalidate — TTL, task flush, generation bump, fingerprint change

See Caching model for full input tables and sequence diagrams.


Core guarantees

#GuaranteeEnforcement
G1Fail-closed reuseAllowlist classifier; verification proof gate
G2Typed decisions onlyJoyRideCacheDecision; no boolean API
G3Bounded memory32 MiB default; pressure + emergency trim
G4Secret safetyAdmission scan; no secret in diagnostics
G5Instant disableJOYRIDE_MODE=disabled
G6Degraded fallbackInternal errors suspend reuse; agent continues
G7AuditabilityDecision log (128), hit audit trail, snapshots
G8Contract stabilityDrift tests on exports and import boundaries

Quick start

Command hot path

import{getJoyRideCache,createJoyRideTaskScope,isJoyRideHitDecision,lookupSafeCommandResult,registerTaskLifecycle,storeReusableCommandResult,}from"@core/joyride"constcache=getJoyRideCache()constscope=createJoyRideTaskScope(taskId,cwd,terminalMode,generation)registerTaskLifecycle(cache,taskId,scope.generation)constdecision=awaitlookupSafeCommandResult(cache,command,scope)if(isJoyRideHitDecision(decision)){returndecision.value// [userRejected, toolResponse]}constresult=awaitexecute(command)awaitstoreReusableCommandResult(cache,command,result,scope)returnresult

Search hot path

constdecision=awaitlookupSearchResult(cache,query,{ cwd, includeGlobs },scope)if(isJoyRideHitDecision(decision)){returndecision.value// results string}// execute search, then storeSearchResult(...)

Rules (non-negotiable)

  1. Import only from @core/joyride
  2. Use isJoyRideHitDecision(decision) before skipping work
  3. Follow decision.fallbackBehavior — do not invent policy
  4. Never call getJoyRideCache().get(), .set(), or .trySet()

Configuration

VariableDefaultEffect
JOYRIDE_MODEenableddisabled · diagnostics-only · enabled
JOYRIDE_COMMAND_REUSEon0/false → never skip commands
JOYRIDE_VERIFICATION_CACHEon0/false → never reuse verification
JOYRIDE_SEARCH_CACHEon0/false → never reuse search
JOYRIDE_SCRATCH_CACHEon0/false → reject scratch retention
# Kill switch
JOYRIDE_MODE=disabled code .# Observe cache behavior without skipping work
JOYRIDE_MODE=diagnostics-only code .

Cache kinds

KindWhatSkip policy
hotExecutionCommand summariesAllowlist safe-readonly only
verificationTest/lint outputComplete proof required
workspaceIndexSearch/grep resultsFull key dimension match
scratchArtifactTemp task artifactsNo skip — cleanup-owned
taskLocalTask metadataFlushed on task end

Default budgets: 32 MiB total · 512 KiB max entry · 8 MiB per task · 4–12 MiB per kind.


Typed decisions

typeJoyRideDecisionType=|"hit"|"miss"|"stale"|"rejected"|"disabled"|"diagnosticOnly"|"degraded"

Every decision includes: canReuse, reasonCode, fallbackBehavior, auditEventId.

Reason codes use stable prefixes: hit. · miss. · stale. · reject. · degraded. · trim. · cleanup. · lifecycle.

Full catalog: Whitepaper Appendix A


Runtime integrations

FileRole
src/core/task/index.tsCommand lookup/store; cancel flush; env-altering invalidation
src/core/task/tools/handlers/SearchFilesToolHandler.tsSearch lookup/store
src/core/task/tools/handlers/AttemptCompletionHandler.tsTask completion flush
src/extension.tsDeactivate diagnostics + shutdown

Diagnostics

import{createJoyRideBugReportSnapshot,getJoyRideDecisionLog,getJoyRideCacheHitAuditTrail,summarizeJoyRideHealth,getJoyRideCache,}from"@core/joyride"summarizeJoyRideHealth(getJoyRideCache())createJoyRideBugReportSnapshot(getJoyRideCache())

Runbook: Troubleshooting


Testing

npm run test:unit -- --grep "JoyRide"
SuiteGuards
JoyRideContractDriftExport surface freeze
JoyRideImportBoundaryIntegration import rules
JoyRideRealSessionSession dogfood scenarios
JoyRideVerificationGaVerification proof strictness
JoyRideBenchmarkPerformance regression gates
JoyRideGaReadinessDoc + suite completeness

Helpers: __tests__/JoyRideTestHelpers.ts


Contributing

Full guide: CONTRIBUTING.md

Quick checklist:

  • Import only from @core/joyride
  • Typed lookup/store helpers — no raw cache access
  • isJoyRideHitDecision() before skipping work
  • Handle fallbackBehavior; precise JOYRIDE_REASON codes
  • Test enabled / disabled / diagnostics-only / degraded
  • Test stale invalidation + unsafe refusal
  • npm run test:unit -- --grep "JoyRide" passes
  • Update docs + JoyRideContract.ts if contract changes

Also see CONTRIBUTING.md and docs/OPERATORS.md.


Comparison

ApproachJoyRideNaive cacheAgent memory
APITyped decisionsboolean hit/missunstructured store
Command reuseAllowlistanything cachedanything "remembered"
VerificationFull prooflast outputlast output
Bounds32 MiB + TTLunboundedunbounded
Disableenv varcode changeunclear
Observabilityreason codes + auditlogsopaque
Persistencesessionvariescross-session

What JoyRide is not

  • Agent memory, identity, or long-term recall
  • UI, dashboard, or status surface
  • Cross-session persistence for active reuse
  • Substitute for tests when proof is incomplete
  • Bypass for user approval boundaries

Tagline

Fast when safe. Silent when irrelevant. Explicit when questioned. Disabled when needed. Degraded when suspicious. Fail-closed always.


License

JoyRide (src/core/joyride/) is licensed under the MIT License — Copyright (c) CardSorting.

The broader LUMI repository may use a different license. See repository root LICENSE for the full project terms.

About

Bounded typed execution cache for LUMI agent hot paths — fail-closed, auditable, MIT licensed by CardSorting.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages