Skip to content

Arturo Quest System

Overview

The Quest System is Arturo's core work-tracking feature, measuring outcome-scoped work in pomodoros (25-minute focused sessions) and cycles (4 pomodoros). Quests are tiered by effort: errand (1-2p), venture (1 cycle), quest (2-4c), expedition (5-10c), and saga (10+c).

Lifecycle

Quests progress through: proposed -> charted -> active -> completed (or abandoned). Each quest can have multiple role assignments with independent effort estimates.

When a quest is created without an explicit issue_url, Arturo automatically opens a corresponding GitLab issue in the astrolabe knowledge repo (the-smithy1/agents/astrolabe). The issue is labelled quest::<title-slug> and tier::<tier>, along with any domain tags.

Contributor Linkage

Quest roles can optionally be linked to a contributor identity via contributor_id and contributor_source (currently 'spyder'). These fields are stored on the quest_roles table and are set when assigning a role:

quest_service.add_quest_role(
    quest_id=42,
    role_name="implementer",
    scope="backend API",
    estimated_pomodoros=8,
    contributor_id=117,
    contributor_source="spyder",
)

If a role is re-assigned (upsert on quest_id, role_name), existing contributor values are preserved unless explicitly overwritten (COALESCE logic).

Shimmer Credits

On quest completion, contributors linked to roles automatically receive shimmer credits based on the quest tier:

Tier Credits
errand 5
venture 15
quest 40
expedition 100
saga 250

Credits are created as pending entries in the shimmer_credit_log table and delivered asynchronously by the scheduler via retry_pending_shimmer_credits(). This avoids blocking the completion path with synchronous HTTP calls. Credit statuses are: pending, sent, or failed.

Prerequisites: A role must have a non-null contributor_id to receive credits. Roles without a linked contributor are skipped.

Auto-Completion

When ARTURO_QUEST_AUTO_COMPLETE=true, the QuestCompletionService monitors merged MRs. If all MRs linked to a quest have been merged, the quest is automatically marked complete. Completion now also triggers shimmer credit issuance for any contributor-linked roles (see Shimmer Credits).

Key Code Paths

File Purpose
src/services/quest_service.py Quest CRUD, velocity calculation, GitLab issue creation (target project: the-smithy1/agents/astrolabe), shimmer credit issuance
src/services/quest_completion_service.py Auto-complete on MR merge
src/services/feedback_service.py Mobile feedback pipeline: screenshot analysis via Claude vision and GitLab issue creation
src/handlers/quest_command_handler.py /arturo quest Slack commands
src/api/router.py REST API endpoints for quest operations, feedback, and CI/automation notifications
src/core/schema.sql Schema including quest_roles contributor columns and shimmer_credit_log table
src/core/migrations/006_quest_contributor_linkage.sql Migration adding contributor linkage and shimmer credit log
agents_shared/notify.py (agents-shared) Shared notify substrate: NotifyHandler and attach_notify_routes used by the /notify endpoint

Slack Commands

  • /arturo quest create <title> --tier <tier> --effort <Np> -- Create a quest
  • /arturo quest list [status] -- List quests
  • /arturo quest view <id> -- View quest details
  • /arturo quest update <id> --status <s> -- Update quest
  • /arturo quest log <id> <Np> [notes] -- Log time
  • /arturo quest velocity [weeks] -- Velocity report

API Endpoints

  • GET /api/v1/quest/list -- List quests. Supports optional query parameters:
  • status -- Filter by quest status
  • domain -- Filter by domain
  • include_roles -- Set to true, 1, or yes to include role details, contributor info, and role counts (roles_total, roles_filled, roles_open) in the response
  • GET /api/v1/quest/{id} -- Quest details (roles now include contributor_id and contributor_source)
  • POST /api/v1/quest/create -- Create quest
  • PATCH /api/v1/quest/{id} -- Update quest
  • GET /api/v1/velocity -- Quest velocity report
  • POST /api/v1/feedback/analyze -- Analyze a mobile screenshot and logs using Claude vision. Returns a draft description, suggested category (bug, suggestion, or question), and confidence score. Requires feedback_service to be configured; returns 503 otherwise.
  • POST /api/v1/feedback/submit -- Submit confirmed feedback as a GitLab issue. Requires a description field in the JSON body. The issue is created in the GitLab project mapped to the client_name (e.g., Smithy-Reader, Smithy-iOS). Returns 503 if feedback_service is not configured.
  • POST /api/v1/notify -- Post a Slack message through Arturo's bot voice. Intended for CI/automation pipelines to post build, deploy, and release outcomes. Wired through the shared agents_shared.notify substrate (agents-shared#37). Accepts a JSON body with:
  • text (required) -- Non-empty message string
  • channel (optional) -- Slack channel override; omit or set to null to use the default channel
  • level (optional) -- One of info, success, error, or warning. Prepends an emoji (ℹ️, , , ⚠️) to text when supplied. Callers may also pass fully formatted text and omit level.

