> ## Documentation Index
> Fetch the complete documentation index at: https://docs.grindxp.app/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Quest Engine

> How quests are created, validated, and transitioned through their lifecycle.

The quest engine lives in `packages/core/src/quest/`. It is a pure domain module with no database calls and no side effects. All vault operations happen in the repository layer.

## State Machine

Quest state transitions are validated by `state-machine.ts`. Not all transitions are legal:

```
available → active         (start / timer start)
available → completed      (direct complete, bounties only)
active → completed         (complete)
active → failed            (deadline passed)
active → abandoned         (manual abandon)
completed → available      (daily/weekly reset at midnight)
```

Attempting an invalid transition throws a typed error.

## Quest Entity

`createQuestEntity` wraps raw quest data from the database into a domain object with computed properties:

* `isOverdue`: whether the deadline has passed
* `nextReset`: when a daily/weekly quest resets
* `currentObjectiveIndex`: for epic/chain quests
* `completionRate`: percentage of objectives done

## Completing a Quest

`completeObjective(quest, objectiveId)` handles partial completion for epic and chain quests. When all objectives are done, the quest status transitions to `completed`.

For simple quests (daily, weekly, bounty, ritual), a single complete call transitions directly.

## Streak Tracking

`resetQuestStreak(quest)` is called by the scheduler when a daily/weekly quest's deadline passes without completion. It:

1. Decrements the streak counter
2. Applies the streak penalty multiplier to the next award
3. Consumes a streak shield if one is available

## Repository Interface

```typescript theme={null}
import { createQuestRepository } from "@grindxp/core/vault";

const repo = createQuestRepository(db);

// Create
await repo.create({ title, type, difficulty, skillTags, baseXp });

// Complete (handles XP award + skill update + streak)
await repo.complete(questId, { proofType, proofData, note });

// List with filtering
await repo.list({ status: "active", type: "daily" });
```

The `complete` method in the repository orchestrates: proof creation → XP calculation → character XP update → skill XP distribution → streak increment → log entry.
