Add the Use Case Diagram, Domain Model (use case and project), Dictionary, Operation Contract, Sequence Diagram, review records RC-001 to RC-015 and the Traceability Matrix. Split US-001 into one story per milestone, make GitHub optional (AGPL license applied when chosen), and accept BC-001, SA-001, PP-001, UCD-001, US-001, UC-001, SSD-001, DM-001, DM-002, OC-001, SD-001, DICT-001 and MIL-001 to MIL-003 after review. Refs: no issues synced yet (sync-project.sh dry run only) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
91 lines
5.8 KiB
Markdown
91 lines
5.8 KiB
Markdown
# Operation Contract
|
|
|
|
## Metadata
|
|
| Key | Value |
|
|
| --- | --- |
|
|
| ID | OC-001 |
|
|
| CrossReference | [SSD-001], [DM-001], [SD-001] |
|
|
|
|
## Version History
|
|
| Date | Status | Author | Reviewer | Change | Commit |
|
|
| --- | --- | --- | --- | --- | --- |
|
|
| 2026-10-05 | Accepted | Jens Tirsvad Nielsen | S02 | Initial version | pending |
|
|
|
|
---
|
|
|
|
Concepts below use the IT terms of [DICT-001] for the PO concepts of [DM-001]. `Run`, `ToolCheck`, `PreflightResult` and `PromptSet` are system concepts with no PO term and are not in the Domain Model.
|
|
|
|
## Contract: startProjectCreation
|
|
|
|
| Item | Value |
|
|
| --- | --- |
|
|
| Operation | `startProjectCreation(): PromptSet` |
|
|
| Traces to | `startProjectCreation` in [SSD-001] |
|
|
| Concepts | Run, Configuration, ToolCheck |
|
|
|
|
**Preconditions**
|
|
|
|
- None; this is the first operation of a Run.
|
|
|
|
**Postconditions**
|
|
|
|
- P1. A `Run` instance was created.
|
|
- P2. A `Configuration` instance was created from `config.env` and `.env`, with every value validated and the credentials held only in memory.
|
|
- P3. A `ToolCheck` instance was created and associated with the `Run`, recording that `git` and `curl` are present and whether `jq` is present.
|
|
- P4. The `Run` was associated with a `PromptSet` that is returned.
|
|
|
|
**Exceptions**
|
|
|
|
| Condition (failing precondition) | Outcome |
|
|
| --- | --- |
|
|
| `config.env` or `.env` is missing, or a value is missing or malformed | The `Run` ends with an error naming the key, never its value; nothing was changed |
|
|
| `git` or `curl` is missing | The `Run` ends with an error naming the tool; nothing was changed |
|
|
|
|
## Contract: provideProjectDetails
|
|
|
|
| Item | Value |
|
|
| --- | --- |
|
|
| Operation | `provideProjectDetails(name: String, description: String, visibility: Visibility, giteaOwner: Owner, githubOwner: Owner [0..1], directory: Path, enablePlanGate: Boolean): Summary` |
|
|
| Traces to | `provideProjectDetails` in [SSD-001] |
|
|
| Concepts | ProjectRequest, PreflightResult, GiteaRepository, GitHubRepository, LicenseFile, PushMirror, LocalProject, Remote, Submodule, HookSetup, Summary |
|
|
|
|
**Preconditions**
|
|
|
|
- A `Run` exists and its `Configuration` is valid (from `startProjectCreation`).
|
|
- `githubOwner` is present exactly when the Maintainer chose GitHub.
|
|
|
|
**Postconditions**
|
|
|
|
- P1. A `ProjectRequest` instance was created with the given attributes and associated with the `Run`.
|
|
- P2. A `PreflightResult` instance was created and associated with the `ProjectRequest`, recording that each token needed for the chosen hosts works, that each owner accepts new repositories, that the name is free on the chosen hosts, that `AGPL-3.0` is offered by Gitea when GitHub was chosen, and the outcome of the SSH test to Gitea on port 10022.
|
|
- P3. A `GiteaRepository` instance was created under `giteaOwner` with the given name, description and visibility, and associated with the `ProjectRequest`.
|
|
- P4. If `githubOwner` is present, a `LicenseFile` instance for `AGPL-3.0` was created and associated with the `GiteaRepository`, so that repository is not empty. Otherwise the `GiteaRepository` has no `LicenseFile` and is empty.
|
|
- P5. If `githubOwner` is present, an empty `GitHubRepository` instance was created under `githubOwner` and associated with the `ProjectRequest`.
|
|
- P6. If `githubOwner` is present, a `PushMirror` instance was created, associated with the `GiteaRepository` as source and the `GitHubRepository` as target, with its effective sync setting recorded, and a first sync was requested.
|
|
- P7. A `LocalProject` instance was created at `directory`, associated with the `ProjectRequest`. If the `GiteaRepository` is not empty, the `LocalProject` holds its history, including the `LicenseFile` commit.
|
|
- P8. A `Remote` named `origin` was associated with the `LocalProject`, pointing at the `GiteaRepository` over SSH if the SSH test passed, otherwise over HTTPS, with no credential in its URL.
|
|
- P9. If `githubOwner` is present, a `Remote` named `github` was associated with the `LocalProject`, pointing at the `GitHubRepository`, with no credential in its URL.
|
|
- P10. A `Submodule` named `framework` was associated with the `LocalProject`.
|
|
- P11. A `HookSetup` instance was associated with the `LocalProject`, recording that skills and git hooks were installed once and, if `enablePlanGate`, that the plan gate was enabled.
|
|
- P12. `AGENTS.md` and `docs/artifact-registry.md` exist in the `LocalProject`, each either newly copied from the framework templates or left as it was because the Maintainer declined to replace it.
|
|
- P13. A `Summary` instance was created listing every created item, every skipped item and the next step for anything that failed, and is returned. It contains no credential.
|
|
|
|
**Exceptions**
|
|
|
|
| Condition (failing precondition) | Outcome |
|
|
| --- | --- |
|
|
| A token is invalid, an owner refuses new repositories, or the name is taken on a chosen host (P2) | The `Run` ends before P3; nothing was created; the error names the failed check |
|
|
| GitHub was chosen and Gitea does not offer `AGPL-3.0` (P2) | The `Run` ends before P3; nothing was created |
|
|
| `GiteaRepository` creation fails after a `GitHubRepository` was created (P5, P3 ordering) | The `Summary` lists the `GitHubRepository` as created, the `GiteaRepository` as failed and how to continue |
|
|
| `PushMirror` creation fails (P6) | The `Summary` lists both repositories as created, the mirror as failed and how to continue; the local steps are not run |
|
|
| `directory` exists, or a target file exists, and the Maintainer declines replacing it (P7, P12) | That item is skipped and listed in the `Summary` |
|
|
| A different `core.hooksPath` exists and the Maintainer declines replacing it (P11) | Hooks are not installed and this is listed in the `Summary` |
|
|
| SSH to port 10022 fails and the `Submodule` cannot be added (P10) | The `Summary` lists the repositories as created, the submodule as failed, and the SSH prerequisite |
|
|
|
|
---
|
|
|
|
[SSD-001]: ./ssd.md
|
|
[DM-001]: ./dm.md
|
|
[DICT-001]: ../dictionary.md
|
|
[SD-001]: ./sd.md
|