Imported from cbcgb-com/sgbs-training (
AGENTS.md). Install upstream withnpx skills add cbcgb-com/sgbs-training. Copyright stays with the author.
Notes for AI
Every change MUST be self-coherent with existing content. Flag any contradictions or confusing content to me. Update AGENTS.md if needed.
Audience & Purpose
Target: Bible study leaders at City Light church (Boston), affiliated with Chinese Bible Church of Greater Boston. Content is non-denominational Sunday school material for training leaders in:
- Inductive Bible Study method (narrative & argumentative styles)
- Leading Bible study fellowship gatherings
Language: Traditional Chinese (繁體中文), respectful tone for adult learners at different experience levels.
Content Standards
Structure & Format
- Clear learning objectives at lesson start
- Specific, actionable homework (honor system)
- Discussion questions use
???format - Include reflection/application sections
- Work for both live teaching and standalone reference
- Avoid duplication within files unless for emphasis
Writing Guidelines
- Balance academic rigor with practical accessibility
- Include cultural context for biblical passages
- Address language barriers with clear theological explanations
- Prioritize Chinese-language resources with working URLs
- Flag denominationally partisan resources
Formatting
- Avoid
- **text**: descriptionformat - Prefer: bullet lists, prose, or tables
- Avoid "why" questions (use specific formats instead)
Content quizzes (.content-quiz)
Shared vanilla HTML/JS pattern (docs/javascripts/content-quiz.js, wired in
mkdocs.yml) for MCQs in class notes. One module, two modes via data-mode:
-
Modular authoring (Lesson 2+): keep each quiz bank in
docs/quizzes/lesson-N/<slug>.html(standalone page: quiz markup + quiz JS/CSS). In the lesson markdown, embed with a borderless iframe—no inline quiz HTML:<iframe class="content-quiz-frame" src="../../quizzes/lesson-2/reflect.html" title="…" loading="lazy" scrolling="no"></iframe>Parent pages load
content-quiz-frame.js+content-quiz-embed.css; the iframe reports height viapostMessageso the frame fits content with no scrollbars. Copy an existingdocs/quizzes/lesson-2/*.htmlshell when adding a new bank. -
Markup:
.content-quiz>.content-quiz__itemwith choices + per-choice.content-quiz__reflection(data-choice="0"…) -
Author a full question bank in the quiz HTML file; JS randomly samples
data-sample-sizeitems (default 3), shuffles each item's option order (and relabels A/B/C…), then presents questions one-at-a-time with 上一題/下一題 flip-through. Keepdata-correct/data-choiceon the authored option indices; only presentation order is random. -
Course convention (2026-09): two question categories. 課前思考題 (reflect) banks hold 10 items with
data-sample-size="3"— each visit samples 3, in randomized question and option order; no correct answers, nodata-pass-correct; every option is partially-right with no winner, and each reflection leaves something worth thinking about. All other MCQ banks hold 10 items withdata-sample-size="10"(all shown, random order) anddata-pass-correct="4"(quiz ends early with 「練習完成!」 once 4 items are answered correctly). Review distractors must each expose a specific student misconception; the selected option's feedback names and corrects that misconception. Option subtlety bar: the correct answer must not be identifiable by style — keep all four options similar in length and register; no strawmen or dismissive tone (「跳過就好」「只是…無關」「是組員不夠認真」) — every distractor carries a true-sounding core with a subtle flaw (wrong scope, right conclusion wrong reason, half-true, plausible-but-arranges-the-wrong-thing); don't echo the lesson's key phrase only in the correct option; don't telegraph the answer in the stem. Vary question types within each bank — never ask the same format ten times; rotate through archetypes (forward scenario→answer, reverse intent-inference, best-fix/rewording, odd-one-out, misfire diagnosis, prevention diagnosis, definition matching, sequencing, classification, spot-the-misclassification, which-is-NOT, evidence-matching). Quiz intro lines are one short, warm invitation to attempt the quiz — 「讀完第一部分了嗎?用下面的複習題測試一下自己,看看掌握了多少。」 — keeping only load-bearing functional clauses (the pass rule, or 「步驟一已替你準備」); no misconception previews, no mechanics, no describing the feedback system. Authoring guide & verification procedure:.agents/skills/sgbs-quiz-authoring/SKILL.md. -
Stems avoid bare「為什麼」; prefer「怎樣/哪一種/最需要小心的是」等具體框架
-
Traditional Chinese; keep tone respectful for adult learners
-
Update the lesson TOC when adding a quiz section
data-mode="reflect" (課前思考題): place immediately above the first
pre-reading subsection (e.g. before「分析敘述文」). No correct answer; every
option gets a soft「值得思考」note that primes the reader for the section ahead.
Questions should be thought-provoking, with plausible distractors and no
obvious winner.
data-mode="review" (預讀複習題): place at the end of 第一部分, right
before「第二部分:課堂實作活動」. Comprehension check on section content. Each
.content-quiz__item needs data-correct="0"-based index; wrong/right choices
are marked, and the selected option’s reflection explains using「答對了」/
「再看一下」. Always four options (A–D) per item: the three distractors
should each name a plausible learner misconception (e.g. skipping to
application, mistaking one OEIA step for another, treating background as the
whole message), and each wrong option’s reflection should briefly illuminate
why that path misleads—not just say「錯了」.
Inline mini-checks (also data-mode="review") may sit mid-section after a
framework interactive; keep the bank small (data-sample-size="2") and tightly
tied to the just-taught idea. Same four-option / misconception rule as
section-end review quizzes.
Content panels (.content-panels)
Shared vanilla HTML/JS pattern (docs/javascripts/content-panels.js, wired in
mkdocs.yml) for chip/tab + one-panel reveals. Use when a framework would
otherwise become a wall of prose (e.g. 三要素、OEIA 焦點).
- Markup:
.content-panels> optional.content-panels__intro+ two or more.content-panels__panelwithdata-label="…" - Optional
data-labelon the root names the tablist for accessibility - Optional
data-style="steps"numbers the tabs for sequences (觀察 → 解釋 → 歸納 → 應用) - Prefer short bullets + one
.content-panels__examplecallout per panel - Traditional Chinese; teach one lens at a time, don’t dump all panels as prose
- Inductive method acronym in this course is OEIA: 觀察(Observation)、 解釋(Explanation)、歸納(Induction)、應用(Application). Do not collapse into OIA, and do not gloss 歸納 as Interpretation.
Scripture quotations (/// scripture shortcode)
Quoted Bible passages MUST use the custom scripture Markdown block
(sgbs_training/mdx_scripture.py, enabled in mkdocs.yml as
sgbs_training.mdx_scripture) instead of hand-written HTML, so scripture
renders consistently everywhere:
/// scripture | 馬太福音28章16-20節
十一個門徒往加利利去,到了耶穌約定的山上……
///
- One block per passage; the reference goes in the argument after
|; verse text is a plain paragraph, copied verbatim. - Renders
<blockquote class="scripture">with ap.scripture__reffollowed by verse paragraphs; styled once, site-wide, as the 引文箋 paper slip indocs/stylesheets/extra.css(light/dark via the--sgbs-*tokens). - Inside raw-HTML containers (e.g.
expandable-card__body), addmarkdown="1"to the wrapping div and to every raw-HTML ancestor up to the top of the HTML block (expandable-card,expandable-cards) — md_in_html never processes a marked element buried inside unmarked raw HTML — and keep a blank line between the div edge and each block.
Content decks (.content-deck)
Shared vanilla HTML/JS pattern (docs/javascripts/content-deck.js, wired in
mkdocs.yml) for quiz-style paginated cards: one card at a time with
上一張/下一張. Use for typed inventories that should be browsed, not tabulated
(e.g. 作者可能想要傳達的信息類型).
- Markup:
.content-deck> optional.content-deck__intro+ two or more.content-deck__cardwithdata-label="…" - Optional
data-labelon the root names the region for accessibility - Optional
data-index="true"shows chip tabs for all carddata-labelvalues above the stage; highlights the active card and supports jump - Optional
data-nav="false"hides 上一張/下一張 (use withdata-indexfor chip-only navigation, e.g. 文學工具) - Prefer short prompt + one
.content-deck__examplecallout per card - Shows the full set in authored order (no random sampling)
- Traditional Chinese; keep each card scannable on its own
Activity timeline (.content-timeline)
CSS-only vertical timeline for in-class workshop flows (dots + connecting
line). Styles in docs/stylesheets/extra.css; no extra JS.
- Markup:
.content-timeline> one or more.content-timeline__item, each with.content-timeline__track(.content-timeline__dot+ optional.content-timeline__line) and.content-timeline__card - Optional
.content-timeline__item--tipfor mid-flow reminders (dashed card) - Inside the card: optional
.content-timeline__meta>.content-timeline__duration, then.content-timeline__title, then bullets or short prose - Omit
.content-timeline__lineon the last item - Set
aria-labelon the root; usearia-hidden="true"on the track column
Course Structure
Flipped classroom: Students read beforehand, class focuses on interactive activities and practical application. First 30 minutes = mock Bible study practice.
Roles:
- 主領 (Leader): Facilitates mock Bible study
- 觀察員 (Observer): Provides feedback to leader
- 其他人 (Others): Participants
Assessment: 4/5 sessions required. Honor system homework. Peer-to-peer feedback. Focus on practical application over formal evaluation.
Homework Policy: Always prepares for next lesson, never reinforces current lesson. Lesson 5 has no homework.
Quality Checklist
- Accurate Scripture references
- Consistent Chinese terminology
- Clear, measurable learning objectives
- Relevant practical examples
- Aligns with inductive Bible study methodology
- No denominational bias
- Cultural sensitivity maintained
- Accurate cross-references
Technical Standards
Markdown Linting
ALWAYS run markdownlint filename.md on ANY markdown file you edit. Fix ALL
violations (not just new ones).
pixi global install markdownlint-cli
Raw HTML Exception: Ignore MD033 issues - HTML is present for good reasons (e.g., visual formatting for grammatical analysis).
MkDocs Sub-bullet Indentation: Use 4 spaces for sub-bullet points in TOC lists
so MkDocs properly renders them as nested items. The project includes a
.markdownlint.json configuration file that sets MD007 to expect 4 spaces,
eliminating markdownlint warnings while maintaining proper MkDocs rendering.
Notebooks
Use marimo notebooks for new development. Don't edit existing .ipynb files (legacy).
Email Generator App
FastAPI + HTMX + shadcn/ui application for personalized homework emails.
Tech Stack: FastAPI, Jinja2, HTMX, Tailwind CSS, shadcn/ui, Modal.com deployment, Google Drive API
Key Files:
apps/api.py- Main FastAPI routesapps/templates/template.html- HTMX interfacesgbs_training/email.py- Email compositionsgbs_training/docs.py- Google Docs generationsgbs_training/exercises.py- Question/note templatessgbs_training/scriptures.py- Scripture classes
Flow: User selects scripture → Form submission → Google Docs creation → Email composition → HTMX preview update
Class emails (weekly homework, Saturday reminder, reinvitation):
compose from sgbs_training/email.py. Homework Google Docs
(查經題目 / 查經筆記) come from create_exercises() in
sgbs_training/docs.py. Recipients: homework:classEmailList (current
term, not withdrawn, has email). Agents save drafts from Eric's HEY
account and never send. Ops map:
.agents/skills/sgbs-email/SKILL.md; procedures in
.agents/skills/sgbs-email/references/.
Roster App
Self-hosted replacement for the Airtable 小组查经训练主日学 base (table 学员名单 + registration form). Live at https://sgbs-training.citylight.life.
Tech Stack: Vite, React, Tailwind CSS (V4), Convex backend; frontend on
Vercel (project sgbs-roster), data in Convex (prod abundant-dodo-507).
Auth is self-hosted passwordless (no identity vendor): registration
verifies email via a 6-digit code (Gmail SMTP, no-reply-com@cbcgb.org);
sign-in is an email lookup;
sessions are app-issued ES256 JWTs (AUTH_PRIVATE_KEY Convex env var).
See apps/roster/docs/designs/authentication/LLD.md.
Key Files:
apps/roster/- App root (independent npm project)apps/roster/convex/auth.ts- Passwordless auth: code request/verify, session-JWT issuance, sign-outapps/roster/convex/authEmail.ts- Verification-code email sending (node action; Gmail SMTP via nodemailer;SMTP_USER/SMTP_PASSenv vars)apps/roster/convex/auth.config.ts- Convex customJwt provider (public JWK embedded as a data URI)apps/roster/scripts/make-auth-keys.py- Generates the ES256 keypair (private key → Convex env var; public JWKS → auth.config.ts)apps/roster/convex/schema.ts-studentstable (ASCII field names; UI keeps Chinese labels) +authCodes/authSessionsauth tablesapps/roster/convex/students.ts- View queries (12 Airtable views) +registerStudent(instructor-managed) + role gates + 退出報名 withdrawal (manualwithdrawnAtplus, from 2026秋季, derived two-miss status; self-service, instructor on-behalf, undo, and re-registration reactivation of manual withdrawal only; seeapps/roster/docs/designs/withdrawal/LLD.mdandapps/roster/src/attendanceStatus.ts)apps/roster/src/withdrawal.ts- Shared withdrawal UI helpers (reason value, date formatting)apps/roster/src/auth/- Sign-in sheet, code-entry step, session storeapps/roster/src/Form.tsx- Reimplementation of the Airtable registration form (shrS5gKu57LudKDSh)apps/roster/src/MyProfile.tsx- Student self-service profile 我的資料 (view/update own record + photo, 退出本季課程 withdrawal)apps/roster/src/Roster.tsx- Grid + kanban view browser (incl. the 已退出 withdrawal view and 標記退出 control)apps/roster/src/Attendance.tsx- Instructor attendance sheet 出席 (per-date recording, default grouped by 小組, 未記錄全部出席 bulk fill; seeapps/roster/docs/designs/attendance/LLD.md)apps/roster/convex/homework.ts- 功課記錄: homework tracking parallel to attendance — internal agent-written mutations (recordHomeworkupsert vianpx convex run,clearHomework), agent roster lookup, instructor-gated marks read; read UI in the 課堂安排 按週次 layout (seeapps/roster/docs/designs/homework/LLD.md)apps/roster/scripts/test-homework.mjs- End-to-end homework suite (drives thenpx convex runagent entry point against a dev Convex deployment)apps/roster/scripts/test-withdrawal.mjs- End-to-end withdrawal suite (runs against a dev Convex deployment)apps/roster/scripts/test-attendance.mjs- End-to-end attendance recording suite (runs against a dev Convex deployment)airtable_dump/- Airtable dump/transform/seed pipeline (seeapps/roster/README.mdfor the full re-import procedure)
Agent Rules
- End every announced action with its tool call in the SAME turn — never end a turn on 'Re-running X next:' verification prose
