Read this file first when working on program-intro-sync.
This repo is a standalone Cloudflare Worker service that monitors external program-description sources and stores change events in Cloudflare D1.
The current task boundary is data monitoring only:
- fetch OpenSIST program metadata and current descriptions
- fetch external GitHub Markdown sources
- normalize and hash source docs
- deterministically match source docs to OpenSIST
ProgramID - write source state, matches, runs, and change events to D1
Do not add LLM merge, backend mutation, backend publishing, or UI work unless the user explicitly asks for that next phase.
-
docs/current-status-summary.md- Concise snapshot of current deployment, D1 state, LLM evaluation, and next fix.
-
docs/memory/project-memory.md- Persistent project context, decisions, current state, known limitations, and next work.
-
README.md- Setup, commands, endpoint list, and documentation map.
-
docs/architecture.md- System boundaries and module responsibilities.
-
docs/description-monitor.md- Monitor scope, event types, idempotency, and admin API shape.
-
docs/data-model.md- D1 schema and runtime data shapes.
-
docs/security-and-config.md- Secrets, logging, license handling, and config rules.
-
src/types.ts- Shared TypeScript contracts.
-
src/pipeline/monitor.ts- Main runtime flow. Most behavioral changes start here.
-
src/db/repository.ts
- D1 access layer. Keep SQL and schema changes consistent with migrations/docs.
- Relevant module for the requested change:
src/opensist/client.tsfor OpenSIST API reads.src/sources/github.tsfor upstream GitHub scanning.src/matching/matcher.tsfor program matching.src/config/sources.tsfor source definitions.src/index.tsfor Worker routes, cron, and admin API.
Read docs/cloudflare-llm-research.md, docs/llm-summary-evaluation.md, and docs/llm-merge-policy.md only when the user asks about LLM summary or merge work.
Read docs/backend-publish-api.md when the user asks how approved drafts should reach the OpenSIST backend.
Cloudflare Worker:
- scheduled cron handler in
src/index.ts - manual admin trigger:
POST /admin/monitor/run - event inspection:
GET /admin/monitor/events?status=pending - event marking:
POST /admin/monitor/events/:id/acknowledgePOST /admin/monitor/events/:id/ignorePOST /admin/monitor/events/:id/consume
D1 is the only durable store.
Preserve these unless the user explicitly changes project direction:
- The monitor must not write to OpenSIST backend mutation APIs.
- The monitor must not call DeepSeek/Qwen/Workers AI.
- The monitor must not commit generated state or output files.
- Secrets must come from Cloudflare secrets or environment variables, never repo files.
- Do not store full external Markdown in D1 by default.
- All event insertion should be idempotent through deterministic
event_key. - A source document key is stable as
<source-name>:<source-path>. - D1 schema changes require a new migration and docs update.
Install dependencies:
npm installTypecheck:
npm run typecheckApply local D1 migrations:
npm run db:migrate:localRun local Worker:
npm run devApply remote D1 migrations:
npm run db:migrate:remoteDeploy:
npm run deploywrangler.jsonc contains non-secret config:
account_idOPENSIST_API_ROOTHIGH_CONFIDENCELOW_CONFIDENCE- D1 binding
- cron trigger
Current Cloudflare resources:
account_id = c1e0d935e0f8ba4685b9b6702130efe7
D1 database_name = program-intro-sync
D1 database_id = 3073eab7-e1f8-4e1e-b171-33740db9ad20
MAX_PROGRAM_UPSERTS_PER_RUN = 25
MAX_RAW_DOWNLOADS_PER_SOURCE = 1Expected secrets:
OPENSIST_COOKIEGITHUB_TOKENADMIN_TOKEN
Use:
wrangler secret put OPENSIST_COOKIE
wrangler secret put GITHUB_TOKEN
wrangler secret put ADMIN_TOKENRead:
src/config/sources.tssrc/sources/github.tsdocs/security-and-config.md
Then:
- update
SOURCE_CONFIGS - define content roots and excluded path parts
- set a clear
licenseLabel - update docs if source behavior or license policy changes
Read:
src/matching/matcher.tssrc/types.tsdocs/data-model.mddocs/memory/project-memory.md
Then:
- keep output as
ProgramMatch - keep confidence bands configurable through env vars
- add reasons for every meaningful score contribution
- prefer deterministic tests/fixtures before adding embeddings or LLM matching
Read:
migrations/0001_initial.sqlsrc/db/repository.tsdocs/data-model.md
Then:
- add a new migration file; do not edit already-applied migrations for deployed databases
- update repository methods and types
- update docs and memory if the change affects architecture or state semantics
- run
npm run typecheckandnpm run db:migrate:local
Read:
docs/cloudflare-llm-research.mddocs/llm-summary-evaluation.mddocs/llm-merge-policy.mddocs/backend-publish-api.mddocs/memory/project-memory.md
Then:
- implement it as a downstream consumer, not inside monitor core
- read pending D1 events
- write merge drafts to a new table
- keep backend publishing and manual review separate from draft generation
- never send secrets or raw provider prompts to logs
Read:
docs/llm-summary-evaluation.mdprompts/llm-summary-system.mdscripts/evaluate-llm-summary/index.mjs
Then:
- start with
npm run eval:llm-summary -- --dry-run --limit 2 - use
CLOUDFLARE_API_TOKENorCF_API_TOKENfor real AI calls - write only local ignored output files under
outputs/llm-summary-evals/ - do not write D1 rows or backend data
- update the prompt and evaluation doc when behavior changes
Read:
docs/backend-publish-api.mddocs/llm-merge-policy.mddocs/security-and-config.md
Then:
- publish only approved drafts
- use optimistic concurrency with the base description hash
- include source event IDs and attributions in the publish request
- keep publish credentials as Cloudflare secrets
- never let the monitor call backend mutation APIs
At minimum, run:
npm run typecheckIf SQL or D1 access changes, also run:
npm run db:migrate:localIf Worker routing changes, start local dev and test the relevant endpoint when the environment allows local port access.
During initial implementation:
wranglerinstalled as a dev dependency.compatibility_datewas set to2026-05-03because Wrangler 4.86.0 did not support2026-06-16.- Local D1 migration succeeded.
- Remote D1 database
program-intro-syncwas created and0001_initial.sqlwas applied. - Remote D1 table existence was verified through
sqlite_master. wrangler devreachedReady.- Curling the local dev port from another shell failed in the implementation environment, likely due to proxy/sandbox isolation.
Still pending:
- Optionally set
GITHUB_TOKENas a Worker secret if unauthenticated GitHub API limits become a problem. - Run manual monitor passes until first source ingestion catches up.
Already done:
ADMIN_TOKENwas generated locally, saved in ignored file.admin-token, and uploaded as a Worker secret.OPENSIST_COOKIEwas uploaded as a Worker secret for the MVP.- Worker was deployed and
/healthplus admin auth were verified. - A manual monitor run succeeded after the subrequest-limit fix.
Keep changes small and aligned with the current module boundaries.
When changing behavior:
- update code
- update docs
- update
docs/memory/project-memory.mdwhen a decision, limitation, or verified state changes - state clearly what was verified and what was not