# ocDRILL question authoring

Use this guide to create or revise an ocDRILL question set from the user's request. It contains the authoring guidance, complete Version 1 schema, and short examples. No app access or other reference files are required.

## What ocDRILL does

ocDRILL shows organic chemistry questions and supplied answers from a local JSON file. The learner solves each question outside the app. “Check Answer” reveals the supplied answer, and the learner assesses their own work. It does not grade chemistry.

Questions contain plain text, 2D molecules, visual blanks, and reaction arrows. RDKit draws molecules from SMILES only. All molecule names stay hidden until answer reveal, including names in question rows. The app does not compare names with SMILES, repair structures, or check reactions and answers.

Blanks accept no input. The format supports no images, curved mechanism arrows, Markdown, HTML, or LaTeX. Mechanism questions can request work on paper and supply text explanations. “Refer to LLM.” is ordinary answer text, not an integration.

## Design good questions

Match the requested topic, level, and count. Use supplied course material to guide content. If missing information prevents a sound question, ask a focused question. Otherwise, proceed with reasonable assumptions.

Keep prompts short, such as “Predict the product.”, “Define the reagents.”, or “Draw the intermediate.” Add only necessary conditions or constraints. Give each question a clear task that the learner can assess independently. Keep connected synthesis steps together. Split unrelated exercises into separate questions.

Vary the chemical decisions across the set, not just the structures. Use suitable combinations of product prediction, reagent selection, structure interpretation, synthesis, comparisons, and conceptual questions. Do not force variety that does not fit the topic.

Check for unintended hints:

- Do not name the mechanism or reaction rule that the learner must infer.
- Keep explanations and diagnostic clues in the answer, not the prompt, title, or annotations.
- Use neutral blank labels such as “Reagent:” or “1.”.
- Do not reveal a missing structure through visible names, product counts, or suggestive blank labels.
- Separate similar exercises so their shared pattern or an earlier answer does not solve the others.
- Do not group independent reactions under a heading that reveals their common solution method.
- Keep necessary reagents, solvent, workup, quantities, and stereochemical data.
- Do not depend on hidden molecule names to make a question solvable.

Necessary problem data are not hints. If the user requests hints or guided practice, provide that support. Otherwise, leave the choice of method to the learner.

For rankings, specify the property and relevant conditions. For synthesis, state the starting materials, target, and requested restrictions. For data interpretation, supply enough plain-text evidence to support the answer. Label invented observations as hypothetical. For error diagnosis, identify the proposed answer as a claim to assess. If the evidence permits several conclusions, do not demand a unique answer.

## Review the chemistry separately

Solve each question before you encode it. Then solve it again from the visible prompt without relying on the drafted answer. Compare the two results. A second reasoning pass reduces errors but does not prove correctness.

Check the chemistry relevant to each question:

- Trace the product atoms, carbon skeleton, and source of added or removed fragments.
- Check reactive sites, reagent compatibility, competing pathways, and functional groups.
- Check reagent amounts, order, solvent, and workup wherever they affect the result.
- Distinguish intermediates from final products after workup.
- Check regioselectivity, stereochemistry, rearrangements, and mixtures.
- Check each synthesis step against the actual intermediate from the preceding step.
- Check whether the conditions justify a major product, several products, or no reaction.
- Check explanations against the specific case rather than an assumed universal rule.
- Check the final written question and answer, not just the solution you intended.
- Double check what you have actually written and proposed is correct.

Resolve ambiguous conditions before delivery. If your answer remains uncertain, replace the example with a defensible question that tests the same objective. If the requested objective itself remains unresolved, disclose that limitation. Do not substitute “Refer to LLM.” for an answer you cannot support.

## Check SMILES and names

Read each SMILES back as a molecular graph without relying on its name. Trace branches, bond orders, ring closures, atom identities, valence, hydrogens, aromatic notation, and charges. Compare that graph with the intended structure. Then check that the name describes the same structure.

Check stereochemistry explicitly. Do not equate `@` or `@@` directly with R or S. Their meaning depends on neighbor order in the SMILES. Check alkene geometry where relevant. Do not label unspecified stereochemistry as a specific stereoisomer or represent one enantiomer as an entire racemic mixture. Supply the relevant structures or explain the mixture clearly in answer text.

If an encoding remains uncertain, choose another example without removing the learning objective. Check JSON escaping separately, especially SMILES backslashes. Neither valid JSON nor successful molecule depiction proves that the intended chemistry is correct.

## Construct the set

Use the schema in this document. Assign IDs by position: `q-001`, `q-002`, `q-003`, and onward. After an insertion, deletion, or reorder, renumber all affected IDs. Ordered IDs are an authoring convention here. The app itself requires only unique IDs.

Put problem data in `label` and `question`. Put solutions and explanations in `answer`. Give the direct answer first, followed by a short explanation. For multiple valid answers, supply a valid example and criteria for alternatives. Use “Refer to LLM.” only for requested external review.

## Complete Version 1 schema

