|
| 1 | +# Product brief: preview a support-ticket CSV import |
| 2 | + |
| 3 | +This is a fictional training project. A support coordinator wants to preview tickets |
| 4 | +from a CSV file before any later import is approved. In this round you write |
| 5 | +`intent.md` to instruct Claude how to implement that feature in a future round. |
| 6 | +**Do not implement the feature now. Change only `intent.md`.** |
| 7 | + |
| 8 | +The repository already has `src/tickets.mjs` and its tests. That code is the stable |
| 9 | +ticket representation. A future implementation may add only |
| 10 | +`src/import-tickets.mjs` and `tests/import-tickets.test.mjs`. It must not alter the |
| 11 | +existing ticket module, the grading workflow, or Claude's instruction loader. |
| 12 | +No UI, database, network calls, file writes or package dependencies are needed. |
| 13 | + |
| 14 | +The proposed preview takes CSV text and returns a result without changing any data: |
| 15 | + |
| 16 | +- Require a `title` column; an optional `priority` column is allowed. Reject other, |
| 17 | + missing, or duplicate column names and malformed rows with `unknown-column`. |
| 18 | +- Trim surrounding whitespace from values. Reject an empty title with `empty-title`. |
| 19 | +- Priorities are `low`, `normal`, `urgent`; missing or blank priority becomes `normal`. |
| 20 | + Reject anything else with `invalid-priority`. |
| 21 | +- Accept at most 100 data rows. Check this before validating row values; more rows |
| 22 | + produces `row-limit`. An empty CSV with no header produces `unknown-column`. |
| 23 | +- Respect CSV quoting (for example, a title containing a comma). |
| 24 | +- Success is `{"tickets":[{"title":"...","priority":"normal"}]}` in input order. |
| 25 | + Failure is `{"error":"error-code"}`. No partial success is returned. |
| 26 | +- Verification commands are `npm test` and `git diff --check`. |
| 27 | + |
| 28 | +## What to write |
| 29 | + |
| 30 | +Keep the six headings in `intent.md`: Goal, Scope, Constraints, Plan, Acceptance, |
| 31 | +and Verification. Under each, write at least 30 characters of useful, original prose. |
| 32 | +Explain the outcome, boundaries, implementation sequence, and observable completion |
| 33 | +checks. Tell Claude to ask before implementing or expanding scope. Avoid placeholders. |
| 34 | + |
| 35 | +Include exactly one fenced **json** block with this contract shape: |
| 36 | + |
| 37 | +```json |
| 38 | +{ |
| 39 | + "schema": 1, |
| 40 | + "change": "ticket-csv-preview", |
| 41 | + "allowed_changes": ["src/import-tickets.mjs", "tests/import-tickets.test.mjs"], |
| 42 | + "protected_paths": ["src/tickets.mjs", ".github/", "CLAUDE.md"], |
| 43 | + "non_goals": ["ui", "database", "network"], |
| 44 | + "requirements": { |
| 45 | + "columns": ["title", "priority"], |
| 46 | + "default_priority": "normal", |
| 47 | + "valid_priorities": ["low", "normal", "urgent"], |
| 48 | + "reject_unknown_columns": true, |
| 49 | + "reject_empty_title": true, |
| 50 | + "max_rows": 100, |
| 51 | + "side_effects": "preview-only" |
| 52 | + }, |
| 53 | + "verification": ["npm test", "git diff --check"], |
| 54 | + "approval": "ask-before-implementation", |
| 55 | + "acceptance_cases": [ |
| 56 | + { |
| 57 | + "csv": "title,priority\nPrinter issue,urgent\n", |
| 58 | + "expected": {"tickets":[{"title":"Printer issue","priority":"urgent"}]} |
| 59 | + } |
| 60 | + ] |
| 61 | +} |
| 62 | +``` |
| 63 | + |
| 64 | +The example contains only one case. Add correctly predicted cases covering all seven |
| 65 | +categories: valid explicit priority, default priority, a quoted title containing a |
| 66 | +comma, empty title, unknown column, invalid priority, and too many rows. You may use |
| 67 | +`"repeat": 101` on a one-data-row case to represent 101 copies without a long document. |
| 68 | +Otherwise omit `repeat`; the input is used once. All expected results must be correct. |
| 69 | +The JSON gives the checker objective facts to verify; the prose makes the document |
| 70 | +useful for a human and Claude. The JSON alone is not a complete intent document. |
| 71 | + |
| 72 | +## How the score works |
| 73 | + |
| 74 | +Twenty published checks are worth five points each (100 total): document structure, |
| 75 | +Claude import, scope and constraints, contract values, verification/approval, correct |
| 76 | +examples, and coverage of all seven categories. The trusted checker recomputes the |
| 77 | +example outputs; writing a desired score or asserting that examples pass has no effect. |
| 78 | + |
| 79 | +This is a deterministic contract score, not an AI judgment of writing quality. During |
| 80 | +the rehearsal, the facilitator will separately discuss clarity, contradictions, and |
| 81 | +whether Claude follows the intent. A machine score cannot certify those qualities. |
| 82 | + |
| 83 | +Only `intent.md` may change from the starter files. Changed scaffolding, symlinks, |
| 84 | +oversized input, invalid UTF-8 or an unreadable submission cannot earn an official |
| 85 | +passing result. No student code is executed by the checker. |
0 commit comments