Spec driven development setup
This commit is contained in:
12
AGENTS.md
Normal file
12
AGENTS.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# Project skills and specifications
|
||||||
|
|
||||||
|
- Project skills are stored in `skills/`; specifications belong in `specs/`.
|
||||||
|
- Use `grill-me` only when the user explicitly requests it, for example
|
||||||
|
`Use grill-me to review this plan` or `Gebruik grill-me voor dit ontwerp`.
|
||||||
|
- Before using it, read `skills/grill-me/SKILL.md` and its dependency
|
||||||
|
`skills/grilling/SKILL.md`. If no dedicated Skill tool is available, load these
|
||||||
|
files directly and follow their instructions within the available tools.
|
||||||
|
- Installing or mentioning a skill does not start an interview. Do not apply
|
||||||
|
`grilling` automatically to ordinary development requests.
|
||||||
|
- Keep the upstream skill files unchanged. Source revision and license are
|
||||||
|
recorded in `skills/upstream.json` and `skills/LICENSE.mattpocock`.
|
||||||
21
skills/LICENSE.mattpocock
Normal file
21
skills/LICENSE.mattpocock
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 Matt Pocock
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
22
skills/README.md
Normal file
22
skills/README.md
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# Project skills
|
||||||
|
|
||||||
|
Reusable agent instructions for this repository. Invoke them explicitly in the
|
||||||
|
conversation, for example:
|
||||||
|
|
||||||
|
> Gebruik grill-me om de JSON-import en -export met mij uit te werken.
|
||||||
|
|
||||||
|
## Installed skills
|
||||||
|
|
||||||
|
| Skill | Purpose |
|
||||||
|
| --- | --- |
|
||||||
|
| [grill-me](grill-me/SKILL.md) | Entry point for reviewing a plan or design through questions. |
|
||||||
|
| [grilling](grilling/SKILL.md) | Interview instructions required by `grill-me`. |
|
||||||
|
|
||||||
|
The skills are copied from [Matt Pocock's skills.sh listing](https://skills.sh/mattpocock/skills/grill-me)
|
||||||
|
and its [upstream repository](https://github.com/mattpocock/skills).
|
||||||
|
The exact upstream commit and paths are recorded in [upstream.json](upstream.json).
|
||||||
|
The upstream [MIT license](LICENSE.mattpocock) is included.
|
||||||
|
|
||||||
|
These project-local files are available to the agent from the next conversation
|
||||||
|
turn through the instructions in the root `AGENTS.md`. They are not installed
|
||||||
|
globally. Updating them requires explicitly downloading a new upstream revision.
|
||||||
7
skills/grill-me/SKILL.md
Normal file
7
skills/grill-me/SKILL.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
name: grill-me
|
||||||
|
description: A relentless interview to sharpen a plan or design.
|
||||||
|
disable-model-invocation: true
|
||||||
|
---
|
||||||
|
|
||||||
|
Call the Skill tool with "grilling".
|
||||||
5
skills/grill-me/agents/openai.yaml
Normal file
5
skills/grill-me/agents/openai.yaml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Grill Me"
|
||||||
|
short_description: "Sharpen a plan through interview"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
30
skills/grilling/SKILL.md
Normal file
30
skills/grilling/SKILL.md
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
name: grilling
|
||||||
|
description: Grill the user relentlessly about a plan, decision, or idea. Use when the user wants to stress-test their thinking, or uses any 'grill' trigger phrases.
|
||||||
|
---
|
||||||
|
|
||||||
|
Interview the user relentlessly until you reach a shared understanding. Map this as a **design tree**: every decision branches into the decisions that hang off it.
|
||||||
|
|
||||||
|
Work the tree in **rounds**. The **frontier** is every decision whose prerequisites are already settled: the questions you can ask _now_ without guessing at answers you haven't heard yet. Ask the whole frontier in one round: number each question and give your recommended answer. Then wait for the user's answers before the next round.
|
||||||
|
|
||||||
|
Format a round like so:
|
||||||
|
|
||||||
|
```
|
||||||
|
❓ **Q1** - **<question title>**: <question body, might be multiple paragraphs, including multiple choices>
|
||||||
|
|
||||||
|
➡️ <your recommended answer>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
❓ **Q2** - **<question title>**: <question body, might be multiple paragraphs, including multiple choices>
|
||||||
|
|
||||||
|
➡️ <your recommended answer>
|
||||||
|
```
|
||||||
|
|
||||||
|
Word each question so "yes" accepts your recommended answer.
|
||||||
|
|
||||||
|
Each round the user answers reshapes the tree: settled decisions push the frontier outward and unblock questions that depended on them. Recompute the frontier and ask the next round. A question whose answer depends on another question still open in this round belongs to a _later_ round, not this one.
|
||||||
|
|
||||||
|
Finding _facts_ is your job, never the user's. When a frontier question needs a fact from the environment (filesystem, tools, etc.), dispatch a sub-agent to find it; don't ask the user for anything you could look up yourself. Don't block on it: a running exploration is an unsettled prerequisite, so only the questions downstream of it wait for the sub-agent to report; ask the rest of the frontier now. The _decisions_ are the user's: put each to them and wait.
|
||||||
|
|
||||||
|
The session is done when the frontier is empty: every branch of the design tree visited, nothing left silently assumed. Do not act on it until the user confirms you have reached a shared understanding.
|
||||||
3
skills/grilling/agents/openai.yaml
Normal file
3
skills/grilling/agents/openai.yaml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Grilling"
|
||||||
|
short_description: "Stress-test thinking a round of questions at a time"
|
||||||
9
skills/upstream.json
Normal file
9
skills/upstream.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"repository": "https://github.com/mattpocock/skills",
|
||||||
|
"commit": "59db609eb1e18aaf59b63284d0e52255aff0c63c",
|
||||||
|
"source": "https://skills.sh/mattpocock/skills/grill-me",
|
||||||
|
"skills": {
|
||||||
|
"grill-me": "skills/productivity/grill-me",
|
||||||
|
"grilling": "skills/productivity/grilling"
|
||||||
|
}
|
||||||
|
}
|
||||||
4
specs/README.md
Normal file
4
specs/README.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# Specifications
|
||||||
|
|
||||||
|
Store feature specifications, requirements and agreed design decisions here.
|
||||||
|
Use descriptive Markdown filenames, for example `school-json-import-export.md`.
|
||||||
160
specs/S1_School-JSON-import-export.md
Normal file
160
specs/S1_School-JSON-import-export.md
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
# S1 — School JSON import and export
|
||||||
|
|
||||||
|
Status: agreed after the grill-me review.
|
||||||
|
|
||||||
|
## User story
|
||||||
|
|
||||||
|
**As** a school maintainer,
|
||||||
|
**I want** to export and import my dance school as a JSON file,
|
||||||
|
**so that** I can store my school configuration locally while the application does
|
||||||
|
not offer persistent storage,
|
||||||
|
**and so that** I retain ownership of my data.
|
||||||
|
|
||||||
|
## Intent
|
||||||
|
|
||||||
|
Export downloads a complete snapshot of one dance school to a local JSON file.
|
||||||
|
Import restores that snapshot as a new school or replaces the corresponding
|
||||||
|
existing school after explicit confirmation.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
### In scope
|
||||||
|
|
||||||
|
- Exporting an existing school to a readable JSON file.
|
||||||
|
- Importing a school that does not exist or no longer exists.
|
||||||
|
- Replacing an existing school with the complete imported snapshot.
|
||||||
|
- Preserving all configured school data and relationships, including:
|
||||||
|
- School details and its persistent unique key.
|
||||||
|
- Dancers and their details.
|
||||||
|
- Dance groups, types, age ranges and styles.
|
||||||
|
- Dancer memberships, including dancers belonging to multiple groups.
|
||||||
|
- Shows, dates, day parts and any existing group assignments to day parts.
|
||||||
|
- Coaches and any existing links between coaches and groups.
|
||||||
|
- Full validation, an import preview, confirmation and clear error messages.
|
||||||
|
|
||||||
|
Preserving existing data does not add management screens for coaches or the
|
||||||
|
ability to assign groups to show day parts.
|
||||||
|
|
||||||
|
### Out of scope
|
||||||
|
|
||||||
|
- Merging an imported snapshot with an existing school.
|
||||||
|
- Persistent server-side storage.
|
||||||
|
|
||||||
|
The existing-school prompt includes a merge option, but selecting it only displays
|
||||||
|
that merging is not yet supported. It must not change any data. Implementing merge
|
||||||
|
behavior requires a separate specification.
|
||||||
|
|
||||||
|
## Identity and file format
|
||||||
|
|
||||||
|
- Every school has a persistent unique key that is included in exports and
|
||||||
|
preserved through imports and subsequent exports.
|
||||||
|
- Import identifies an existing school by that key, not by its name or a
|
||||||
|
runtime-generated numeric ID. The key remains meaningful after a server restart.
|
||||||
|
- A school with the same name but a different unique key is a separate school.
|
||||||
|
- A file contains one school and all data needed to restore it without accessing
|
||||||
|
another school or the original server state.
|
||||||
|
- The readable, documented JSON format includes a `formatVersion` field.
|
||||||
|
- Users may edit the JSON manually. Edited files undergo the same validation as
|
||||||
|
files produced by the application.
|
||||||
|
- Unknown fields and unsupported format versions are rejected explicitly; data
|
||||||
|
must not be silently ignored.
|
||||||
|
- Relationships in the file must be unambiguous and restored correctly. Internal
|
||||||
|
numeric IDs need not remain identical, provided school identity and all
|
||||||
|
relationships are preserved without collisions with other schools.
|
||||||
|
|
||||||
|
## Export flow
|
||||||
|
|
||||||
|
1. The maintainer opens an existing school's management screen.
|
||||||
|
2. The maintainer selects the JSON export option.
|
||||||
|
3. The application downloads a JSON file containing a consistent, complete
|
||||||
|
snapshot of that school.
|
||||||
|
4. Export does not change the school or any other application data.
|
||||||
|
|
||||||
|
## Import flow
|
||||||
|
|
||||||
|
1. The maintainer selects the JSON import option and chooses a local file.
|
||||||
|
2. The application validates the entire file before changing any stored data.
|
||||||
|
3. For a valid file, the application shows a preview containing the school name
|
||||||
|
and the numbers of dancers, dance groups and shows.
|
||||||
|
4. If the unique school key is unknown, the maintainer confirms adding the school
|
||||||
|
or cancels the import.
|
||||||
|
5. If the key already exists, the application identifies the school that would be
|
||||||
|
replaced and offers replace, merge or cancel:
|
||||||
|
- **Replace:** explicitly warn that the existing school is replaced completely.
|
||||||
|
After confirmation, replace all its configured data with the snapshot.
|
||||||
|
- **Merge:** show a message that this functionality is not yet supported and
|
||||||
|
leave all data unchanged.
|
||||||
|
- **Cancel:** leave all data unchanged.
|
||||||
|
6. A confirmed import is committed as one operation. The application must not
|
||||||
|
expose a partially imported or partially replaced school.
|
||||||
|
7. If validation or importing fails, show **"Import niet gelukt"** together with
|
||||||
|
the concrete cause. The user can correct the file and try again.
|
||||||
|
|
||||||
|
## Validation and failure behavior
|
||||||
|
|
||||||
|
- Validate JSON syntax, the supported file structure and format version, required
|
||||||
|
data, field values and all relationships before applying the import.
|
||||||
|
- Reject unknown fields and references to missing objects, including a group's
|
||||||
|
reference to a dancer absent from the snapshot.
|
||||||
|
- A failure must not create a partial school, partially replace an existing
|
||||||
|
school, or modify another school.
|
||||||
|
- A replacement must not remove the original school until the complete
|
||||||
|
replacement can succeed. If it fails, the original school remains intact.
|
||||||
|
- Error messages explain the cause specifically enough to correct the file.
|
||||||
|
For example: **"Import niet gelukt: groep Hiphop verwijst naar een onbekende
|
||||||
|
danser."**
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
|
||||||
|
### Export
|
||||||
|
|
||||||
|
1. Each existing school offers a JSON-file export that can be downloaded and
|
||||||
|
stored locally.
|
||||||
|
2. The export includes its persistent unique key, `formatVersion`, all configured
|
||||||
|
data listed in scope and all relationships between those objects.
|
||||||
|
3. Exporting leaves the application data unchanged.
|
||||||
|
4. A school with no dancers, groups or shows can be exported and imported.
|
||||||
|
|
||||||
|
### Adding a school
|
||||||
|
|
||||||
|
5. A valid file with an unknown school key shows the preview before any data is
|
||||||
|
added. Confirming creates the complete school; cancelling changes nothing.
|
||||||
|
6. An exported school can be restored after the original school is deleted or
|
||||||
|
the in-memory server state is lost.
|
||||||
|
7. An existing school with the same name but a different key is neither replaced
|
||||||
|
nor treated as the same school.
|
||||||
|
|
||||||
|
### Replacing a school
|
||||||
|
|
||||||
|
8. A valid file with an existing school key prompts the user to replace, merge or
|
||||||
|
cancel and clearly identifies the existing school.
|
||||||
|
9. Confirming replacement replaces the complete configuration. Objects and
|
||||||
|
relationships present only in the previous configuration are not retained as
|
||||||
|
part of the replaced school.
|
||||||
|
10. Other schools remain unchanged by replacement.
|
||||||
|
11. Selecting merge displays that merging is not yet supported and changes
|
||||||
|
nothing. Cancelling also changes nothing.
|
||||||
|
|
||||||
|
### Validation and errors
|
||||||
|
|
||||||
|
12. Malformed JSON, unsupported format versions, unknown fields, missing required
|
||||||
|
data, invalid field values and unresolved relationships cause the entire
|
||||||
|
import to fail.
|
||||||
|
13. Each failed import displays **"Import niet gelukt"** and a concrete cause.
|
||||||
|
14. A failed new-school import adds nothing. A failed replacement preserves the
|
||||||
|
entire existing school. Other schools are unaffected in either case.
|
||||||
|
15. After a failure, the user can select a corrected file and retry.
|
||||||
|
|
||||||
|
### Round-trip integrity
|
||||||
|
|
||||||
|
16. Exporting and importing a school preserves every configured field and
|
||||||
|
relationship, including a dancer's membership in multiple groups, shows and
|
||||||
|
their day parts, and any existing coaches or day-part group assignments.
|
||||||
|
17. Exporting the restored school again preserves its unique school key and
|
||||||
|
equivalent configuration, even if internal numeric IDs changed.
|
||||||
|
|
||||||
|
## Implementation handoff
|
||||||
|
|
||||||
|
This specification records agreed behavior. Backend endpoints, the detailed JSON
|
||||||
|
schema and frontend implementation remain implementation work; this review does
|
||||||
|
not implement the feature.
|
||||||
Reference in New Issue
Block a user