### File, questions, and rows

The nesting is file → questions → question or answer rows → items. This fragment illustrates the structure. Its empty `items` arrays require content before use.

```json
{
  "version": 1,
  "title": "Set title",
  "questions": [{
    "id": "q-001",
    "label": "Predict the product.",
    "question": [{"items": []}],
    "answer": [{"items": []}]
  }]
}
```

| Field | Requirement |
| --- | --- |
| `version` | Required number equal to `1`. |
| `title` | Required nonempty string. |
| `questions` | Required array with at least one question. |
| `id` | Required nonempty, unique string. Use `q-001`, `q-002`, and onward in array order. |
| `label` | Required nonempty plain-text string. |
| `question`, `answer` | Required arrays with at least one row each. |
| `items` | Required array with at least one item in each row. |

Each question and row is an object. Each row shows items from left to right and scrolls horizontally when necessary. The app hides answer rows until answer reveal. The four permitted item types are `text`, `molecule`, `blank`, and `arrow`.

### Text item

```json
{"type": "text", "text": "Displayed text"}
```

`text` is a required string. Text is literal, with Unicode and newline support. Markdown, HTML, and LaTeX have no special meaning.

### Molecule item

```json
{"type": "molecule", "smiles": "CCCO", "name": "1-propanol", "size": "medium"}
```

Every molecule requires string fields `smiles` and `name`. Use nonempty values for both. The app draws the SMILES without comparing it with the name. An unreadable SMILES produces an error box, not rejection of the whole file.

`size` is optional and defaults to `medium`:

| Value | Approximate drawing dimensions |
| --- | --- |
| `small` | 160 × 120 pixels |
| `medium` | 240 × 180 pixels |
| `large` | 340 × 240 pixels |

### Blank item

```json
{"type": "blank", "size": "large", "label": ""}
```

`size` is optional: `short`, `medium`, or `large`, with `medium` as the default. `label` is an optional string. In a row, the blank is a dashed rectangle. In an arrow annotation, it is an answer line with the label immediately before it. Blanks are visual only.

### Arrow item and annotations

```json
{
  "type": "arrow",
  "direction": "right",
  "above": [
    {"type": "blank", "label": "1.", "size": "short"},
    {"type": "blank", "label": "2.", "size": "short"},
    {"type": "blank", "label": "3.", "size": "short"}
  ],
  "below": [{"type": "text", "text": "Conditions"}]
}
```

`direction` is optional: `right` or `equilibrium`, with `right` as the default. `above` and `below` are optional arrays that can be empty. Annotations support only `text` and `blank`, with the same fields as those items. Multiple annotations stack vertically in their supplied order. Three or more reagent blanks are supported.

### Layout choices

| Exercise | Question layout | Answer layout |
| --- | --- | --- |
| Draw a structure | Name in the prompt and a large blank. | Molecule. |
| Predict a product | Molecule, arrow with reagents, large blank. | Product molecule and explanation. |
| Define reagents | Starting molecule, arrow with annotation blanks, target molecule. | Reagent text with conditions. |
| Complete a sequence | Molecules or blanks separated by arrows. | Missing structures and reagents in corresponding order. |
| Concept or comparison | Text and any relevant molecules. | Text, with structures where useful. |
| Multiple valid answers | An explicit task with sufficient constraints. | One valid example with criteria, or labeled alternatives in separate rows. |
| External review | A fully specified question. | A text item containing `"Refer to LLM."`. |

Keep a connected reaction sequence in one row. Use separate rows for explanations and alternatives. Do not put solutions inside question blanks.

### JSON rules

Use double-quoted keys and strings. Omit optional fields instead of setting them to `null`. Use only the documented fields and exact enum values. Do not include comments, trailing commas, duplicate keys, or empty required arrays.

Encode line breaks as `\n` and literal double quotes as `\"`. Encode each SMILES backslash as `\\` in JSON. For example, the SMILES `F/C=C\F` becomes the JSON string `"F/C=C\\F"`. The parsed value must retain the intended chemical notation.

## Final checks and delivery

If Python execution is available and the user attached `validate_question_file.py`, run it against the generated JSON:

```bash
python3 validate_question_file.py set.json
```

Use the actual attachment and output locations. Do not simulate a code interpreter or invent execution results. If either the script or Python execution is unavailable, check the JSON manually against this schema.

The optional script uses only the Python standard library. It checks syntax, fields, types, nesting, enums, nonempty SMILES, and ordered IDs. It does not parse SMILES, compare names with structures, validate chemistry, or assess question quality.

Correct reported errors before delivery. After corrections, run the script again if available. Always do the separate chemistry review, even after the script passes. Do not claim chemical verification that did not occur.

Check the questions for hints and the answers for completeness. After revisions, check affected structures, names, conditions, explanations, and dependent steps again. Provide one UTF-8 `.json` file, or one complete JSON code block if file output is unavailable. Keep any requested review summary outside the JSON. Do not add import instructions.
