Universal Quest System
Quests grow up: visibility/context discriminator, optional bounty, target-artifact rollup, auto-generation from CMDB gaps, and atomic credential + XP rewards on completion.
Added
- `QuestPayload.visibility` (`internal` | `public`) and `QuestPayload.context` (`marketplace` | `workspace_task` | `maintenance`) as required discriminators
- `QuestEvidenceKind` union — `validation_session`, `artifact_assessment_submitted`, `form_completed`, `manual_attestation`
- `QuestTargetArtifact[]` rollup payload — multi-artifact, multi-kind quest targets supersede the single `requiredGttSlug`
- Bounty is now optional — `workspace_task` and `maintenance` contexts accept `priceTier: 'free'` with no escrow checks
- Bounty-free quests auto-close on activation (verified → closed) with two-hop `stateHistory` entries
- **Artifact-completeness library** (`src/lib/server/artifact-completeness/`) — pure-function `computeCompleteness(artifact, domain)` with FAIR domain implementation for `it_system` artifacts
- **Quest Generator engine** (`src/lib/server/quest-generator/`) — template-driven scanner with dedup, rate caps (50/workspace/day, 5/template/cycle), circuit-breaker, 24h scheduler, cockpit lazy-refresh
- `questTemplates` + `questGenerationLog` collections with FAIR-on-`it_system` default template seeded per workspace
- `quest_completion` credential type with `QuestCompletionMetadata` — atomic credential + Foundation Skill XP credit on quest completion
- `QuestPayload.rewardSpec` — canonical reward configuration (credentialType + skill + xp) copied from generator templates at insert time
- Compensating-rollback reward path — credential revoked if XP write fails; existing-credential pre-check prevents double-rewards on retry
- Migrations 027 (visibility/context backfill), 028 (targetArtifacts from requiredGttSlug), 029 (questTemplates schema + indexes), 030 (seed default FAIR template into existing workspaces)
Changed
- Quest publish validator now checks `visibility`, `context`, `evidenceSpec.kind`, `targetArtifacts` consistency, and optional `rewardSpec` (credentialType + xp + foundation-skill existence)
- Q1g acceptance loop guards against non-`validation_session` evidence and issues reward *before* close-CAS for bounty-free path (failure leaves quest at `verified` for retry)
- Marketplace QuestPublishPane hides bounty and party-kind fields for non-marketplace contexts
- Workspace-creation routes (`/api/spaces/+server.ts`, `/api/spaces/from-template/+server.ts`) seed the default FAIR quest template
- Cockpit page-load triggers a lazy quest-refresh (debounced, fire-and-forget with `.catch()` to prevent SvelteKit unhandled-rejection crashes)
Universal Quest System
Quests stop being a single-shape marketplace-only object and become a general-purpose unit of work that can target any artifact in the workspace. The v1 lands in four chunks (U1a–U1d Foundation, U2c Completeness library, U2a Generator engine, U3a Reward wiring) that together turn the cockpit into a self-replenishing to-do list grounded in actual data gaps.
U1a–U1d Foundation
QuestPayload gains two required discriminators: visibility (internal workspace-only vs public marketplace) and context (marketplace / workspace_task / maintenance). The evidence-type union expands from a single shape to four — validation_session, artifact_assessment_submitted, form_completed, manual_attestation — and the Q1g acceptance loop now guards against non-validation_session evidence to prevent unintended state transitions. A new targetArtifacts rollup payload supersedes the single requiredGttSlug field (which is @deprecated with a v2 removal note) and lets one quest target multiple artifacts of multiple kinds. Bounty becomes optional: only marketplace-context quests still require it — workspace_task and maintenance quests accept priceTier: 'free' and bypass all wallet/treasury/HoF escrow checks. Bounty-free quests auto-close on activation (verified → closed) with both state hops recorded in stateHistory for audit consistency.
Migrations 027 (backfill visibility='public', context='marketplace') and 028 (backfill targetArtifacts from requiredGttSlug using $cond/$ifNull for null-safety) ship the schema change without breaking existing quests.
U2c Artifact-Completeness Library
A pure-function module that defines what "complete" means per domain for CMDB artifacts. v1.5 implements the FAIR domain (Findable / Accessible / Interoperable / Reusable — 6-dimension check for it_system artifacts). Other domains return null and are explicitly null-checked by the generator, so the system fails closed instead of generating noise. This becomes the canonical "is this artifact good enough?" oracle that the generator consults before deciding whether to spawn a quest.
U2a Quest Generator Engine
The heart of the new system: a template-driven generator that scans every CMDB artifact in every workspace against quest templates, calls computeCompleteness() per artifact, and auto-creates an internal quest for each gap it finds. Ships with the FAIR-on-it_system default template seeded into every new workspace (migration 030 backfills existing workspaces).
Production-grade safeguards baked in:
- Dedup via
generatorTemplateId+ targetArtifacts canonical-hash — same gap never spawns twice - Rate caps: 50 quests per workspace per day (UTC), 5 per template per cycle
- Circuit-breaker: pauses a template after 3 consecutive empty runs, manual-only resume in v1.5
- 24h scheduler over active workspaces + cockpit lazy-refresh debounce (fire-and-forget with explicit
.catch()) - Unique slug format:
gen-{domain}-{spaceId8}-{YYYYMMDD}-{nanoid6} insertMany({ ordered: false })for best-effort batch semantics
U3a Reward Wiring
Quest completion now issues a credential and credits Foundation Skill XP atomically. A new quest_completion credential type carries QuestCompletionMetadata (skill slug, XP awarded, listing reference). The bounty-free auto-close path calls rewardQuest() before the close-CAS so a reward failure leaves the quest retryable at verified rather than closed-but-unrewarded. Compensating rollback: if the XP write fails after credential issue, the credential is revoked. Idempotency: existing-credential pre-check prevents double-rewards on retry.
rewardSpec lives on QuestPayload as the canonical source (the generator copies it from the template at insert time — no dual-config drift). Publish validator enforces credentialType: 'quest_completion', positive XP, and existence of the named skill in foundationSkills.
Net effect
A workspace now self-populates its own backlog: as long as artifacts exist and templates are seeded, the generator fills the quest queue with concrete, addressable data-quality work — and completing those quests rewards the human inside the workspace with skill XP, closing the loop between operational improvement and individual progression.