본문으로 건너뛰기
cccskills
무료GitHub에 공개

scheduling

The cross-repo scheduling system (sch_* tables, matrx-scheduler). Use when touching features/scheduling/**, /schedules or /administration/scheduling, migrations/sch_*.sql, a scheduled agent, cron, trigger, lease, or claim, or debugging ghost tasks, missed fires, double-runs, or stuck claims.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

연동 도구Supabase
설치 방법 보기

포함된 파일(1)

  • SKILL.md8.2 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Scheduling

Cross-repo scheduling spine. Three live systems share four Supabase tables (sch_task, sch_agent_task, sch_trigger, sch_run):

  • matrx-frontend — control plane (this repo). Users create/observe.
  • aidream + matrx-scheduler — server-side executor.
  • matrx-extend (Chrome extension) — browser-context executor for context-match triggers.

Spec: docs/SCHEDULING.md. FEATURE doc: features/scheduling/FEATURE.md.


30-second mental model

sch_task           kind='agent' (today). Spine: title, surfaces[], next_due_at.
  ↳ sch_agent_task   1:1 extension: agent_id, prompt, variables, conversation_id.
sch_trigger        when it fires (one-shot, interval, cron, heartbeat, context-match, …). v1 = one trigger per task.
sch_run            each execution attempt. Lease via claim_token + claim_expires_at.

RLS: owner-or-is_super_admin() on all four tables. Service_role is NEVER used for user-initiated writes; admin pages use the regular browser client and rely on RLS for cross-user reads.

Atomicity: a partial unique index sch_run_unique_active_per_task forces at most one active run per task. Concurrent claimers lose the race to the index, not the application.

DB invariants: sch_task.next_due_at = MIN(sch_trigger.next_due_at) is maintained by trigger sch_trigger_cascade_next_due_at. Don't UPDATE sch_task.next_due_at directly — write to sch_trigger and let the cascade flow.


When to use this skill

  • Adding or modifying a sch_* migration.
  • Changing the trigger taxonomy or adding a new trigger type.
  • Building / fixing FE pages under /schedules or /administration/scheduling.
  • Editing the Python matrx-scheduler package or its router on aidream.
  • Wiring a new executor surface (e.g. a desktop app scanner).
  • Debugging "ghost tasks" (queued runs not getting picked up), missed fires, double-runs, stuck claims.

Where each thing lives

LayerFiles
DB migrationsmigrations/sch_*.sql
FE typesfeatures/scheduling/types.ts
FE Supabase façade (reads)features/scheduling/service/queries.ts — joined task reads + taskDetailToAgendaTask reshape + residual updateAgentTaskFields write (the one sch_agent_task field-patch HTTP doesn't cover yet). ONLY place that .from('sch_*').
FE HTTP client (writes + compute)features/scheduling/service/schedulerClient.ts — typed wrapper over aidream's /scheduler/* (16 endpoints): tasks/triggers/runs CRUD, cron validate, preview-fires, compute-next-due-at, scanner status. Primary path for all user-facing writes.
FE TS twin of next_duelib/scheduler-client/next-due.ts — used by CronForm and cron-tester for live-typing previews; also exported to non-HTTP clients (Chrome extension, edge functions).
FE Redux slicesfeatures/scheduling/redux/{tasks,runs}/
FE hooksfeatures/scheduling/hooks/ — useScheduledTasks (+ list realtime), useTaskDetail, useTaskRuns, useRunStream
FE list / detail / formfeatures/scheduling/components/{list,detail,form}/
User routesapp/(authenticated)/schedules/
Admin routesapp/(authenticated)/(admin-auth)/administration/scheduling/
Admin servicelib/services/scheduling-admin-service.ts (browser client + is_platform_admin() RLS)
Python packageaidream/packages/matrx-scheduler/matrx_scheduler/
Python routeraidream/aidream/api/routers/scheduling.py
Per-request supabase clientaidream/aidream/services/scheduling/per_request_client.py
matrx-ai bridgeaidream/aidream/services/scheduling/agent_runner_adapter.py
Capture emitteraidream/aidream/services/scheduling/capture_emitter.py

Non-negotiable rules

  1. NEVER call .from('sch_*') outside features/scheduling/service/queries.ts or lib/services/scheduling-admin-service.ts. The select shape needs to stay consistent; row→AgendaTask flattening lives in one place. New user-facing writes go through service/schedulerClient.ts — don't add parallel Supabase writes to queries.ts.
  2. NEVER use the aidream service_role supabase singleton in scheduling routes. Use make_user_supabase_client(jwt) so RLS binds to the caller.
  3. NEVER insert into sch_run directly from the FE. Use the sch_enqueue_manual_run(p_task_id) RPC — it stamps user_id from the task row, sets status='queued', and refuses to spoof other fields.
  4. NEVER UPDATE sch_task.next_due_at from application code. Write to sch_trigger.next_due_at; the DB trigger cascades.
  5. NEVER bypass the RLS gate by tightening is_super_admin() to is_platform_admin() (or vice-versa). The two tiers exist deliberately — scheduling uses is_super_admin() to match the route layout's requireSuperAdmin gate.

Common tasks

Add a new trigger type (e.g. event)

  1. Add to the TriggerType discriminated union in features/scheduling/types.ts and the Python models.py.
  2. Add the case to computeNextDueAt in lib/scheduler-client/next-due.ts (TS twin used by previews) AND compute_next_due_at in the Python next_due module (authoritative for writes).
  3. Add a subform component in features/scheduling/components/form/triggers/ and wire it in ScheduleForm.tsx.
  4. Add validation in features/scheduling/utils/validation.ts.
  5. Add a Jest + pytest case for the new type.
  6. Update the DB CHECK on sch_trigger.type if you're adding a brand-new value — the existing 8 values already cover everything in the spec.

Add a new executor surface (e.g. desktop)

  1. Add the value to:
    • the FE SURFACE_VALUES constant
    • the sch_task_surfaces_chk CHECK constraint (migration)
    • the SURFACE_META map for the picker tooltip
  2. In the new surface's code (e.g. Tauri desktop app), call matrx_scheduler.configure(surface="desktop", ...) and start_scanner(). Each surface has its own scanner; the partial unique index ensures no double-runs across surfaces.

Debug a "ghost task" (queued run that never executes)

  1. Confirm the row's surface value — manual fires set it to NULL so any surface can claim; if it's hardcoded to a value no executor is running on, it'll sit forever.
  2. Check sch_task.surfaces — does it contain 'any' or a value that matches an online scanner?
  3. Check the scanner status: GET /scheduler/status (admin only), or the FE admin page at /administration/scheduling/scanner-health.
  4. Confirm AIDREAM_SCHEDULER=1 is set on the host process you expect to execute the run.

Debug a "stuck claimed" run

  1. Visit /administration/scheduling/orphan-leases.
  2. The scanner sweeps any status IN (claimed,running) AND claim_expires_at < now() to failed on every tick — if a row sits in claimed for >60s after expiry, something's broken upstream.
  3. Manual remediation: use the page's "Mark failed" button (RPC-less, direct UPDATE — gated by RLS owner-or-super-admin).

Verification

After changes, always:

  • Python: uv run pytest packages/matrx-scheduler/tests (25 tests, must all pass).
  • TypeScript: pnpm exec jest features/scheduling/utils/__tests__/ (triggerHumanize + validation).
  • Type check: pnpm tsc --noEmit clean across the feature.
  • Smoke: create a schedule via the form, confirm it lands in all 3 tables (use Supabase MCP execute_sql to inspect).
  • For Python execution changes: enable AIDREAM_SCHEDULER=1, create an interval task on surfaces=['server'], watch logs for "scheduler.run requested" and the resulting sch_run row transition.

Related skills

  • protected-resources — scheduling is NOT a protected resource (no audit log, no SECURITY DEFINER mutation gate), but if scheduling ever grows admin-level operations that warrant audit, follow that pattern.
  • connect-matrx-extend — relevant when adding context-match UX or cross-repo run-pickup support.
  • window-panels — for future "Quick Schedule" overlay (v1.5).

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Admin debug system wiring for the floating AdminIndicator's live debug data and Copy Full Context. Use when adding debug visibility to a route or feature, wiring useDebugContext or the debug panel, capturing console errors, or enabling the copy-context workflow for a page.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

armanisadeghi/ai-matrx32026년 10월 19일 업데이트

Compact two-icon Copy / Copy-for-AI controls (components/agent-copy). Use when adding copy buttons to a row, card, list, or record; merging duplicate Copy/JSON/AI controls; continuing the copy rollout; or writing a Copy-for-AI payload. NOT for markdown content actions (use rich-document-actions).

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

armanisadeghi/ai-matrx32026년 10월 19일 업데이트

Disclosing a surface's existing fixed AI jobs in the shell's top Agents menu. Use when a page, panel, overlay, or window already runs a mandate behind a button, assist, automatic action, or mode; when the agent-disclosure guard names a file; or during a surface check.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

armanisadeghi/ai-matrx32026년 10월 19일 업데이트

The watch-fix-rerun method for making an existing platform agent or automated process efficient and correct: baseline its ledger, run one unit yourself, fix the class behind every wasted call, rerun, record. Use when asked to improve, optimize, watch, or 'make efficient' an agent, a sandbox session, a sync job, or any recurring automated process.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

armanisadeghi/ai-matrx32026년 10월 19일 업데이트

Redux state for agent execution and firing agent shortcuts. Use when editing features/agents/redux/, building agent UI, creating a conversation, touching assembleRequest or NDJSON stream state, wiring agent-state selectors, adding a per-conversation capability, or triggering a shortcut from a button, menu, or code (useShortcutTrigger, launchAgentExecution).

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

armanisadeghi/ai-matrx32026년 10월 19일 업데이트

The provision for a call site: the exhaustive menu of values that place in the code can realistically produce. Use before creating or fixing a mandate or agent that reasons about more than its own input, when deciding whether an agent can answer at all with what it is sent, or when its output 'looks right' but nobody checked it could be. NOT for building the agent (use create-agent).

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

armanisadeghi/ai-matrx32026년 10월 19일 업데이트

armanisadeghi의 스킬 모두 보기

이 스킬의 문제 신고