Default channel: Configured via the ARTURO_CI_NOTIFY_CHANNEL environment variable (k8s configmap). Falls back to #build-alerts when the variable is absent or blank.

Prerequisites: The route is only registered when a slack_client is injected into ApiRouter (always true in production; omitted in unit tests that don't need it). Requires Bearer auth like all other /api/v1 routes.

Responses: 200 {ok: true, data: {ts, channel}} on success; 400 for missing or empty text; 401 for missing/wrong Bearer token; 502 for Slack post failures.

Example: List quests with roles

GET /api/v1/quest/list?status=active&include_roles=true

Response entries include:

{
  "id": 42,
  "title": "Implement shimmer integration",
  "tier": "quest",
  "status": "active",
  "roles": [
    {
      "role_name": "implementer",
      "scope": "backend API",
      "status": "assigned",
      "contributor_id": 117
    }
  ],
  "roles_total": 1,
  "roles_filled": 1,
  "roles_open": 0
}

Example: Analyze mobile feedback

POST /api/v1/feedback/analyze
Content-Type: application/json

{
  "screenshot_base64": "<base64-encoded image>",
  "logs": "recent client log lines...",
  "app_name": "Smithy-Reader",
  "device_info": {"os": "iOS 18.1", "model": "iPhone 15"},
  "current_room": "The Great Hall"
}

Response:

{
  "ok": true,
  "data": {
    "draft_description": "The screenshot shows a rendering glitch in the room description panel...",
    "suggested_category": "bug",
    "confidence": 0.85
  }
}

Example: Submit feedback as GitLab issue

POST /api/v1/feedback/submit
Content-Type: application/json

{
  "category": "bug",
  "description": "Rendering glitch in room description panel",
  "client_name": "Smithy-Reader",
  "app_name": "Smithy-Reader",
  "device_info": {"os": "iOS 18.1", "model": "iPhone 15"},
  "current_room": "The Great Hall"
}

Response:

{
  "ok": true,
  "data": {
    "status": "created",
    "issue_url": "https://gitlab.com/the-smithy1/mobile/reader/-/issues/42",
    "issue_number": 42
  }
}

Supported clients for feedback routing:

client_name GitLab project
Smithy-Reader the-smithy1/mobile/reader
Smithy-iOS the-smithy1/ios
Smithy-Looper the-smithy1/mobile/looper
Smithy-Companion the-smithy1/mobile/companion

Unknown clients default to the-smithy1/TheSmithy.

Example: Post a CI notification

curl -sf -X POST "$ARTURO_API_BASE_URL/api/v1/notify" \
  -H "Authorization: Bearer $ARTURO_INTERNAL_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"text": "dev-cd #142 deploy succeeded", "level": "success"}'

Response:

{
  "ok": true,
  "data": {
    "ts": "1717.001",
    "channel": "#build-alerts"
  }
}

To post to a specific channel instead of the default:

curl -sf -X POST "$ARTURO_API_BASE_URL/api/v1/notify" \
  -H "Authorization: Bearer $ARTURO_INTERNAL_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"text": "rollback initiated", "channel": "#incidents", "level": "warning"}'

Feature Repositories

  • arturo → project_id: the-smithy1/agents/arturo

Code Paths to Explore

  • tests/test_quest_service.py in arturo
  • src/api/router.py in arturo
  • src/handlers/quest_command_handler.py in arturo
  • src/services/quest_completion_service.py in arturo
  • src/services/quest_service.py in arturo
  • src/services/feedback_service.py in arturo

Feature Repositories

  • arturo → project_id: the-smithy1/agents/arturo

Code Paths to Explore

  • tests/test_quest_service.py in arturo
  • src/api/router.py in arturo
  • src/handlers/quest_command_handler.py in arturo
  • src/services/quest_completion_service.py in arturo
  • src/services/quest_service.py in arturo