@turri-dev/cli 0.0.0-stage → 0.1.2-next.48dacfc
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.pi/themes/turri-dark.json +80 -0
- package/.pi/themes/turri-light.json +82 -0
- package/LICENSE +21 -0
- package/README.md +272 -2
- package/assets/jellyfish/dark-00.png +0 -0
- package/assets/jellyfish/dark-01.png +0 -0
- package/assets/jellyfish/dark-02.png +0 -0
- package/assets/jellyfish/dark-03.png +0 -0
- package/assets/jellyfish/dark-04.png +0 -0
- package/assets/jellyfish/dark-05.png +0 -0
- package/assets/jellyfish/dark-06.png +0 -0
- package/assets/jellyfish/dark-07.png +0 -0
- package/assets/jellyfish/dark-08.png +0 -0
- package/assets/jellyfish/dark-09.png +0 -0
- package/assets/jellyfish/dark-10.png +0 -0
- package/assets/jellyfish/dark-11.png +0 -0
- package/assets/jellyfish/dark-12.png +0 -0
- package/assets/jellyfish/dark-13.png +0 -0
- package/assets/jellyfish/dark-14.png +0 -0
- package/assets/jellyfish/fallback.txt +252 -0
- package/assets/jellyfish/light-00.png +0 -0
- package/assets/jellyfish/light-01.png +0 -0
- package/assets/jellyfish/light-02.png +0 -0
- package/assets/jellyfish/light-03.png +0 -0
- package/assets/jellyfish/light-04.png +0 -0
- package/assets/jellyfish/light-05.png +0 -0
- package/assets/jellyfish/light-06.png +0 -0
- package/assets/jellyfish/light-07.png +0 -0
- package/assets/jellyfish/light-08.png +0 -0
- package/assets/jellyfish/light-09.png +0 -0
- package/assets/jellyfish/light-10.png +0 -0
- package/assets/jellyfish/light-11.png +0 -0
- package/assets/jellyfish/light-12.png +0 -0
- package/assets/jellyfish/light-13.png +0 -0
- package/assets/jellyfish/light-14.png +0 -0
- package/bin/turri.mjs +29 -0
- package/dist/ask.js +149 -0
- package/dist/brand.js +50 -0
- package/dist/btw.js +174 -0
- package/dist/chat-models.js +37 -0
- package/dist/chat-skills.js +18 -0
- package/dist/cli.js +178 -0
- package/dist/config-command.js +197 -0
- package/dist/config-edit.js +367 -0
- package/dist/config.js +489 -0
- package/dist/conform-cli.js +29 -0
- package/dist/cultivate-cli.js +110 -0
- package/dist/drift-cli.js +25 -0
- package/dist/environment.js +70 -0
- package/dist/extension.js +2372 -0
- package/dist/genome.js +301 -0
- package/dist/graph.js +246 -0
- package/dist/identity.js +35 -0
- package/dist/init-config.js +511 -0
- package/dist/judge.js +62 -0
- package/dist/lineage-cli.js +13 -0
- package/dist/loop-cli.js +132 -0
- package/dist/loop-tools.js +225 -0
- package/dist/mature-tools.js +193 -0
- package/dist/model-check.js +117 -0
- package/dist/module-report.js +9 -0
- package/dist/pi-launch.js +31 -0
- package/dist/pi.js +813 -0
- package/dist/plain/check.js +76 -0
- package/dist/plain/concepts.js +213 -0
- package/dist/plain/errors.js +43 -0
- package/dist/plain/files.js +57 -0
- package/dist/plain/highlight.js +195 -0
- package/dist/plain/index.js +15 -0
- package/dist/plain/liquid.js +129 -0
- package/dist/plain/markdown.js +208 -0
- package/dist/plain/parser.js +752 -0
- package/dist/plain/plain.tmLanguage.json +124 -0
- package/dist/plain/spec.js +291 -0
- package/dist/plain/stdlib.js +44 -0
- package/dist/question-dialog.js +125 -0
- package/dist/questioning.js +109 -0
- package/dist/quiet.js +125 -0
- package/dist/regenerate/activity.js +187 -0
- package/dist/regenerate/agent-env.js +190 -0
- package/dist/regenerate/agent-shell.js +114 -0
- package/dist/regenerate/arbiter.js +133 -0
- package/dist/regenerate/audit.js +203 -0
- package/dist/regenerate/cases.js +83 -0
- package/dist/regenerate/change-view.js +102 -0
- package/dist/regenerate/choose-conformance.js +117 -0
- package/dist/regenerate/chunk-plan.js +625 -0
- package/dist/regenerate/codebase.js +75 -0
- package/dist/regenerate/command-check.js +312 -0
- package/dist/regenerate/compaction.js +20 -0
- package/dist/regenerate/confine.js +310 -0
- package/dist/regenerate/conform.js +133 -0
- package/dist/regenerate/conformance-agents.js +955 -0
- package/dist/regenerate/conformance.js +936 -0
- package/dist/regenerate/conversation-writes.js +100 -0
- package/dist/regenerate/credentials.js +88 -0
- package/dist/regenerate/debug-log.js +228 -0
- package/dist/regenerate/debugger.js +90 -0
- package/dist/regenerate/delivery.js +19 -0
- package/dist/regenerate/diagnose-job.js +40 -0
- package/dist/regenerate/diagnose.js +81 -0
- package/dist/regenerate/diff-view.js +240 -0
- package/dist/regenerate/drift.js +194 -0
- package/dist/regenerate/engine.js +118 -0
- package/dist/regenerate/environment-error.js +220 -0
- package/dist/regenerate/job-log.js +102 -0
- package/dist/regenerate/job-panel.js +336 -0
- package/dist/regenerate/jobs-tree.js +300 -0
- package/dist/regenerate/jobs.js +427 -0
- package/dist/regenerate/lanes.js +32 -0
- package/dist/regenerate/lineage.js +384 -0
- package/dist/regenerate/loop.js +1435 -0
- package/dist/regenerate/masking.js +95 -0
- package/dist/regenerate/notes.js +397 -0
- package/dist/regenerate/os-sandbox.js +243 -0
- package/dist/regenerate/paths.js +165 -0
- package/dist/regenerate/plain-palette.js +83 -0
- package/dist/regenerate/prompt.js +704 -0
- package/dist/regenerate/records.js +294 -0
- package/dist/regenerate/regenerate.js +598 -0
- package/dist/regenerate/regression.js +181 -0
- package/dist/regenerate/release.js +262 -0
- package/dist/regenerate/requires.js +241 -0
- package/dist/regenerate/resources.js +164 -0
- package/dist/regenerate/self-check.js +111 -0
- package/dist/regenerate/services.js +155 -0
- package/dist/regenerate/shell.js +320 -0
- package/dist/regenerate/side-panel.js +278 -0
- package/dist/regenerate/spec-map-view.js +574 -0
- package/dist/regenerate/spec-map.js +561 -0
- package/dist/regenerate/spec-steps.js +527 -0
- package/dist/regenerate/state.js +10 -0
- package/dist/regenerate/steer.js +91 -0
- package/dist/regenerate/steering.js +119 -0
- package/dist/regenerate/stop-report.js +161 -0
- package/dist/regenerate/submit-work.js +71 -0
- package/dist/regenerate/test-kinds.js +124 -0
- package/dist/regenerate/test-scripts.js +695 -0
- package/dist/regenerate/testing.js +406 -0
- package/dist/regenerate/transcript-view.js +1 -0
- package/dist/regenerate/unit-gate.js +20 -0
- package/dist/regenerate/unit-review.js +347 -0
- package/dist/regenerate/web.js +256 -0
- package/dist/regenerate/workspace.js +99 -0
- package/dist/regenerate-cli.js +68 -0
- package/dist/release-agent.js +114 -0
- package/dist/release-cli.js +131 -0
- package/dist/release-tools.js +148 -0
- package/dist/review/live.js +165 -0
- package/dist/rules.js +47 -0
- package/dist/self-invocation.js +110 -0
- package/dist/setup.js +245 -0
- package/dist/skill-progress.js +78 -0
- package/dist/skill.js +149 -0
- package/dist/skills.js +74 -0
- package/dist/spec-diff-cli.js +37 -0
- package/dist/spec-tools.js +155 -0
- package/dist/stack.js +158 -0
- package/dist/stacks.js +97 -0
- package/dist/stdlib.js +100 -0
- package/dist/terminal-images.js +46 -0
- package/dist/tools.js +242 -0
- package/dist/validate-cli.js +52 -0
- package/docs/README.md +58 -0
- package/docs/authoring-plain.md +245 -0
- package/docs/config.md +353 -0
- package/docs/deploy.md +109 -0
- package/docs/development.md +88 -0
- package/docs/headless.md +148 -0
- package/docs/images/how-turri-works.svg +50 -0
- package/docs/images/turri-banner.png +0 -0
- package/docs/installation.md +119 -0
- package/docs/parser.md +108 -0
- package/docs/regenerating.md +1116 -0
- package/docs/sandbox.md +233 -0
- package/docs/skills-and-gates.md +254 -0
- package/docs/theming.md +76 -0
- package/docs/using.md +454 -0
- package/genome/rules/bullet-continuation.md +69 -0
- package/genome/rules/concise-specs-examples.md +431 -0
- package/genome/rules/concise-specs-integration-examples.md +270 -0
- package/genome/rules/concise-specs.md +80 -0
- package/genome/rules/definitions.md +107 -0
- package/genome/rules/examples/integration-embedded-testing/run_conformance_tests_java.sh +163 -0
- package/genome/rules/examples/integration-embedded-testing/run_unittests_java.sh +51 -0
- package/genome/rules/exported-concepts.md +39 -0
- package/genome/rules/func-specs.md +129 -0
- package/genome/rules/impl-reqs.md +68 -0
- package/genome/rules/import-modules.md +48 -0
- package/genome/rules/integration-embedded-testing.md +276 -0
- package/genome/rules/integration-embedded.md +171 -0
- package/genome/rules/integration-standalone.md +135 -0
- package/genome/rules/integrations.md +137 -0
- package/genome/rules/linked-resources.md +69 -0
- package/genome/rules/module-structure.md +105 -0
- package/genome/rules/project-model.md +88 -0
- package/genome/rules/required-concepts.md +44 -0
- package/genome/rules/requires-modules.md +80 -0
- package/genome/rules/stdlib.md +73 -0
- package/genome/rules/test-reqs.md +57 -0
- package/genome/skills/add-acceptance-test/SKILL.md +100 -0
- package/genome/skills/add-concept/SKILL.md +71 -0
- package/genome/skills/add-functional-spec/SKILL.md +84 -0
- package/genome/skills/add-functional-specs/SKILL.md +118 -0
- package/genome/skills/add-implementation-requirement/SKILL.md +86 -0
- package/genome/skills/add-resource/SKILL.md +105 -0
- package/genome/skills/add-template/SKILL.md +64 -0
- package/genome/skills/add-test-requirement/SKILL.md +73 -0
- package/genome/skills/analyze-2-func-specs/SKILL.md +101 -0
- package/genome/skills/analyze-func-specs/SKILL.md +123 -0
- package/genome/skills/analyze-if-func-spec-too-complex/SKILL.md +211 -0
- package/genome/skills/break-down-func-spec/SKILL.md +205 -0
- package/genome/skills/brood/SKILL.md +229 -0
- package/genome/skills/brood/references/intent.md +35 -0
- package/genome/skills/brood/references/product.md +101 -0
- package/genome/skills/brood/references/stack.md +61 -0
- package/genome/skills/brood/references/testing.md +56 -0
- package/genome/skills/bud/SKILL.md +148 -0
- package/genome/skills/bud/references/checklist.md +44 -0
- package/genome/skills/bud/references/intent.md +30 -0
- package/genome/skills/check-plain-env/SKILL.md +285 -0
- package/genome/skills/consolidate-concepts/SKILL.md +192 -0
- package/genome/skills/create-import-module/SKILL.md +104 -0
- package/genome/skills/create-requires-module/SKILL.md +109 -0
- package/genome/skills/debug-specs/SKILL.md +188 -0
- package/genome/skills/implement-conformance-testing-script/SKILL.md +238 -0
- package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_cypress.ps1 +337 -0
- package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_golang.ps1 +111 -0
- package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_java.sh +136 -0
- package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_python.ps1 +103 -0
- package/genome/skills/implement-conformance-testing-script/assets/run_conformance_tests_python.sh +150 -0
- package/genome/skills/implement-unit-testing-script/SKILL.md +160 -0
- package/genome/skills/implement-unit-testing-script/assets/run_unittests_flutter.ps1 +87 -0
- package/genome/skills/implement-unit-testing-script/assets/run_unittests_golang.ps1 +73 -0
- package/genome/skills/implement-unit-testing-script/assets/run_unittests_java.sh +72 -0
- package/genome/skills/implement-unit-testing-script/assets/run_unittests_python.ps1 +81 -0
- package/genome/skills/implement-unit-testing-script/assets/run_unittests_python.sh +98 -0
- package/genome/skills/implement-unit-testing-script/assets/run_unittests_react.ps1 +87 -0
- package/genome/skills/init-plain-project/SKILL.md +117 -0
- package/genome/skills/init-plain-project/references/checklist.md +30 -0
- package/genome/skills/mature/SKILL.md +126 -0
- package/genome/skills/refactor-module/SKILL.md +196 -0
- package/genome/skills/resolve-section-ownership/SKILL.md +64 -0
- package/genome/skills/resolve-spec-conflict/SKILL.md +96 -0
- package/genome/skills/spawn/SKILL.md +163 -0
- package/package.json +68 -4
- package/stdlib/backend/common.plain +25 -0
- package/stdlib/backend/conformance/common.plain +12 -0
- package/stdlib/backend/conformance/go-gin.plain +9 -0
- package/stdlib/backend/conformance/go-nethttp.plain +9 -0
- package/stdlib/backend/conformance/java-springboot.plain +9 -0
- package/stdlib/backend/conformance/python-django.plain +9 -0
- package/stdlib/backend/conformance/python-fastapi.plain +9 -0
- package/stdlib/backend/conformance/python-flask.plain +9 -0
- package/stdlib/backend/conformance/rust-axum.plain +9 -0
- package/stdlib/backend/conformance/typescript-express.plain +9 -0
- package/stdlib/backend/conformance/typescript-fastify.plain +9 -0
- package/stdlib/backend/conformance/typescript-nestjs.plain +9 -0
- package/stdlib/backend/go-gin.plain +18 -0
- package/stdlib/backend/go-nethttp.plain +18 -0
- package/stdlib/backend/java-springboot.plain +19 -0
- package/stdlib/backend/python-django.plain +19 -0
- package/stdlib/backend/python-fastapi.plain +23 -0
- package/stdlib/backend/python-flask.plain +23 -0
- package/stdlib/backend/rust-axum.plain +17 -0
- package/stdlib/backend/typescript-express.plain +19 -0
- package/stdlib/backend/typescript-fastify.plain +19 -0
- package/stdlib/backend/typescript-nestjs.plain +19 -0
- package/stdlib/cli/common.plain +17 -0
- package/stdlib/cli/conformance/common.plain +11 -0
- package/stdlib/cli/conformance/go-cobra.plain +9 -0
- package/stdlib/cli/conformance/go-flag.plain +9 -0
- package/stdlib/cli/conformance/java-picocli.plain +9 -0
- package/stdlib/cli/conformance/python-argparse.plain +9 -0
- package/stdlib/cli/conformance/python-click.plain +9 -0
- package/stdlib/cli/conformance/python-typer.plain +9 -0
- package/stdlib/cli/conformance/rust-clap.plain +9 -0
- package/stdlib/cli/conformance/typescript-commander.plain +9 -0
- package/stdlib/cli/go-cobra.plain +14 -0
- package/stdlib/cli/go-flag.plain +14 -0
- package/stdlib/cli/java-picocli.plain +15 -0
- package/stdlib/cli/python-argparse.plain +18 -0
- package/stdlib/cli/python-click.plain +16 -0
- package/stdlib/cli/python-typer.plain +16 -0
- package/stdlib/cli/rust-clap.plain +14 -0
- package/stdlib/cli/typescript-commander.plain +17 -0
- package/stdlib/frontend/angular.plain +17 -0
- package/stdlib/frontend/common.plain +17 -0
- package/stdlib/frontend/conformance/angular.plain +5 -0
- package/stdlib/frontend/conformance/common.plain +11 -0
- package/stdlib/frontend/conformance/react-vite.plain +5 -0
- package/stdlib/frontend/conformance/sveltekit-spa.plain +5 -0
- package/stdlib/frontend/conformance/vue-vite.plain +5 -0
- package/stdlib/frontend/react-vite.plain +16 -0
- package/stdlib/frontend/sveltekit-spa.plain +16 -0
- package/stdlib/frontend/vue-vite.plain +16 -0
- package/stdlib/lang/go.plain +13 -0
- package/stdlib/lang/java.plain +12 -0
- package/stdlib/lang/python.plain +18 -0
- package/stdlib/lang/rust.plain +12 -0
- package/stdlib/lang/typescript.plain +13 -0
- package/stdlib/library/common.plain +15 -0
- package/stdlib/library/conformance/common.plain +9 -0
- package/stdlib/library/conformance/go.plain +9 -0
- package/stdlib/library/conformance/java-gradle.plain +9 -0
- package/stdlib/library/conformance/java-maven.plain +9 -0
- package/stdlib/library/conformance/python.plain +9 -0
- package/stdlib/library/conformance/rust.plain +9 -0
- package/stdlib/library/conformance/typescript.plain +9 -0
- package/stdlib/library/go.plain +12 -0
- package/stdlib/library/java-gradle.plain +13 -0
- package/stdlib/library/java-maven.plain +13 -0
- package/stdlib/library/python.plain +13 -0
- package/stdlib/library/rust.plain +12 -0
- package/stdlib/library/typescript.plain +15 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: add-implementation-requirement
|
|
3
|
+
description: >-
|
|
4
|
+
Add an implementation requirement to the ***implementation reqs*** section of
|
|
5
|
+
a ***plain spec file. Use when the user wants to add non-functional
|
|
6
|
+
requirements like technology choices, architectural constraints, coding
|
|
7
|
+
standards, data formats, error handling strategies, or any HOW-to-build
|
|
8
|
+
guidance to a .plain file.
|
|
9
|
+
allowed-tools: [read, write, edit, bash, ls, grep, find]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Add Implementation Requirement
|
|
13
|
+
|
|
14
|
+
## Workflow
|
|
15
|
+
|
|
16
|
+
1. **Identify the target `.plain` file.** If ambiguous, ask the user.
|
|
17
|
+
2. **Read the file** to understand existing implementation reqs, definitions, and functional specs.
|
|
18
|
+
3. **Determine if this belongs in implementation reqs** — it must describe HOW to build, not WHAT to build (that goes in `***functional specs***`).
|
|
19
|
+
4. **Draft the requirement** following the rules below.
|
|
20
|
+
5. **Insert it** into the `***implementation reqs***` section.
|
|
21
|
+
6. **Read the file again** to confirm correct placement and syntax.
|
|
22
|
+
|
|
23
|
+
## What Belongs Here
|
|
24
|
+
|
|
25
|
+
Implementation reqs are free-form instructions that steer code generation. Common contents:
|
|
26
|
+
|
|
27
|
+
- **Technology choices**: language, framework, runtime version
|
|
28
|
+
- **Architectural constraints**: patterns, layering, dependency rules
|
|
29
|
+
- **Coding standards**: naming conventions, style guidelines
|
|
30
|
+
- **Data formats**: serialization, encoding, transformation rules
|
|
31
|
+
- **Error handling**: strategies, retry logic, exception hierarchies
|
|
32
|
+
- **Algorithm descriptions**: specific approaches when behavior alone is insufficient
|
|
33
|
+
- **Performance guidance**: memory constraints, streaming requirements, batching strategies
|
|
34
|
+
- **Language-specific constructs**: generics, annotations, framework-specific types and idioms
|
|
35
|
+
|
|
36
|
+
## What Does NOT Belong Here
|
|
37
|
+
|
|
38
|
+
- **Behavior and features** — those go in `***functional specs***`
|
|
39
|
+
- **Concept definitions** — those go in `***definitions***`
|
|
40
|
+
- **Conformance-test instructions** — those go in `***test reqs***`. Note: **unit-test instructions belong HERE**, not in `***test reqs***` — see *Unit-test guidance belongs here* below
|
|
41
|
+
|
|
42
|
+
## Unit-test guidance belongs here
|
|
43
|
+
|
|
44
|
+
**Everything about `:UnitTests:` goes in `***implementation reqs***`** — paths, approach, packages, framework (JUnit / pytest / Jest / Go's `testing` / …), conventions, fixtures, mocking policy, file layout, naming, lint / static-analysis gates. Unit tests are part of the generated codebase, so requirements that shape them are implementation reqs by definition.
|
|
45
|
+
|
|
46
|
+
- The unit-test generator reads **only** `***implementation reqs***`; anything about `:UnitTests:` placed in `***test reqs***` is silently ignored
|
|
47
|
+
- Phrase each `:UnitTests:` requirement in terms of the predefined `:UnitTests:` concept so the partition stays visible at a glance
|
|
48
|
+
- `***test reqs***` is exclusively for `:ConformanceTests:` — see [`add-test-requirement`](../add-test-requirement/SKILL.md)
|
|
49
|
+
|
|
50
|
+
## Key Principle: HOW vs WHAT
|
|
51
|
+
|
|
52
|
+
`***implementation reqs***` describe HOW the software should be built.
|
|
53
|
+
`***functional specs***` describe WHAT the software should do.
|
|
54
|
+
|
|
55
|
+
If the requirement describes observable behavior (endpoints, business rules, user-facing features), it belongs in functional specs. If it describes internal structure, technology, or coding guidance, it belongs here.
|
|
56
|
+
|
|
57
|
+
## Format
|
|
58
|
+
|
|
59
|
+
Implementation reqs are bullet points in the `***implementation reqs***` section:
|
|
60
|
+
|
|
61
|
+
```plain
|
|
62
|
+
***implementation reqs***
|
|
63
|
+
|
|
64
|
+
- :Implementation: should be in Python 3.12.
|
|
65
|
+
|
|
66
|
+
- :Implementation: should use pip for dependency management.
|
|
67
|
+
|
|
68
|
+
- :ReportExporter: writes a :CsvFile: with streaming writes, never holding the full dataset in memory.
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Reference defined `:Concepts:` where they add clarity. Implementation reqs in non-leaf sections apply to all subsections.
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
## Encapsulation Warning
|
|
76
|
+
|
|
77
|
+
`requires` modules only receive functional specs from their dependencies — not implementation reqs. If downstream modules need certain behavior to be visible, that behavior must be expressed in functional specs, not here.
|
|
78
|
+
|
|
79
|
+
## Validation Checklist
|
|
80
|
+
|
|
81
|
+
- [ ] Describes HOW to build, not WHAT to build
|
|
82
|
+
- [ ] All referenced `:Concepts:` are defined in `***definitions***`
|
|
83
|
+
- [ ] Does not duplicate guidance already present in the file or its imports
|
|
84
|
+
- [ ] Trimmed per `concise-specs.md`: plain words, no rationale, no standard behavior of a technology already named
|
|
85
|
+
- [ ] Placed inside a `***implementation reqs***` section
|
|
86
|
+
- [ ] No behavioral requirements that should be in `***functional specs***`
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: add-resource
|
|
3
|
+
description: >-
|
|
4
|
+
Add a linked resource (external file reference) to a ***plain spec. Use when
|
|
5
|
+
the user wants to reference a JSON schema, API spec, data file, or other
|
|
6
|
+
external file from within a functional spec, definition, or implementation
|
|
7
|
+
requirement.
|
|
8
|
+
allowed-tools: [read, write, edit, bash, ls, grep, find]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Add Resource
|
|
12
|
+
|
|
13
|
+
Linked resources are external files referenced from within a `.plain` spec using markdown link syntax. The file contents are passed to the renderer alongside the spec, providing additional context for code generation.
|
|
14
|
+
|
|
15
|
+
## Workflow
|
|
16
|
+
|
|
17
|
+
1. **Identify or create the resource file.** Keep it inside the project — the `resources/` directory is the conventional home; it does not have to sit next to the `.plain` file.
|
|
18
|
+
2. **Add the markdown link** at the appropriate place in the spec.
|
|
19
|
+
3. **Verify the file path** is relative to the `.plain` file location.
|
|
20
|
+
4. **Read the file back** to confirm correct link syntax and path.
|
|
21
|
+
|
|
22
|
+
## Format
|
|
23
|
+
|
|
24
|
+
Use standard markdown link syntax inside any spec section:
|
|
25
|
+
|
|
26
|
+
```plain
|
|
27
|
+
***definitions***
|
|
28
|
+
- :AuthData: is the authentication data structure.
|
|
29
|
+
- Its format is defined in the [auth schema](resources/auth_schema.json).
|
|
30
|
+
|
|
31
|
+
***implementation reqs***
|
|
32
|
+
- When transforming :BackupData:, use the JOLT transform.
|
|
33
|
+
- The transform is defined in [backup_transform.jolt](resources/backup_transform.jolt).
|
|
34
|
+
|
|
35
|
+
***functional specs***
|
|
36
|
+
|
|
37
|
+
- An API conforming to the [API specification](resources/api_spec.yaml) is exposed.
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Path Rules
|
|
41
|
+
|
|
42
|
+
- Paths are resolved **relative to the directory where `turri` is run** (the current working directory).
|
|
43
|
+
- Relative paths may traverse into parent directories — `[resource](../../resources/resource.md)` is valid — as long as they resolve to a real text file on disk.
|
|
44
|
+
- **No external URLs** — only local file references.
|
|
45
|
+
- **No folder paths** — the target must be a file, not a directory.
|
|
46
|
+
- Only text-based files are supported.
|
|
47
|
+
|
|
48
|
+
### A linked resource MUST be a single, text-based file that exists on disk
|
|
49
|
+
|
|
50
|
+
A linked resource is **always** a single file that exists on disk at the path you reference, **and** that file's content must be text-based. The renderer reads the linked file's bytes and feeds them into the model alongside the spec; a directory, a remote URL, or a binary blob breaks that contract and is one of the most disruptive mistakes you can make when authoring a `.plain` file — the spec looks valid but the renderer either silently ignores the link, fails to read it, or wastes the model's context window on bytes it cannot interpret.
|
|
51
|
+
|
|
52
|
+
Three things a linked resource **must not** be:
|
|
53
|
+
|
|
54
|
+
1. **A folder / directory.** `[integrations](src/integrations/)`, `[schemas](resources/schemas/)`, `[host project](../host_project/)` are all invalid — the renderer cannot ingest a directory. If a whole directory's worth of content is relevant, pick the single most representative **file** inside it (a `README.md`, an exemplar source file, a manifest at the directory root) and link **that**.
|
|
55
|
+
2. **A URL / external location.** `[Stripe docs](https://stripe.com/docs/api)`, `[OpenAPI spec](https://example.com/openapi.json)`, any `http://` / `https://` / `ftp://` / `git://` / `s3://` / `gs://` target. Linked resources are local-file only. If a URL's content is essential to the spec, fetch it once, save the response to a text file under `resources/` (e.g. `resources/stripe-docs-snapshot.md`, `resources/example-openapi.yaml`), and link **that file**.
|
|
56
|
+
3. **A binary file.** PNG, JPG, JPEG, GIF, BMP, TIFF, WebP, ICO, PDF, DOCX, XLSX, PPTX, ZIP, TAR, GZ, MP3, MP4, WAV, compiled binaries (`.exe`, `.so`, `.dylib`, `.class`, `.wasm`), and anything else that isn't human-readable text in its raw form. Binary content cannot be meaningfully consumed by the renderer; linking a screenshot, a PDF spec, or a packaged artifact accomplishes nothing except bloating the context. If the information in a binary asset is essential, transcribe it into a text-based form first — a UI screenshot becomes a Markdown description or a structured YAML wireframe under `resources/`; a PDF spec becomes a Markdown extract or the underlying JSON Schema / OpenAPI; an architecture diagram becomes a Mermaid block inside a Markdown file.
|
|
57
|
+
|
|
58
|
+
If the markdown-link target ends with `/`, contains `://`, points at a path that resolves to a directory, or points at a file with a binary extension (see the list above), **stop** — it cannot be a linked resource. Convert it to a text file under `resources/` first, then link the converted file.
|
|
59
|
+
|
|
60
|
+
### Do not mention URLs or folder paths in `.plain` content at all
|
|
61
|
+
|
|
62
|
+
The constraint above is **not** just about markdown link syntax. URLs (any `http://`, `https://`, `ftp://`, `git://`, `s3://`, … string) and folder paths (`src/integrations/`, `../host_project/`, anything ending with `/`, anything that resolves to a directory) **must not appear anywhere in `.plain` content** — not as link targets, not in concept body prose, not in functional-spec text, not in implementation-reqs. Mentioning a URL or a folder in prose is a critical and common mistake because:
|
|
63
|
+
|
|
64
|
+
- The renderer cannot follow URLs or open folders. A URL or folder reference in prose is a *ghost* dependency: it looks meaningful to a human reader, but it contributes nothing to code generation. Worse, downstream readers (and future you) assume the renderer used the referenced content, so the spec drifts from reality.
|
|
65
|
+
- The fix is always the same: if external content matters, fetch it (or pick one canonical file out of the directory), save it as a text file under `resources/`, and refer to it through a normal linked resource. The concept or spec then names the content through the linked file, not through a URL or folder path string.
|
|
66
|
+
|
|
67
|
+
The **only** exceptions are URLs and paths that are *values the produced software itself uses at runtime* (e.g. the base URL the integration calls, a database connection path, a CLI argument value). Those are configuration values, not external references, and they belong in the spec because the generated code needs them. A useful litmus test: "Would the renderer benefit from reading the bytes at this URL / folder?" If yes, save it to a text file and link the file. If no (it's a runtime value), it can stay as plain text in the spec.
|
|
68
|
+
|
|
69
|
+
### What a linked resource CAN be
|
|
70
|
+
|
|
71
|
+
- A single file inside the project, reachable by a path relative to where `turri` is run — parent-directory traversal (`../`) is allowed (`resources/` is the conventional home).
|
|
72
|
+
- A **text-based** file the renderer can read end-to-end: JSON, YAML, XML, HTML, Markdown, plain text, CSV, TSV, source code in any language (`.py`, `.js`, `.ts`, `.go`, `.java`, `.rb`, `.rs`, `.kt`, `.swift`, `.c`, `.cpp`, `.cs`, …), shell scripts, SQL, JSON Schema, OpenAPI, AsyncAPI, Protobuf `.proto`, GraphQL SDL, `.jolt`, `.env.example`, `.toml`, `.ini`, `.proto`, `Dockerfile`, etc.
|
|
73
|
+
|
|
74
|
+
## Common Resource Types
|
|
75
|
+
|
|
76
|
+
| Type | Typical location | Use case |
|
|
77
|
+
|------|-----------------|----------|
|
|
78
|
+
| JSON Schema | `resources/*.json` | Defining data structure contracts |
|
|
79
|
+
| OpenAPI / Swagger spec | `resources/*.yaml` | API endpoint definitions |
|
|
80
|
+
| Data transforms | `resources/*.jolt` | Data transformation rules |
|
|
81
|
+
| Test fixtures | `resources/*.json`, `resources/*.csv` | Sample data for tests |
|
|
82
|
+
| Configuration examples | `resources/*.yaml` | Reference configurations |
|
|
83
|
+
|
|
84
|
+
## When to Use Resources
|
|
85
|
+
|
|
86
|
+
- The information is too detailed or structured to express inline in the spec (e.g., a full JSON schema).
|
|
87
|
+
- The same data is referenced by multiple specs or sections.
|
|
88
|
+
- The resource is an industry-standard format (OpenAPI, JSON Schema) that the renderer can interpret directly.
|
|
89
|
+
|
|
90
|
+
## When NOT to Use Resources
|
|
91
|
+
|
|
92
|
+
- The information is short enough to include inline in the spec text.
|
|
93
|
+
- The file is generated code (those belong in `plain_modules/`, not `resources/`).
|
|
94
|
+
|
|
95
|
+
## Validation Checklist
|
|
96
|
+
|
|
97
|
+
- [ ] Resource file exists at the specified path
|
|
98
|
+
- [ ] **Target is a file on disk, not a directory** (the path does not end in `/` and does not resolve to a folder)
|
|
99
|
+
- [ ] **Target is a local path, not a URL** (no `://` anywhere in the target: no `http://`, `https://`, `ftp://`, `git://`, `s3://`, `gs://`, etc.)
|
|
100
|
+
- [ ] **Target is a text-based file** (no binary extensions: `.png`, `.jpg`, `.jpeg`, `.gif`, `.bmp`, `.tiff`, `.webp`, `.ico`, `.pdf`, `.docx`, `.xlsx`, `.pptx`, `.zip`, `.tar`, `.gz`, `.mp3`, `.mp4`, `.wav`, `.exe`, `.so`, `.dylib`, `.class`, `.wasm`, …)
|
|
101
|
+
- [ ] **No URLs or folder paths anywhere in the surrounding `.plain` content** (not as link targets, not in body prose), with the sole exception of URLs / paths that are runtime values the generated software itself uses
|
|
102
|
+
- [ ] Path is relative to the `.plain` file, not absolute
|
|
103
|
+
- [ ] Path resolves to a real text file on disk from where `turri` is run (`../` traversal is allowed)
|
|
104
|
+
- [ ] Markdown link syntax is correct: `[display text](relative/path)`
|
|
105
|
+
- [ ] Resource content is relevant and adds value beyond what the spec text says
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: add-template
|
|
3
|
+
description: >-
|
|
4
|
+
Create or include a Liquid template in a ***plain spec file using
|
|
5
|
+
{% include %} syntax. Use when the same spec content needs to be reused
|
|
6
|
+
across multiple .plain files with different parameters.
|
|
7
|
+
allowed-tools: [read, write, edit, bash, ls, grep, find]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Add Template
|
|
11
|
+
|
|
12
|
+
Templates use Liquid syntax (`{% include %}`) to reuse the same spec content across multiple `.plain` files. Each inclusion can pass different parameters, producing tailored output from a single source. This is distinct from `import` and `requires` — templates are about textual reuse with parameterization, not module dependencies.
|
|
13
|
+
|
|
14
|
+
## When to Use Templates
|
|
15
|
+
|
|
16
|
+
- The **exact same spec structure** is needed in more than one `.plain` file.
|
|
17
|
+
- The reused content differs only in specific values (names, paths, config) that can be parameterized.
|
|
18
|
+
- You want a single source of truth for a pattern that appears in multiple modules.
|
|
19
|
+
|
|
20
|
+
## Format
|
|
21
|
+
|
|
22
|
+
### Including a Template
|
|
23
|
+
|
|
24
|
+
Use `{% include %}` with the template path and parameters:
|
|
25
|
+
|
|
26
|
+
```plain
|
|
27
|
+
{% include "console_app_template.plain", main_file_name: "app.py", app_name: "MyApp" %}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Parameters are passed as key-value pairs after the template path. Inside the template, parameters are accessed using Liquid variable syntax (`{{ main_file_name }}`).
|
|
31
|
+
|
|
32
|
+
### Writing a Template
|
|
33
|
+
|
|
34
|
+
Templates live in the `template/` directory. Only **variables** (`{{ variable_name }}`) are supported — conditionals, loops, and other Liquid features are not available:
|
|
35
|
+
|
|
36
|
+
```plain
|
|
37
|
+
***definitions***
|
|
38
|
+
- :{{ app_name }}MainFile: is the entry point file for :{{ app_name }}:.
|
|
39
|
+
|
|
40
|
+
***implementation reqs***
|
|
41
|
+
- :{{ app_name }}MainFile: should be called "{{ main_file_name }}".
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Workflow: Including an Existing Template
|
|
45
|
+
|
|
46
|
+
1. **Check the `template/` directory** to see what templates are available.
|
|
47
|
+
2. **Read the template** to understand what parameters it expects and what content it produces.
|
|
48
|
+
3. **Add the `{% include %}` statement** to the target `.plain` file with the correct parameters.
|
|
49
|
+
4. **Verify** that the expanded content does not introduce concept name collisions or duplicate sections.
|
|
50
|
+
|
|
51
|
+
## Workflow: Creating a New Template
|
|
52
|
+
|
|
53
|
+
1. **Identify the repeated pattern** — find spec content that is duplicated (or will be duplicated) across multiple `.plain` files.
|
|
54
|
+
2. **Extract the common content** into a new `.plain` file in the `template/` directory.
|
|
55
|
+
3. **Parameterize the differences** — replace the varying parts with Liquid variables.
|
|
56
|
+
4. **Update the original files** to use `{% include %}` instead of the duplicated content.
|
|
57
|
+
|
|
58
|
+
## Validation Checklist
|
|
59
|
+
|
|
60
|
+
- [ ] Template file is in the `template/` directory
|
|
61
|
+
- [ ] All varying parts are parameterized with Liquid variables
|
|
62
|
+
- [ ] All required parameters are passed at each `{% include %}` call site
|
|
63
|
+
- [ ] Expanded content does not introduce concept name collisions
|
|
64
|
+
- [ ] Template is used by more than one `.plain` file (otherwise, inline the content)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: add-test-requirement
|
|
3
|
+
description: >-
|
|
4
|
+
Add a test requirement to the ***test reqs*** section of a ***plain spec
|
|
5
|
+
file. Use when the user wants to specify conformance testing instructions
|
|
6
|
+
like test frameworks, execution methods, or testing constraints in a .plain
|
|
7
|
+
file.
|
|
8
|
+
allowed-tools: [read, write, edit, bash, ls, grep, find]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Add Test Requirement
|
|
12
|
+
|
|
13
|
+
## Workflow
|
|
14
|
+
|
|
15
|
+
1. **Identify the target `.plain` file.** If ambiguous, ask the user.
|
|
16
|
+
2. **Read the file** to understand existing test reqs and the overall spec structure.
|
|
17
|
+
3. **Confirm this is a conformance test concern** — unit test guidance goes in `***implementation reqs***`, not here.
|
|
18
|
+
4. **Draft the requirement** following the rules below.
|
|
19
|
+
5. **Insert it** into the `***test reqs***` section.
|
|
20
|
+
6. **Read the file again** to confirm correct placement and syntax.
|
|
21
|
+
|
|
22
|
+
## What Belongs Here
|
|
23
|
+
|
|
24
|
+
Test reqs specify how **conformance tests** should be written and run. Common contents:
|
|
25
|
+
|
|
26
|
+
- **Test framework**: which framework to use (e.g., pytest, Unittest, xUnit)
|
|
27
|
+
- **Execution method**: the command to run the tests
|
|
28
|
+
- **Testing constraints**: what must or must not be done in tests (e.g., no skipping tests, mock requirements)
|
|
29
|
+
- **Test data**: how test fixtures or mock data should be structured
|
|
30
|
+
- **Environment setup**: any prerequisites for running conformance tests
|
|
31
|
+
|
|
32
|
+
## What Does NOT Belong Here
|
|
33
|
+
|
|
34
|
+
- **Unit test guidance** — that goes in `***implementation reqs***`
|
|
35
|
+
- **Acceptance tests** — those are nested under individual functional specs in `***functional specs***`
|
|
36
|
+
- **Behavioral requirements** — those go in `***functional specs***`
|
|
37
|
+
- **Technology choices for the implementation** — those go in `***implementation reqs***`
|
|
38
|
+
|
|
39
|
+
## Conformance Tests vs Other Tests
|
|
40
|
+
|
|
41
|
+
| Test Type | Where to Specify | Purpose |
|
|
42
|
+
|-----------|-----------------|---------|
|
|
43
|
+
| Unit tests | `***implementation reqs***` | Test individual functionalities in isolation |
|
|
44
|
+
| Conformance tests | `***test reqs***` | Verify implementation conforms to the full spec |
|
|
45
|
+
| Acceptance tests | `***acceptance tests***` under a functional spec | Verify a specific functional spec |
|
|
46
|
+
|
|
47
|
+
## Format
|
|
48
|
+
|
|
49
|
+
Test reqs are bullet points in the `***test reqs***` section:
|
|
50
|
+
|
|
51
|
+
```plain
|
|
52
|
+
***test reqs***
|
|
53
|
+
|
|
54
|
+
- :ConformanceTests: should be implemented using pytest framework.
|
|
55
|
+
|
|
56
|
+
- :ConformanceTests: will be run using "pytest" command.
|
|
57
|
+
|
|
58
|
+
- :ConformanceTests: must be implemented and executed - do not skip tests.
|
|
59
|
+
|
|
60
|
+
- :ConformanceTests: should mock all external HTTP calls.
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Reference predefined concepts like `:ConformanceTests:` and any defined `:Concepts:` where they add clarity.
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
## Validation Checklist
|
|
67
|
+
|
|
68
|
+
- [ ] Describes conformance testing concerns, not unit tests or behavior
|
|
69
|
+
- [ ] All referenced `:Concepts:` are defined (or are predefined like `:ConformanceTests:`)
|
|
70
|
+
- [ ] Does not duplicate guidance already present in the file or its imports
|
|
71
|
+
- [ ] Trimmed per `concise-specs.md`: plain words, no rationale, no default framework behavior
|
|
72
|
+
- [ ] Placed inside a `***test reqs***` section
|
|
73
|
+
- [ ] No behavioral requirements that should be in `***functional specs***`
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: analyze-2-func-specs
|
|
3
|
+
description: >-
|
|
4
|
+
Analyze two functional specs from a ***plain spec file to determine if they
|
|
5
|
+
conflict. Use when the user wants to check whether two specific functional
|
|
6
|
+
requirements are compatible, or when debugging a suspected conflict between
|
|
7
|
+
two specs.
|
|
8
|
+
allowed-tools: [read, ls, grep, find]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Analyze Two Functional Specs
|
|
12
|
+
|
|
13
|
+
## Input
|
|
14
|
+
|
|
15
|
+
Two functional specs from a `.plain` file (or across `requires` modules). The user provides them directly or points to them by location in a file.
|
|
16
|
+
|
|
17
|
+
## Workflow
|
|
18
|
+
|
|
19
|
+
1. **Read both functional specs** and the `***definitions***` section so all referenced `:Concepts:` are understood.
|
|
20
|
+
2. **Determine chronological order** — which spec comes first? The earlier spec was rendered first and the later spec was rendered with the earlier one in context.
|
|
21
|
+
3. **Run the conflict analysis** using the checklist below.
|
|
22
|
+
4. **Output the verdict and nothing else** — either `COMPATIBLE` or `CONFLICTING`. No reasoning, no category labels, no resolution suggestions.
|
|
23
|
+
|
|
24
|
+
## Conflict Analysis Checklist
|
|
25
|
+
|
|
26
|
+
Work through each question. If any answer is "yes", the specs likely conflict.
|
|
27
|
+
|
|
28
|
+
### 1. Direct Contradiction
|
|
29
|
+
|
|
30
|
+
Do the two specs make mutually exclusive assertions about the same behavior?
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
Spec A: :Resource: items are returned sorted by name in ascending order.
|
|
34
|
+
Spec B: :Resource: items are returned sorted by creation date in descending order.
|
|
35
|
+
|
|
36
|
+
Verdict: CONFLICTING — both define the sort order for the same response,
|
|
37
|
+
but specify different fields and directions. A single implementation cannot
|
|
38
|
+
satisfy both unless scoped to different contexts.
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### 2. State or Data Conflict
|
|
42
|
+
|
|
43
|
+
Does one spec set a state or value that the other spec assumes is different?
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
Spec A: :TaskList: is initially empty.
|
|
47
|
+
Spec B: :TaskList: contains a default "Welcome" :Task: on first load.
|
|
48
|
+
|
|
49
|
+
Verdict: CONFLICTING — both define the initial state of :TaskList: differently.
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### 3. Behavioral Override
|
|
53
|
+
|
|
54
|
+
Does the later spec silently replace behavior established by the earlier spec without acknowledging it?
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
Spec A: :User: credentials are validated using an API key.
|
|
58
|
+
Spec B: :User: credentials are validated using OAuth 2.0.
|
|
59
|
+
|
|
60
|
+
Verdict: CONFLICTING — both define the authentication mechanism but pick
|
|
61
|
+
different approaches. The later spec overrides the earlier one.
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 4. Scope Ambiguity
|
|
65
|
+
|
|
66
|
+
Are the two specs ambiguous enough that a renderer could interpret them as conflicting, even if the user intends them to be complementary?
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
Spec A: All :Resource: items are returned.
|
|
70
|
+
Spec B: Only active :Resource: items are returned.
|
|
71
|
+
|
|
72
|
+
Verdict: CONFLICTING (ambiguous) — "all" vs "only active" appear contradictory.
|
|
73
|
+
Could be resolved by scoping each to different conditions (e.g., filtered vs unfiltered).
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 5. Shared Concept, Different Constraints
|
|
77
|
+
|
|
78
|
+
Do both specs impose constraints on the same `:Concept:` that cannot coexist?
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
Spec A: :BatchSize: is 100 items.
|
|
82
|
+
Spec B: :BatchSize: is 50 items for :Resource: types with attachments.
|
|
83
|
+
|
|
84
|
+
Verdict: COMPATIBLE — Spec B adds a conditional refinement, not a contradiction.
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Output Format
|
|
88
|
+
|
|
89
|
+
The skill emits exactly one of these two strings, with no surrounding text, explanation, category label, or resolution suggestion:
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
COMPATIBLE
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
or
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
CONFLICTING
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The internal analysis (checklist, chronological reasoning) informs the verdict but must not appear in the output. The caller decides what to do with the result — typically: act on `COMPATIBLE` by proceeding, or invoke `resolve-spec-conflict` on `CONFLICTING` to produce the actual fix.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: analyze-func-specs
|
|
3
|
+
description: >-
|
|
4
|
+
Analyze a batch of functional specs from a ***plain spec file to determine
|
|
5
|
+
which pairs conflict. Replaces the pair-by-pair `analyze-2-func-specs` flow
|
|
6
|
+
when a caller wants to check many specs at once (e.g. a new spec against
|
|
7
|
+
every existing spec, or a freshly inserted batch against itself).
|
|
8
|
+
allowed-tools: [read, ls, grep, find]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Analyze Functional Specs
|
|
12
|
+
|
|
13
|
+
## Input
|
|
14
|
+
|
|
15
|
+
A **set of two or more functional specs** to check against each other. Callers typically supply one of:
|
|
16
|
+
|
|
17
|
+
- A whole `***functional specs***` section to self-check.
|
|
18
|
+
- A new spec (or batch of new specs) **plus** the existing specs from the same file and any `requires` modules.
|
|
19
|
+
- An explicit list of spec snippets the user wants compared.
|
|
20
|
+
|
|
21
|
+
Each spec must be identifiable. If the caller didn't label them, assign **stable identifiers** in order of appearance: `S1`, `S2`, `S3`, …. Use those identifiers in the output. If the caller provided their own IDs or quoted snippets, use those instead and keep them verbatim.
|
|
22
|
+
|
|
23
|
+
The skill also needs the `***definitions***` section (and any imported definitions) so referenced `:Concepts:` can be resolved.
|
|
24
|
+
|
|
25
|
+
## Workflow
|
|
26
|
+
|
|
27
|
+
1. **Read all input specs and the relevant `***definitions***`** so every `:Concept:` is understood.
|
|
28
|
+
2. **Establish chronological order** across the batch. Earlier specs are considered to have been rendered first; later specs are evaluated with the earlier ones in context. If the caller already provided an order, preserve it.
|
|
29
|
+
3. **Generate the pair list.** Enumerate every unordered pair `(Sᵢ, Sⱼ)` with `i < j`. Skip pairs where the two specs share no `:Concept:` and no overlapping subject — they are trivially compatible and listing them adds noise.
|
|
30
|
+
4. **Run the conflict analysis below on each remaining pair.** Use the same checklist that the legacy `analyze-2-func-specs` skill used, but apply it pair by pair across the batch in a single pass — do not require the caller to invoke the analyzer once per pair.
|
|
31
|
+
5. **Record every CONFLICTING pair.** Compatible pairs are not listed individually; only the conflicts are emitted.
|
|
32
|
+
6. **Output the verdict** in the format below. No reasoning, no category labels, no resolution suggestions.
|
|
33
|
+
|
|
34
|
+
## Conflict Analysis Checklist (applied per pair)
|
|
35
|
+
|
|
36
|
+
Work through each question for the pair under inspection. If any answer is "yes", that pair is CONFLICTING.
|
|
37
|
+
|
|
38
|
+
### 1. Direct Contradiction
|
|
39
|
+
|
|
40
|
+
Do the two specs make mutually exclusive assertions about the same behavior?
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
Spec A: :Resource: items are returned sorted by name in ascending order.
|
|
44
|
+
Spec B: :Resource: items are returned sorted by creation date in descending order.
|
|
45
|
+
|
|
46
|
+
Verdict: CONFLICTING — both define the sort order for the same response,
|
|
47
|
+
but specify different fields and directions. A single implementation cannot
|
|
48
|
+
satisfy both unless scoped to different contexts.
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 2. State or Data Conflict
|
|
52
|
+
|
|
53
|
+
Does one spec set a state or value that the other spec assumes is different?
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
Spec A: :TaskList: is initially empty.
|
|
57
|
+
Spec B: :TaskList: contains a default "Welcome" :Task: on first load.
|
|
58
|
+
|
|
59
|
+
Verdict: CONFLICTING — both define the initial state of :TaskList: differently.
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 3. Behavioral Override
|
|
63
|
+
|
|
64
|
+
Does the later spec silently replace behavior established by the earlier spec without acknowledging it?
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
Spec A: :User: credentials are validated using an API key.
|
|
68
|
+
Spec B: :User: credentials are validated using OAuth 2.0.
|
|
69
|
+
|
|
70
|
+
Verdict: CONFLICTING — both define the authentication mechanism but pick
|
|
71
|
+
different approaches. The later spec overrides the earlier one.
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 4. Scope Ambiguity
|
|
75
|
+
|
|
76
|
+
Are the two specs ambiguous enough that a renderer could interpret them as conflicting, even if the user intends them to be complementary?
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
Spec A: All :Resource: items are returned.
|
|
80
|
+
Spec B: Only active :Resource: items are returned.
|
|
81
|
+
|
|
82
|
+
Verdict: CONFLICTING (ambiguous) — "all" vs "only active" appear contradictory.
|
|
83
|
+
Could be resolved by scoping each to different conditions (e.g., filtered vs unfiltered).
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 5. Shared Concept, Different Constraints
|
|
87
|
+
|
|
88
|
+
Do both specs impose constraints on the same `:Concept:` that cannot coexist?
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
Spec A: :BatchSize: is 100 items.
|
|
92
|
+
Spec B: :BatchSize: is 50 items for :Resource: types with attachments.
|
|
93
|
+
|
|
94
|
+
Verdict: COMPATIBLE — Spec B adds a conditional refinement, not a contradiction.
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Output Format
|
|
98
|
+
|
|
99
|
+
Emit exactly one of the two shapes below, with no surrounding text, explanation, category label, or resolution suggestion.
|
|
100
|
+
|
|
101
|
+
If **no pair** is conflicting:
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
COMPATIBLE
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
If **one or more pairs** are conflicting, emit `CONFLICTING` followed by one line per conflicting pair, in `Sᵢ x Sⱼ` form (using the identifiers from the input, with `i < j`), sorted lexicographically:
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
CONFLICTING
|
|
111
|
+
S1 x S4
|
|
112
|
+
S2 x S3
|
|
113
|
+
S3 x S5
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Rules for the output:
|
|
117
|
+
|
|
118
|
+
- Do **not** list compatible pairs.
|
|
119
|
+
- Do **not** include reasoning, checklist categories, or fixes — the caller decides what to do with each conflict (typically: invoke `resolve-spec-conflict` on each pair).
|
|
120
|
+
- If the input contained fewer than two specs, emit `COMPATIBLE` (nothing to compare).
|
|
121
|
+
- Identifiers must match exactly what the caller provided (or the `S1`, `S2`, … fallback assigned in step 1).
|
|
122
|
+
|
|
123
|
+
The internal pairwise analysis informs the verdict but must not appear in the output.
|