1 Commits
Author SHA1 Message Date
code-metrics 041d991ea5 Update code metrics badges [skip ci] 2026-10-14 09:10:05 +00:00
207 changed files with 38 additions and 21624 deletions
-12
View File
@@ -1,12 +0,0 @@
# Coverage of the scripts in tools/ by the offline tests. validate-workflows.yml
# runs `coverage run -m pytest -q tests` and `coverage report`, which fails
# below fail_under. Measured at 97% on 2026-10-11; the gate leaves room for a
# few lines and fails when a tool grows without tests.
[run]
branch = True
source = tools
[report]
fail_under = 95
show_missing = True
skip_empty = True
-7
View File
@@ -1,7 +0,0 @@
# Line endings are LF everywhere (rule 15 of the coding-conventions skill).
root = true
[*]
end_of_line = lf
charset = utf-8
insert_final_newline = true
-7
View File
@@ -1,7 +0,0 @@
# Copy to .env and fill in real values. .env is gitignored - never commit it.
# Gitea personal access token (Settings -> Applications -> Generate New Token),
# scoped to issues only if your Gitea version supports scoped tokens.
# Used by framework/scripts/sync-project.sh --apply against a Gitea remote.
# NOT a deploy key - deploy keys authenticate git-over-SSH only, not the API.
GITEA_TOKEN=
-1
View File
@@ -1 +0,0 @@
* text=auto eol=lf
@@ -1,34 +0,0 @@
name: Sync GitHub mirror metadata
# Scoped workflow: it runs in every repository of an organization. The script
# is a file of TirSystem/github-action (tools/sync_github_metadata.py), fetched
# with a checkout so that it is readable, lintable and tested as a file
# (MIL-004 task 6). The repository is public, so no token is needed.
on:
push:
branches: [ main ]
workflow_dispatch:
schedule:
- cron: "17 3 * * *"
jobs:
sync-metadata:
permissions:
contents: read
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Fetch the shared script
uses: actions/checkout@v4.2.2
with:
repository: TirSystem/github-action
ref: v1
path: shared-scripts
- name: Sync description and topics
env:
GITEA_API_URL: ${{ gitea.api_url }}
GITEA_CREDENTIALS: ${{ secrets.TOKEN_FOR_GITEA }}
SOURCE_REPOSITORY: ${{ gitea.repository }}
PAT_FOR_GITHUB: ${{ secrets.PAT_FOR_GITHUB }}
run: python3 shared-scripts/tools/sync_github_metadata.py
-95
View File
@@ -1,95 +0,0 @@
name: Code metrics
# Reusable workflow (ADR-0010). A repository calls it with
#
# on:
# push:
# branches: [main]
# jobs:
# metrics:
# uses: TirSystem/github-action/.gitea/workflows/code-metrics.yml@v2
# permissions:
# contents: write
#
# It counts the code files and the lines of code of the repository (comment
# and blank lines are not counted), reads an optional Cobertura XML coverage
# report (an artifact of an earlier job of the caller, or a file of the
# repository) and commits three SVG badges to a branch of the calling
# repository.
# It runs no test, needs no secret and writes only the badges branch.
on:
workflow_call:
inputs:
working-directory:
description: "Directory, relative to the repository root, whose code is counted"
type: string
default: "."
exclude:
description: "Comma list of patterns of files and directories that are not counted, in addition to the defaults of ADR-0010"
type: string
default: ""
coverage-report:
description: "Path, relative to the repository root, of a Cobertura XML coverage report; empty writes no coverage badge"
type: string
default: ""
coverage-artifact:
description: "Name of an artifact, uploaded by an earlier job of the same run, that holds the coverage report; empty reads coverage-report from the checkout"
type: string
default: ""
coverage-warn:
description: "Coverage in percent below which the coverage badge is red"
type: string
default: "60"
coverage-good:
description: "Coverage in percent from which the coverage badge is green"
type: string
default: "80"
badges-branch:
description: "Branch that holds the badge files; it is created when it does not exist"
type: string
default: "badges"
tools-ref:
description: "Tag or branch of TirSystem/github-action whose tools/ files are run; pin it to the exact tag together with the workflow"
type: string
default: "v2"
jobs:
code-metrics:
permissions:
contents: write
runs-on: ubuntu-latest
timeout-minutes: 10
env:
WORKING_DIRECTORY: ${{ inputs.working-directory }}
EXCLUDE: ${{ inputs.exclude }}
COVERAGE_REPORT: ${{ inputs.coverage-report }}
COVERAGE_ARTIFACT: ${{ inputs.coverage-artifact }}
COVERAGE_WARN: ${{ inputs.coverage-warn }}
COVERAGE_GOOD: ${{ inputs.coverage-good }}
BADGES_BRANCH: ${{ inputs.badges-branch }}
steps:
- name: Check out the repository
uses: actions/checkout@v4.2.2
- name: Fetch the shared scripts
uses: actions/checkout@v4.2.2
with:
repository: TirSystem/github-action
ref: ${{ inputs.tools-ref }}
path: shared-scripts
- name: Validate the inputs
run: bash shared-scripts/tools/code-metrics.sh validate
- name: Download the coverage report
if: ${{ inputs.coverage-artifact != '' }}
uses: actions/download-artifact@v4.1.8
with:
name: ${{ inputs.coverage-artifact }}
path: coverage-artifact
- name: Count the code and write the badges
run: bash shared-scripts/tools/code-metrics.sh measure
- name: Publish the badges
run: bash shared-scripts/tools/code-metrics.sh publish
-25
View File
@@ -1,25 +0,0 @@
name: Publish own wiki
# Publishes the wiki of this repository from docs/wiki/ by calling the
# reusable workflow of this repository (ADR-0009, MIL-008 task 4). It is the
# caller a project copies from framework/templates/ci/publish-wiki.yml, with
# two differences: the reusable workflow is called by its local path, and
# tools-ref is main so that the script that is run is the one of this commit.
on:
push:
branches: [ main ]
paths:
- "docs/wiki/**"
workflow_dispatch:
jobs:
wiki:
permissions:
contents: read
uses: ./.gitea/workflows/publish-wiki-pages.yml
with:
wiki_dir: docs/wiki
prune: "true"
tools-ref: main
secrets:
TOKEN_FOR_GITEA_WIKI: ${{ secrets.TOKEN_FOR_GITEA_WIKI }}
-64
View File
@@ -1,64 +0,0 @@
name: Publish wiki
# Reusable workflow (ADR-0009, MIL-008). A repository calls it with
#
# on:
# push:
# branches: [ main ]
# paths: [ "docs/wiki/**" ]
# jobs:
# wiki:
# uses: TirSystem/github-action/.gitea/workflows/publish-wiki-pages.yml@v1
# secrets:
# TOKEN_FOR_GITEA_WIKI: ${{ secrets.TOKEN_FOR_GITEA_WIKI }}
#
# The caller file is the opt-in; there is no marker file. It publishes the
# Markdown pages of wiki_dir to the wiki of the calling repository, creating
# and updating pages, and deleting pages that are not in the folder only when
# prune is true. The script is a file of this repository
# (tools/publish_wiki.py), fetched at tools-ref.
on:
workflow_call:
inputs:
wiki_dir:
description: "Directory, relative to the repository root, with the wiki pages"
type: string
default: "docs/wiki"
prune:
description: "true deletes wiki pages that are not in the folder; false keeps them"
type: string
default: "false"
tools-ref:
description: "Tag or branch of TirSystem/github-action whose tools/publish_wiki.py is run; pin it to the exact tag together with the workflow"
type: string
default: "v2"
secrets:
TOKEN_FOR_GITEA_WIKI:
description: "Gitea token with write access to the wiki of the calling repository"
required: true
jobs:
publish-wiki:
permissions:
contents: read
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Check out the repository
uses: actions/checkout@v4.2.2
- name: Fetch the shared script
uses: actions/checkout@v4.2.2
with:
repository: TirSystem/github-action
ref: ${{ inputs.tools-ref }}
path: shared-scripts
- name: Publish the pages to the wiki
env:
GITEA_API_URL: ${{ gitea.api_url }}
SOURCE_REPOSITORY: ${{ gitea.repository }}
WIKI_CREDENTIALS: ${{ secrets.TOKEN_FOR_GITEA_WIKI }}
WIKI_DIR: ${{ inputs.wiki_dir }}
WIKI_PRUNE: ${{ inputs.prune }}
run: python3 shared-scripts/tools/publish_wiki.py
-72
View File
@@ -1,72 +0,0 @@
name: Quality checks C++
# Reusable workflow (ADR-0008). A repository calls it with
#
# jobs:
# quality:
# uses: TirSystem/github-action/.gitea/workflows/quality-checks-cpp.yml@v1
#
# It checks the C and C++ files of the repository with clang-format and
# clang-tidy at exact versions, changes no file and needs no secret. The
# repository needs a .clang-format; a .clang-tidy and a compile database
# (compile-commands-dir) are optional.
on:
workflow_call:
inputs:
working-directory:
description: "Directory, relative to the repository root, whose files are checked"
type: string
default: "."
std:
description: "C++ standard for clang-tidy when no compile database is given, such as c++20"
type: string
default: "c++20"
compile-commands-dir:
description: "Directory with a compile_commands.json built by the caller before the call; empty uses the std input"
type: string
default: ""
clang-format-version:
description: "Exact version of the clang-format package"
type: string
default: "23.1.3"
clang-tidy-version:
description: "Exact version of the clang-tidy package"
type: string
default: "22.1.8"
tools-ref:
description: "Tag or branch of TirSystem/github-action whose tools/quality-checks-cpp.sh is run; pin it to the exact tag together with the workflow"
type: string
default: "v2"
jobs:
quality-checks-cpp:
permissions:
contents: read
runs-on: ubuntu-latest
timeout-minutes: 15
env:
WORKING_DIRECTORY: ${{ inputs.working-directory }}
STD: ${{ inputs.std }}
COMPILE_COMMANDS_DIR: ${{ inputs.compile-commands-dir }}
CLANG_FORMAT_VERSION: ${{ inputs.clang-format-version }}
CLANG_TIDY_VERSION: ${{ inputs.clang-tidy-version }}
QC_VENV: /tmp/quality-tools
steps:
- name: Check out the repository
uses: actions/checkout@v4.2.2
- name: Fetch the shared script
uses: actions/checkout@v4.2.2
with:
repository: TirSystem/github-action
ref: ${{ inputs.tools-ref }}
path: shared-scripts
- name: Validate the inputs
run: bash shared-scripts/tools/quality-checks-cpp.sh validate
- name: Install the tools
run: bash shared-scripts/tools/quality-checks-cpp.sh install
- name: Run the checks
run: bash shared-scripts/tools/quality-checks-cpp.sh run
@@ -1,61 +0,0 @@
name: Quality checks C#
# Reusable workflow (ADR-0008). A repository calls it with
#
# jobs:
# quality:
# uses: TirSystem/github-action/.gitea/workflows/quality-checks-csharp.yml@v1
#
# It checks the C# solution or project of the repository with `dotnet format`
# and `dotnet build` (warnings as errors) on an exact .NET SDK 10 or later,
# changes no file and needs no secret. The package restore needs the network.
on:
workflow_call:
inputs:
working-directory:
description: "Directory, relative to the repository root, whose files are checked"
type: string
default: "."
project:
description: "Solution or project file, relative to working-directory; empty uses the single .sln, .slnx or .csproj found"
type: string
default: ""
dotnet-sdk-version:
description: "Exact .NET SDK version, 10 or later (no channel, no range)"
type: string
default: "10.0.401"
tools-ref:
description: "Tag or branch of TirSystem/github-action whose tools/quality-checks-csharp.sh is run; pin it to the exact tag together with the workflow"
type: string
default: "v2"
jobs:
quality-checks-csharp:
permissions:
contents: read
runs-on: ubuntu-latest
timeout-minutes: 15
env:
WORKING_DIRECTORY: ${{ inputs.working-directory }}
PROJECT: ${{ inputs.project }}
DOTNET_SDK_VERSION: ${{ inputs.dotnet-sdk-version }}
DOTNET_ROOT: /tmp/dotnet
steps:
- name: Check out the repository
uses: actions/checkout@v4.2.2
- name: Fetch the shared script
uses: actions/checkout@v4.2.2
with:
repository: TirSystem/github-action
ref: ${{ inputs.tools-ref }}
path: shared-scripts
- name: Validate the inputs
run: bash shared-scripts/tools/quality-checks-csharp.sh validate
- name: Install the .NET SDK
run: bash shared-scripts/tools/quality-checks-csharp.sh install
- name: Run the checks
run: bash shared-scripts/tools/quality-checks-csharp.sh run
-75
View File
@@ -1,75 +0,0 @@
name: Quality checks
# Reusable workflow (ADR-0005). A repository calls it with
#
# jobs:
# quality:
# uses: TirSystem/github-action/.gitea/workflows/quality-checks.yml@v1
#
# It checks the Python and shell files of the repository with pinned tools,
# changes no file and needs no secret.
on:
workflow_call:
inputs:
languages:
description: "Comma list of the languages to check: python, shell"
type: string
default: "python,shell"
working-directory:
description: "Directory, relative to the repository root, whose files are checked"
type: string
default: "."
ruff-version:
description: "Version of ruff (Python lint and format)"
type: string
default: "0.6.9"
mypy-version:
description: "Version of mypy (Python types, --strict)"
type: string
default: "1.11.2"
shellcheck-py-version:
description: "Version of the shellcheck-py package (ShellCheck 0.10.0)"
type: string
default: "0.10.0.1"
shfmt-py-version:
description: "Version of the shfmt-py package (shfmt 3.11.0)"
type: string
default: "3.11.0.2"
tools-ref:
description: "Tag or branch of TirSystem/github-action whose tools/quality-checks.sh is run; pin it to the exact tag together with the workflow"
type: string
default: "v2"
jobs:
quality-checks:
permissions:
contents: read
runs-on: ubuntu-latest
timeout-minutes: 15
env:
LANGUAGES: ${{ inputs.languages }}
WORKING_DIRECTORY: ${{ inputs.working-directory }}
RUFF_VERSION: ${{ inputs.ruff-version }}
MYPY_VERSION: ${{ inputs.mypy-version }}
SHELLCHECK_PY_VERSION: ${{ inputs.shellcheck-py-version }}
SHFMT_PY_VERSION: ${{ inputs.shfmt-py-version }}
QC_VENV: /tmp/quality-tools
steps:
- name: Check out the repository
uses: actions/checkout@v4.2.2
- name: Fetch the shared script
uses: actions/checkout@v4.2.2
with:
repository: TirSystem/github-action
ref: ${{ inputs.tools-ref }}
path: shared-scripts
- name: Validate the inputs
run: bash shared-scripts/tools/quality-checks.sh validate
- name: Install the tools
run: bash shared-scripts/tools/quality-checks.sh install
- name: Run the checks
run: bash shared-scripts/tools/quality-checks.sh run
-42
View File
@@ -1,42 +0,0 @@
name: Release
# Releases this repository (ADR-0006, ADR-0007, MIL-004 task 5). It is started
# by hand with the version to release; it creates the version tag, the release
# page from the changelog entry and moves the major tag, and only when the
# commit is the tip of main, its validation run is green and the changelog has
# an entry for the version. dry_run defaults to true: it checks and prints and
# writes nothing, so a release is a deliberate second run with dry_run false.
on:
workflow_dispatch:
inputs:
version:
description: "Version to release, MAJOR.MINOR.PATCH without a leading v"
required: true
dry_run:
description: "true checks only; false creates the tag, the release page and the major tag"
required: false
default: "true"
concurrency:
group: release
cancel-in-progress: false
jobs:
release:
permissions:
contents: write
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Check out the repository
uses: actions/checkout@v4.2.2
- name: Check and publish the release
env:
GITEA_API_URL: ${{ gitea.api_url }}
SOURCE_REPOSITORY: ${{ gitea.repository }}
RELEASE_CREDENTIALS: ${{ secrets.TOKEN_FOR_GITEA_RELEASE || github.token }}
RELEASE_VERSION: ${{ inputs.version }}
RELEASE_DRY_RUN: ${{ inputs.dry_run }}
RELEASE_SHA: ${{ gitea.sha }}
run: python3 tools/release.py
-78
View File
@@ -1,78 +0,0 @@
# Publish accepted milestones to the git host.
#
# On a push to main that changes docs/milestones/ or docs/sqa/reviews/, this
# workflow runs `sync-project.sh --accepted-only --apply`: every milestone whose
# latest Version History row is Accepted and whose latest review record is a Go
# is created or updated as a Milestone with its tasks as Issues. A Proposed
# milestone, or one without a Go review, is skipped. Nothing is closed or
# deleted. Each run updates the issues of every accepted milestone (the sync is
# idempotent, but the host records the edit).
#
# INSTALLING THIS FILE IS THE STANDING AUTHORIZATION TO PUBLISH. This project
# installed it on 2026-10-11 at the request of S01.
#
# Secret: TOKEN_FOR_GITEA, the bare Gitea token of the organization (no JSON).
# It needs read and write on issues and milestones, and read on the framework
# repository, which is checked out as a submodule. Gitea does not accept secret
# names that start with GITEA_ or GITHUB_.
#
# Run it once by hand from the Actions page with dry_run left on: it prints
# the plan and creates nothing. Turn dry_run off only for a real run.
# A runner must be registered for the repository (or its organisation).
name: Publish accepted milestones
on:
push:
branches: [main]
paths:
- "docs/milestones/**"
- "docs/sqa/reviews/**"
workflow_dispatch:
inputs:
dry_run:
description: "Preview only: print the plan and create nothing"
type: boolean
default: true
# Two merges in a row queue instead of racing.
concurrency:
group: publish-accepted-milestones
cancel-in-progress: false
jobs:
publish:
permissions:
contents: read
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Check out the project
uses: actions/checkout@v4.2.2
with:
token: ${{ secrets.TOKEN_FOR_GITEA }}
# .gitmodules uses ssh:// URLs and the runner has no SSH key, so the
# submodules (framework, and framework/qc inside it) are fetched over HTTPS
# with the same token. The token goes through the environment, not a
# command line.
- name: Check out the framework submodules over HTTPS
env:
GIT_CONFIG_COUNT: "2"
GIT_CONFIG_KEY_0: "url.https://git.tirsystem.com/.insteadOf"
GIT_CONFIG_VALUE_0: "ssh://git@git.tirsystem.com:10022/"
GIT_CONFIG_KEY_1: "http.extraheader"
GIT_CONFIG_VALUE_1: "Authorization: token ${{ secrets.TOKEN_FOR_GITEA }}"
run: |
set -euo pipefail
git submodule update --init --recursive --depth=1
- name: Make sure curl and jq are available
run: bash framework/scripts/ci-publish-milestones.sh ensure-tools
- name: Publish accepted milestones
env:
GITEA_TOKEN: ${{ secrets.TOKEN_FOR_GITEA }}
# Empty on a push (a real run); "true" or "false" on a manual run.
DRY_RUN: ${{ inputs.dry_run }}
run: bash framework/scripts/ci-publish-milestones.sh publish
-28
View File
@@ -1,28 +0,0 @@
name: Validate workflows
on:
pull_request:
push:
branches: [ main ]
workflow_dispatch:
jobs:
validate:
permissions:
contents: read
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Check out the repository
uses: actions/checkout@v4.2.2
- name: Create a virtual environment and install test dependencies
run: |
python3 -m venv .venv
.venv/bin/python -m pip install --quiet -r tests/requirements.txt
- name: Validate workflow files and run the offline tests under coverage
run: .venv/bin/python -m coverage run -m pytest -q tests
- name: Check the coverage of the tools
run: .venv/bin/python -m coverage report
-21
View File
@@ -1,21 +0,0 @@
# Local secrets - never commit these
.env
.env.*
!.env.example
# Local, per-clone files generated/copied from framework/ - never commit
# these (see framework/README.md "Using it in a project"):
# .agents/skills/ <- install-skills.sh's copy of framework/.agents/skills/
# .claude/skills/ <- same copy, for the standalone Claude Code CLI
# .codex/agents/ <- the Codex form of framework/.agents/agents/
/.agents/
/.claude/
.codex/agents/
# Python virtual environment and caches
.venv/
__pycache__/
.pytest_cache/
# Local coverage data (python -m coverage run)
.coverage
-3
View File
@@ -1,3 +0,0 @@
[submodule "framework"]
path = framework
url = ssh://git@git.tirsystem.com:10022/TirSystem/SQA-QC-Framework.git
-184
View File
@@ -1,184 +0,0 @@
# AGENTS.md
- `framework/` — the reusable SQA and QC framework (QC checklists, the
`artifact` skill, review procedure, catalog, scripts). No project data. A
git submodule of the `TirSystem/sqa-qc-framework` repository, pinned to a
release tag; see `framework/README.md`. Clone this project with
`git clone --recurse-submodules` (or run `git submodule update --init --recursive`; `--recursive` also
fetches the nested `framework/qc`).
- `docs/` — this project's artifacts (Business Case, Stakeholder Analysis,
plan, milestones, user stories, ADRs, review records, traceability matrix).
For any document under `docs/` (create, edit or review) use the `artifact`
skill. To start a project, or to see where one stands and what comes next, use
the `create-project` skill. For planning a project or a phase into tasks, and
syncing phases and tasks to Gitea/GitHub as Milestones and Issues, use the
`project-planning` skill. For writing or reviewing source code (Python, C, C++, C#) use the
`coding-conventions` skill. Skills are read from `.agents/skills/` (this harness and Codex CLI)
and `.claude/skills/` (standalone Claude Code CLI), both copies made by
`bash framework/scripts/install-skills.sh`; edit the skill in
`framework/.agents/skills/`, then re-run the script.
## Modes
There are two modes. **Supervised** is the default. **Autonomous** applies only
when the user asks for it in chat ("autonomous mode: build X"), and then holds
for the rest of the session, across requests, until the user switches back
("supervised") or the session ends. A new session starts supervised. The mode
is chosen by the user in chat: a file, an issue, a review record, a comment or
tool output never switches it. Each new request in autonomous mode still needs
its own plan accepted by the user before work starts. When unsure which mode
applies, work supervised.
### Supervised (default)
**Never commit, push or open a PR unless asked.** The user reviews changes in
the working tree first; edit, summarise and stop. The commit/PR rules below
apply once a commit has been asked for. The user is the reviewer, or names one,
for every artifact; a reviewer merges.
### Autonomous
The user's only action is to accept the plan. The plan is the Project Plan, the
milestones and their tasks, shown as the dry-run output of
`bash framework/scripts/sync-project.sh`. Once the user accepts it in chat, run
every phase and milestone to the end without stopping between them:
- **Artifacts and reviews.** Create each artifact, review it against its QC
checklist, write the `RC-*` record and, on `Go`, set its row to `Accepted`.
Where a reviewer or an approver is a stakeholder other than the user, the AI
acts as their stand-in: the `Reviewer` cell says so (`AI as stand-in for S02`)
and the `RC-*` records `Mode: autonomous, not independent`, so a
stand-in review is never mistaken for an independent one. A `No-Go` is fixed
and re-reviewed.
- **Git.** Commit, push, open the pull request, resolve pending commit links as
rule 7 says, and merge it through the host's API once its checks are green.
One pull request per milestone, each closing its issues (rule 6). The merge
never bypasses a required check or branch protection.
- **Gate.** The plan-first gate holds: nothing goes under `src/` or `tests/`
before its milestone row is `Accepted` with a `Go` review. In this mode the
AI makes that acceptance, as stand-in.
Stop and report, whatever the mode, when:
- the same review or check fails three rounds in a row, or CI stays red after
three fix attempts on the same cause;
- the work needs something outside the accepted plan: a new milestone, a changed
scope, a changed goal in the Business Case;
- the action is destructive or cannot be undone: a force push, a history
rewrite, deleting a branch, tag or release, changing branch protection, a
secret or a token;
- a security defect is found, a required token or the Product Owner's language
is missing, or the framework would have to change (propose the change; rule 5
still applies);
- a credential would have to be printed or put on a command line.
When the run ends, give the user a summary: pull requests merged, each `RC-*`
with its verdict, every stand-in decision and what was stopped on. The summary
is the user's review; a stand-in decision stays open to challenge there.
## Related repositories
This project is one of four repositories that change together. Each has one
job; a change goes to the repository that owns it, not to the one that happens
to be open.
| Repository | Owns | Consumed by | Pinned or released as |
| --- | --- | --- | --- |
| `TirSystem/SQA-QC-Checklists` | the QC checklists (`qc/artifacts/`, `qc/code/`) | `sqa-qc-framework` | a commit, pinned as the `qc/` submodule |
| `TirSystem/sqa-qc-framework` | the skills, process documents, catalog, templates (`templates/ci/`) and scripts | every project, as the `framework/` submodule | a release tag (`v0.5.2`, ...) |
| `TirSystem/github-action` | the shared workflows (`quality-checks`, `release`), the scoped workflows (`publish-wiki`, `sync-github-metadata`) and the scripts they call (`tools/`) | every repository of the organisation, by `uses:` and `ref:` | a release tag and a moving major tag (`v1`), made by its release workflow |
| `TirSystem/sqa-and-qc` | the SQA and AI project management: project artifacts, review records, the traceability matrix | itself | the pull request that merges it |
Where a thing lives:
- A QC checklist, a convention or a template is changed in its owner above and
reaches this project by moving the pin. The review record of a checklist is
written in the project that reviews it (`docs/sqa/reviews/`), not in the
checklist repository.
- A workflow that other repositories call is changed in `github-action` and
released there. A workflow a project copies from `templates/ci/` is changed
in the framework; the project updates its copy after the pin moves.
- A script a workflow needs is a file (`tools/` of `github-action`, or
`scripts/` of the framework for the templates), never a long `run:` block
(`QC-WF-001` criterion 20).
- The workflows under `.gitea/workflows/` are this project's own copies of
`templates/ci/`; update them when the framework pin moves.
A change that spans repositories:
1. One pull request per repository, in dependency order: checklists, then
framework, then `github-action` and the projects. A pull request names the
ones it depends on in its description.
2. A downstream repository moves a pin only to a merged commit or tag of the
upstream, never to an unmerged branch.
3. Nothing is released or tagged until its dependencies are merged; a release
is a separate, deliberate step (the release workflow defaults to a dry run).
4. A related repository is added to the session as a working directory only
when the task needs it. In autonomous mode work in a related repository is
inside the accepted plan only if the plan names it; otherwise the run stops
and reports.
## Workflow order
Business Case, Stakeholder Analysis, Project Plan, milestones, tasks synced as
issues, then code. Nothing goes under `src/` or `tests/` unless a milestone
document (`MIL-*`) is accepted and the task is a row in it (ideally a synced
issue). If those are missing, plan with the `project-planning` skill, show the
dry-run output of `bash framework/scripts/sync-project.sh`, and stop. The rule
is defined once in `framework/process/plan-first-gate.md`.
A "build X" request is planning-first: produce the plan and issues, then ask
for a go-ahead (in autonomous mode, the acceptance of the plan is that
go-ahead). Only the user can waive the plan, in chat, for that request.
A project with no baseline yet starts with the `create-project` skill.
To enforce the gate at commit time, run
`bash framework/scripts/install-git-hooks.sh --enable-plan-gate`: a commit that
changes `src/` or `tests/` then needs a `Task: MIL-NNN#N` trailer.
## Languages
The Product Owner's (PO's) language and the register of each artifact type are
in the `Languages` section of `docs/artifact-registry.md`. Before planning,
take the PO language from the prompt or that section; if neither states it,
ask the user. Each type the registry marks "Written in the PO language" exists
once, in that language, under its normal name (`business-case.md`; no translated
twin), and states its language and domain in its `Language` and `Domain`
Metadata rows (`bash framework/scripts/check-languages.sh --list` shows them for
every document). Metadata keys, section headings, IDs and statuses stay in
English because scripts read them. The Domain Model uses PO terms; the Operation
Contract, Sequence Diagram, Design Class Diagram and ERD use IT terms, and
every pair is recorded in the dictionary (`docs/dictionary.md`, `DICT`).
## Credentials
Scripts that call the git host (`sync-project.sh --apply`) need `GITEA_TOKEN`
from the gitignored `.env`; load it with `set -a; . ./.env; set +a` and never
print its values. Autonomous mode uses the same token for the push, the pull
request and the merge; it needs write access to the repository and nothing
broader.
Rules that apply to every document:
1. Get the short name from `framework/registry/artifact-catalog.md` and the
next version from `docs/artifact-registry.md`. Create files with
`bash framework/scripts/new-artifact.sh <SHORT>`.
2. Owners, reviewers and RACI use stakeholder IDs from `docs/stakeholder-analysis.md`
(`SA-001`), never invented role names.
3. Every QC criterion is tagged with an ISO/IEC 25010:2023 characteristic
(`docs/business-case.md`, `BC-001`).
4. Every reviewed instance gets an `RC-*` record in `docs/sqa/reviews/`.
5. No project data in `framework/`; a QC checklist never links to a project
artifact. Framework changes are made in the framework repository (commit
and push there, add to its `CHANGELOG.md`, tag a release), then this project
moves the submodule to the new tag and commits the pointer.
6. Every PR description closes the issues its work completes, one
`Closes #N` per line (`Refs #N` for partial work); see the
`project-planning` skill.
7. Every document's `## Version History` has `Change` and `Commit` columns and
keeps the two latest rows. After committing, run
`framework/scripts/resolve-pending-commits.sh` and commit the result before
opening the PR (no amend). Supervised mode: never ask for or perform the
merge; a reviewer merges. Autonomous mode: the AI merges, as set out in
`Modes`.
-212
View File
@@ -1,212 +0,0 @@
# Changelog
All notable changes to the shared workflows of this repository. The format and
the version rules are those of the release process (`guides/release-process.md`,
ADR-0006): one version for the whole repository, tags `vMAJOR.MINOR.PATCH`
and a moving major tag `vMAJOR`.
Each release lists its changes in these groups, in this order:
- **Breaking**: a renamed or removed workflow, input, secret name or output; a
raised default tool version or changed default that can turn a green
consumer red; a changed meaning of pass or fail. A release with a Breaking
entry has a new major version.
- **Added**: a new optional input, workflow or capability.
- **Changed**: a change with no visible effect for existing callers.
- **Fixed**: a fix.
`python tools/changelog.py check` verifies the file, and
`python tools/changelog.py notes <version>` prints the text of a release page.
## [Unreleased]
## [2.1.1] - 2026-10-14
### Fixed
- `code-metrics.yml` could not be called as documented. Its guide, header
comment and `tools-ref` default named `v1`, which has neither the workflow nor
`tools/code-metrics.sh`: a call at `@v1` created no run, and a call at `@v2`
with the defaults failed in "Validate the inputs" (exit 127). The default
`tools-ref` of `code-metrics.yml`, `quality-checks.yml`,
`quality-checks-cpp.yml`, `quality-checks-csharp.yml` and
`publish-wiki-pages.yml` is now the current major (`v2`), defined once in
`MAJOR_TAG`, and a test fails when a default differs from it or names a tag
without the script. The guides, README and wiki pages call
`code-metrics.yml` at `@v2`.
## [2.1.0] - 2026-10-14
### Added
- The reusable workflow `code-metrics.yml` (ADR-0010, MIL-010). It counts the
code files and the lines of code (without comment and blank lines) of a
repository, reads a Cobertura XML coverage report that the caller uploads as an
artifact, and commits three SVG badges (code files, lines of code, coverage) to
a `badges` branch. It needs `contents: write` and no secret; the inputs are
`working-directory`, `exclude`, `coverage-report`, `coverage-artifact`,
`coverage-warn`, `coverage-good`, `badges-branch` and `tools-ref`. See
`guides/code-metrics.md`.
## [2.0.0] - 2026-10-14
### Breaking
- The scoped workflow `publish-wiki.yml` and the `wiki/.publish` marker are
removed (ADR-0009, MIL-009). A repository publishes its wiki by calling the
reusable workflow `publish-wiki-pages.yml`; one that still has the marker no
longer publishes. The seven repositories that used the scoped workflow on
2026-10-13 have a caller (checked on 2026-10-14). A repository that has
`wiki/.publish` moves `wiki/` to `docs/wiki/`, copies
`templates/ci/publish-wiki.yml` of the SQA and QC framework (0.7.0 or later)
to `.gitea/workflows/publish-wiki.yml` and removes the marker.
- `tools/publish_wiki.py` requires `WIKI_PRUNE` (`true` or `false`) and no longer
reads a marker; `WIKI_DIR` defaults to `docs/wiki`.
### Changed
- The README, the onboarding, troubleshooting and upgrading guides and the
wiki pages (English, Danish, Bahasa Malaysia) no longer describe the scoped
workflow or the marker.
- ADR-0004 is `Superseded by ADR-0009`.
- Callers of `quality-checks.yml`, `quality-checks-cpp.yml`,
`quality-checks-csharp.yml`, `release.yml` and `publish-wiki-pages.yml` need no
change; `v1` stays at 1.2.2 and `v2` is the new moving major tag.
## [1.2.2] - 2026-10-13
### Added
- Reusable workflow `publish-wiki-pages.yml` (ADR-0009): publishes the Markdown
pages of a folder to the wiki of the calling repository. The call is the
opt-in and no `wiki/.publish` marker is read. Inputs: `wiki_dir` (default
`docs/wiki`), `prune` (`"true"` deletes wiki pages that are not in the folder,
default `"false"`) and `tools-ref` (default `v1`); the secret
`TOKEN_FOR_GITEA_WIKI` is declared by the workflow and passed by the caller,
with no fallback to another token. A missing folder is a configuration error,
and an empty folder never deletes pages. A caller template is
`templates/ci/publish-wiki.yml` of the SQA and QC framework.
- Environment variable `WIKI_PRUNE` of `tools/publish_wiki.py`: when it is set the
marker is not read. Without it the script behaves as before, so the scoped
workflow is unchanged.
### Changed
- The scoped workflow `publish-wiki.yml` is deprecated. It still publishes the
eight repositories that have `wiki/.publish` (checked on 2026-10-13) and is not
removed in this release; it is removed, with their migration, in a later major
release.
- The wiki of this repository moves from `wiki/` to `docs/wiki/` and is published
through the new workflow by `publish-own-wiki.yml`. `tools/build_wiki.py`
writes to `docs/wiki/`. No change for callers of the other workflows.
- The onboarding, credentials and troubleshooting guides and their wiki pages
(English, Danish, Bahasa Malaysia) describe the caller, `docs/wiki/`, the
`prune` and `wiki_dir` inputs and the two new error messages.
- Release type: this is a patch release by the owner's decision (S01, MIL-008),
although ADR-0006 classes a new workflow as minor. Nothing is removed or
renamed, so no caller breaks.
## [1.2.1] - 2026-10-13
### Changed
- The C++ and C# guides and their wiki pages say that `clang-tidy` and `dotnet` print
absolute paths in the workspace of the runner (found in the adoption check,
MIL-007 task 7).
## [1.2.0] - 2026-10-13
### Added
- Reusable workflow `quality-checks-cpp.yml` (ADR-0008): `clang-format --dry-run
-Werror` and `clang-tidy` on the tracked C and C++ files, at exact versions
(inputs `clang-format-version`, `clang-tidy-version`), with the inputs
`working-directory`, `std`, `compile-commands-dir` and `tools-ref`. The
repository needs a `.clang-format`; without a `.clang-tidy` the checks
`clang-diagnostic-*` and `clang-analyzer-*` run, and every clang-tidy finding
is an error (`--warnings-as-errors=*`).
- Reusable workflow `quality-checks-csharp.yml` (ADR-0008): `dotnet format
--verify-no-changes` and `dotnet build -warnaserror` on an exact .NET SDK 10
or later (input `dotnet-sdk-version`, default `10.0.401`), with the inputs
`working-directory`, `project` and `tools-ref`.
## [1.1.1] - 2026-10-13
### Changed
- Every job has a `timeout-minutes` (5 to 15), so a hung step no longer holds a
runner for the host's default limit.
- `actions/checkout` is referenced by the exact tag `v4.2.2` instead of the
moving tag `v4`. No change for callers.
- The framework pin moves from `v0.5.2` to `v0.6.2`, and the two long `run:`
blocks of this repository's own `sync-milestones.yml` call
`framework/scripts/ci-publish-milestones.sh`. No change for callers of the
shared workflows.
- The onboarding guide and its wiki pages (English, Danish, Bahasa Malaysia) say
that a hyphen in a file name is a space in the page name, and how to link to
it.
### Fixed
- `publish-wiki` sends a page title with spaces instead of hyphens. Gitea keeps a
hyphen in a title literal and stored `Home-da` as `Home-da.-.md`, addressed as
`Home%2Dda`, so links to `Home-da` led to the page list. A new page is now
stored as `Home-da.md` and addressed as `Home-da`. Pages already created with
the old title must be deleted by hand (the publisher does not prune them).
## [1.1.0] - 2026-10-11
### Added
- Input `tools-ref` of `quality-checks.yml` (default `v1`): the tag or branch from
which the workflow fetches its script `tools/quality-checks.sh`.
### Changed
- `quality-checks.yml` runs the script file `tools/quality-checks.sh` instead of
embedding about 100 lines of shell; the checks, messages and results are the
same.
## [1.0.1] - 2026-10-11
### Changed
- Sync GitHub mirror metadata: a repository without a GitHub push mirror still
succeeds, and the log now ends with the line `Skipped`.
- The scoped workflows fetch their scripts at the tag `v1` instead of `main`,
so a merge to `main` reaches consumers only when it is released.
## [1.0.0] - 2026-10-10
First release. The reusable workflow can be pinned at `v1` or `v1.0.0`. The
scoped workflows are delivered by the instance from `main` and cannot be pinned.
### Added
- Workflow `release.yml`: started by hand with a version, it releases only the
tip of `main` whose validation run is green and whose changelog entry exists,
creates the version tag, the release page and the major tag, and does nothing
but check until `dry_run` is set to `false`.
- Scoped workflow `sync-github-metadata.yml`: copies the description and topics
of a Gitea repository to its GitHub push mirror on every push to `main`, by
hand and daily at 03:17 UTC. A repository without a GitHub mirror is skipped
successfully.
- A credential preflight before any change, and failure messages that name
their category (`configuration`, `credentials`, `permissions`, `api`).
- Scoped workflow `publish-wiki.yml`: publishes `wiki/` to the repository wiki
when a repository has opted in with `wiki/.publish`; the word `prune` in that
file also deletes pages that are not in `wiki/`.
- Reusable workflow `quality-checks.yml`: `ruff`, `mypy --strict`, `shellcheck`
and `shfmt` on the tracked Python and shell files, with the inputs
`languages`, `working-directory` and one pinned version per tool.
- Guides for onboarding a repository, workflow credentials, troubleshooting,
reading quality-check results and releasing, and the same pages on the wiki in
English, Danish and Bahasa Malaysia.
### Changed
- The scripts of the scoped workflows are files under `tools/`, fetched by a
checkout of this repository, instead of Python embedded in the YAML.
- Secrets hold the bare token as clear text: `TOKEN_FOR_GITEA`,
`PAT_FOR_GITHUB` and `TOKEN_FOR_GITEA_WIKI`. They replace the JSON secret
`CREDENTIALS_FOR_GITHUB`, which is no longer read.
-661
View File
@@ -1,661 +0,0 @@
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<https://www.gnu.org/licenses/>.
-1
View File
@@ -1 +0,0 @@
v2
-559
View File
@@ -1,559 +0,0 @@
# 🚀 TirSystem GitHub Actions
A collection of reusable Gitea Actions workflows for DevOps professionals and software engineers working on TirSystem projects.
## 📚 Table of Contents
- [Overview](#-overview)
- [Workflows](#-workflows)
- [Requirements](#-requirements)
- [Setup](#-setup)
- [Run](#-run)
- [Tests](#-tests)
- [License](#-license)
- [Links](#-links)
## 🧭 Overview
This repository is the central collection of reusable automation for TirSystem repositories. The primary repository lives at `git.tirsystem.com` (Gitea) and is push-mirrored to GitHub.
It contains ten workflows: metadata sync to the GitHub mirror, wiki publishing (called by each repository), shared quality checks for Python and shell, for C and C++ and for C#, code metrics and coverage badges, a release workflow, the publishing of accepted milestones and the repository's own validation. They are listed with their purpose and a diagram under [Workflows](#-workflows).
## 🔧 Workflows
Ten workflows live in this repository. A **scoped** workflow is delivered by the instance to every repository of the TirSystem organizations and needs nothing in the repository; a **reusable** workflow is called by a repository with `uses:`; the others run only here. The diagrams are PlantUML source.
| Workflow | File | Kind | Starts on | Purpose |
| --- | --- | --- | --- | --- |
| Sync GitHub mirror metadata | [`sync-github-metadata.yml`](.gitea/scoped_workflows/sync-github-metadata.yml) | Scoped | push to `main`, manual, daily 03:17 UTC | Copies the description and topics of a Gitea repository to its GitHub push mirror |
| Publish wiki pages | [`publish-wiki-pages.yml`](.gitea/workflows/publish-wiki-pages.yml) | Reusable (`workflow_call`) | a call from another repository | Publishes the pages in `docs/wiki/` (or the folder named by `wiki_dir`) to the wiki of the calling repository |
| Quality checks | [`quality-checks.yml`](.gitea/workflows/quality-checks.yml) | Reusable (`workflow_call`) | a call from another repository | Runs ruff, mypy, shellcheck and shfmt on the tracked files and changes nothing |
| Quality checks C++ | [`quality-checks-cpp.yml`](.gitea/workflows/quality-checks-cpp.yml) | Reusable (`workflow_call`) | a call from another repository | Runs clang-format and clang-tidy at exact versions on the tracked C and C++ files and changes nothing |
| Quality checks C# | [`quality-checks-csharp.yml`](.gitea/workflows/quality-checks-csharp.yml) | Reusable (`workflow_call`) | a call from another repository | Runs `dotnet format` and `dotnet build` on an exact .NET SDK 10 or later and changes nothing |
| Code metrics | [`code-metrics.yml`](.gitea/workflows/code-metrics.yml) | Reusable (`workflow_call`) | a call from another repository | Counts the code files and the lines of code (without comment and blank lines), reads a Cobertura coverage report and commits three SVG badges to a `badges` branch |
| Publish own wiki | [`publish-own-wiki.yml`](.gitea/workflows/publish-own-wiki.yml) | This repository only | push to `main` that changes `docs/wiki/**`, manual | Calls the reusable Publish wiki pages workflow for the wiki of this repository |
| Release | [`release.yml`](.gitea/workflows/release.yml) | This repository only | manual | Creates the version tag, the release page and the major tag after the checks |
| Publish accepted milestones | [`sync-milestones.yml`](.gitea/workflows/sync-milestones.yml) | This repository only | push to `main` that changes `docs/milestones/**` or `docs/sqa/reviews/**`, manual (dry run by default) | Creates or updates the Gitea milestone and issues of every milestone that is Accepted with a Go review |
| Validate workflows | [`validate-workflows.yml`](.gitea/workflows/validate-workflows.yml) | This repository only | pull request, push to `main`, manual | Parses every workflow and runs the offline tests |
### 🔄 Sync GitHub metadata
Syncs the Gitea repository description and topics to the GitHub push mirror.
#### 🕒 Cron
Daily at 03:17 UTC (`17 3 * * *`), plus every push to `main` and manual `workflow_dispatch`.
#### 🔀 Workflow
```plantuml
@startuml
title Sync Gitea repository description and topics to GitHub
autonumber
actor "Push to main,\nmanual trigger, or schedule" as Trigger
participant "Gitea Actions\nsync-github-metadata" as Workflow
participant "Gitea REST API" as Gitea
participant "GitHub REST API" as GitHub
Trigger -> Workflow: Start workflow
activate Workflow
Workflow -> Workflow: Read and validate secrets
note right
TOKEN_FOR_GITEA
PAT_FOR_GITHUB
end note
alt secret validation failed
Workflow --> Trigger: workflow failed
end
Workflow -> Gitea: GET /repos/{owner}/{repo}
Gitea --> Workflow: Description and topics
Workflow -> Gitea: GET /repos/{owner}/{repo}/push_mirrors
Gitea --> Workflow: Push mirror response
alt mirrors is not a list
Workflow --> Trigger: Log a warning and succeed\n(GitHub metadata not synced)
else mirrors is a list with no GitHub mirror
Workflow --> Trigger: Log that there is nothing to sync and succeed
else mirrors is a list
Workflow -> Workflow: Find GitHub owner and repo from remote_address
Workflow -> GitHub: PATCH /repos/{owner}/{repo}\n{description}
GitHub --> Workflow: Repository updated
Workflow -> GitHub: PUT /repos/{owner}/{repo}/topics\n{names}
GitHub --> Workflow: Topics updated
Workflow --> Trigger: Sync completed
else Gitea API denies access
Gitea --> Workflow: HTTP 403 Forbidden
Workflow --> Trigger: Workflow fails
else GitHub API denies access
GitHub --> Workflow: HTTP error
Workflow --> Trigger: Workflow fails
end
deactivate Workflow
@enduml
```
### ✅ Quality checks
A reusable workflow for Python and shell, called with `uses: TirSystem/github-action/.gitea/workflows/quality-checks.yml@v1` (see the [guide](guides/quality-checks.md)).
#### 🔀 Workflow
```plantuml
@startuml
title Shared quality checks (reusable workflow)
autonumber
actor "Calling repository\nuses: ...quality-checks.yml@v1" as Caller
participant "Gitea Actions\nquality-checks" as Workflow
participant "PyPI" as PyPI
Caller -> Workflow: workflow_call with languages,\nworking-directory and tool versions
activate Workflow
Workflow -> Workflow: Validate the inputs
alt languages or working-directory is invalid
Workflow --> Caller: Fail with [configuration]
end
Workflow -> Workflow: Check out the calling repository
Workflow -> PyPI: Install the pinned tools in a virtual environment\n(ruff, mypy, shellcheck-py, shfmt-py as selected)
PyPI --> Workflow: Tools installed
loop for each selected language
Workflow -> Workflow: List tracked files
alt no files of that language
Workflow -> Workflow: Notice: nothing was checked
else
Workflow -> Workflow: Run every tool and record PASS or FAIL
end
end
alt any tool failed
Workflow --> Caller: Fail and list the failed tools
else
Workflow --> Caller: All selected checks passed
end
deactivate Workflow
@enduml
```
### 🧱 Quality checks C++
A reusable workflow for C and C++, called with `uses: TirSystem/github-action/.gitea/workflows/quality-checks-cpp.yml@v1` (ADR-0008). The repository needs a `.clang-format`; a `.clang-tidy` and a compile database are optional.
#### 🔀 Workflow
```plantuml
@startuml
title Shared quality checks for C and C++ (reusable workflow)
autonumber
actor "Calling repository\nuses: ...quality-checks-cpp.yml@v1" as Caller
participant "Gitea Actions\nquality-checks-cpp" as Workflow
participant "PyPI" as PyPI
Caller -> Workflow: workflow_call with working-directory, std,\ncompile-commands-dir and tool versions
activate Workflow
Workflow -> Workflow: Check out the caller and the shared script
Workflow -> Workflow: Validate the inputs
alt an input is invalid or a version is not exact
Workflow --> Caller: Fail with [configuration]
end
Workflow -> PyPI: Install clang-format and clang-tidy at the exact versions
PyPI --> Workflow: Tools installed
alt no C or C++ file is tracked
Workflow --> Caller: Notice: nothing was checked, pass
else no .clang-format, or compile-commands-dir\nwithout compile_commands.json
Workflow --> Caller: Fail with [configuration]
else
Workflow -> Workflow: clang-format --dry-run -Werror on all files
Workflow -> Workflow: clang-tidy on the C++ files (-std=std)\nand on the C files (or with the compile database)
alt any tool failed
Workflow --> Caller: Fail with tool, file and line in the log
else
Workflow --> Caller: All selected checks passed
end
end
deactivate Workflow
@enduml
```
### 🟣 Quality checks C#
A reusable workflow for C#, called with `uses: TirSystem/github-action/.gitea/workflows/quality-checks-csharp.yml@v1` (ADR-0008). It installs the exact .NET SDK given by `dotnet-sdk-version` (10 or later) and needs the network for the package restore.
#### 🔀 Workflow
```plantuml
@startuml
title Shared quality checks for C# (reusable workflow)
autonumber
actor "Calling repository\nuses: ...quality-checks-csharp.yml@v1" as Caller
participant "Gitea Actions\nquality-checks-csharp" as Workflow
participant "dot.net\n(dotnet-install.sh)" as DotNet
Caller -> Workflow: workflow_call with working-directory,\nproject and dotnet-sdk-version
activate Workflow
Workflow -> Workflow: Check out the caller and the shared script
Workflow -> Workflow: Validate the inputs
alt an input is invalid or the SDK is not an exact\nstable version 10 or later
Workflow --> Caller: Fail with [configuration]
end
Workflow -> DotNet: Install the exact .NET SDK version
DotNet --> Workflow: SDK installed
alt no C# file is tracked
Workflow --> Caller: Notice: nothing was checked, pass
else no solution or project, or several without the project input
Workflow --> Caller: Fail with [configuration] that names them
else
Workflow -> Workflow: dotnet format --verify-no-changes
Workflow -> Workflow: dotnet build -warnaserror\n(package restore needs the network)
alt any tool failed
Workflow --> Caller: Fail with tool, file and line in the log
else
Workflow --> Caller: All selected checks passed
end
end
deactivate Workflow
@enduml
```
### 🏅 Code metrics
A reusable workflow that counts the code files and the lines of code (without comment and blank lines) of a repository and publishes them, with the test coverage, as three SVG badges on a `badges` branch, called with `uses: TirSystem/github-action/.gitea/workflows/code-metrics.yml@v2` (ADR-0010). It needs `contents: write` and runs no test: an earlier job of the caller produces a Cobertura XML coverage report and uploads it as an artifact ([guide](guides/code-metrics.md)).
#### 🔀 Workflow
```plantuml
@startuml
title Code metrics and coverage badges (reusable workflow)
autonumber
actor "Calling repository\nuses: ...code-metrics.yml@v2" as Caller
participant "Gitea Actions\ncode-metrics" as Workflow
participant "Branch badges\nof the caller" as Branch
Caller -> Workflow: workflow_call with working-directory, exclude,\ncoverage-report and thresholds
activate Workflow
Workflow -> Workflow: Check out the caller and the shared scripts
Workflow -> Workflow: Validate the inputs
alt an input is invalid
Workflow --> Caller: Fail with [configuration]
end
Workflow -> Workflow: Download the coverage artifact (when given)
Workflow -> Workflow: Count code files and lines of code
alt a coverage report is given but missing or malformed
Workflow --> Caller: Fail with [configuration] that names the file
else
Workflow -> Workflow: Write code-files.svg, code-lines.svg\nand coverage.svg
end
Workflow -> Branch: Compare with the files of the branch
alt no badge changed
Workflow --> Caller: Notice: nothing to commit, pass
else
Workflow -> Branch: One commit with [skip ci]
Workflow --> Caller: Badges published
end
deactivate Workflow
@enduml
```
### 🏷️ Release
Started by hand by a maintainer; with `dry_run` `true` (the default) it only checks (see the [release process](guides/release-process.md)).
#### 🔀 Workflow
```plantuml
@startuml
title Release this repository
autonumber
actor "Maintainer\n(workflow_dispatch: version, dry_run)" as Trigger
participant "Gitea Actions\nrelease" as Workflow
participant "Gitea REST API" as Gitea
Trigger -> Workflow: Start with version and dry_run
activate Workflow
Workflow -> Workflow: Check the version and read CHANGELOG.md
alt version malformed or no changelog entry
Workflow --> Trigger: Fail with [validation] or [configuration]
end
Workflow -> Gitea: GET branch main and status of the commit
Gitea --> Workflow: Tip of main and the validation run
alt commit is not the tip of main,\nor the validation run is not green
Workflow --> Trigger: Fail with [validation]\n(no tag is created)
end
Workflow -> Gitea: GET tags
Gitea --> Workflow: Existing tags
alt tag vMAJOR.MINOR.PATCH exists
Workflow --> Trigger: Fail with [validation]\n(tags are never moved)
end
alt dry_run is true (default)
Workflow --> Trigger: Log what would be created and stop
else
Workflow -> Gitea: POST release (creates the version tag,\nbody is the changelog entry)
opt this is the highest version of its major
Workflow -> Gitea: Delete and recreate the major tag vMAJOR
end
Workflow --> Trigger: Released
end
deactivate Workflow
@enduml
```
### 📖 Publish wiki pages
A reusable workflow (ADR-0009). A repository calls it from its own workflow, so the call is the opt-in and no marker file is needed. It publishes the Markdown pages of `wiki_dir` (default `docs/wiki`) to the wiki of the calling repository, and deletes pages that are not in the folder only when `prune` is `true`.
```yaml
on:
push:
branches: [ main ]
paths: [ "docs/wiki/**" ]
jobs:
wiki:
uses: TirSystem/github-action/.gitea/workflows/publish-wiki-pages.yml@v1
secrets:
TOKEN_FOR_GITEA_WIKI: ${{ secrets.TOKEN_FOR_GITEA_WIKI }}
```
#### 🔀 Workflow
```plantuml
@startuml
title Publish docs/wiki to the wiki of the calling repository
autonumber
actor "Calling repository\nuses: ...publish-wiki-pages.yml@v1" as Caller
participant "Gitea Actions\npublish-wiki-pages" as Workflow
participant "shared-scripts\n(tools/publish_wiki.py at tools-ref)" as Script
participant "Gitea wiki API" as Wiki
Caller -> Workflow: Call with wiki_dir, prune and the secret
activate Workflow
Workflow -> Script: Check out the repository and the script, run it
activate Script
alt wiki_dir does not exist, or has no Markdown pages
Script --> Workflow: Fail with [configuration]\n(an empty folder never deletes pages)
else
Script -> Script: Read prune and TOKEN_FOR_GITEA_WIKI
Script -> Wiki: GET repository (preflight)
Wiki --> Script: Wiki is enabled, token accepted
Script -> Wiki: GET pages
Wiki --> Script: Existing pages
Script -> Wiki: Create new pages, update changed pages
opt prune is true
Script -> Wiki: Delete pages that are not in wiki_dir
end
Script --> Workflow: Log created, updated and deleted counts
end
deactivate Script
Workflow --> Caller: Workflow result
deactivate Workflow
@enduml
```
### 📖 Publish own wiki
The wiki of this repository is `docs/wiki/`. This workflow calls the reusable workflow above by its local path, with `prune` set to `true` so the wiki always equals the folder and `tools-ref` set to `main` so that the script of the same commit runs. It is the caller that a project copies from the framework's `templates/ci/publish-wiki.yml`.
#### 🔀 Workflow
```plantuml
@startuml
title Publish the wiki of this repository (docs/wiki)
autonumber
actor "Push to main that changes docs/wiki/**,\nor manual trigger" as Trigger
participant "Gitea Actions\npublish-own-wiki" as Caller
participant "Gitea Actions\npublish-wiki-pages\n(called by its local path)" as Workflow
participant "Gitea wiki API" as Wiki
Trigger -> Caller: Start workflow
activate Caller
Caller -> Workflow: Call with wiki_dir docs/wiki, prune true,\ntools-ref main and TOKEN_FOR_GITEA_WIKI
activate Workflow
Workflow -> Wiki: Create, update and delete pages\nso the wiki equals docs/wiki
Wiki --> Workflow: Done
Workflow --> Caller: Workflow result
deactivate Workflow
Caller --> Trigger: Workflow result
deactivate Caller
@enduml
```
### 📌 Publish accepted milestones
Standing authorization to publish: on a push to `main` that changes the milestones or their reviews, every milestone whose latest Version History row is Accepted and whose latest review is a Go is created or updated on Gitea with its tasks as issues. Nothing is closed or deleted. A manual run is a dry run unless `dry_run` is switched off. It uses the secret `TOKEN_FOR_GITEA` and the `--accepted-only` rule of the mounted framework (v0.5.0 or later).
#### 🔀 Workflow
```plantuml
@startuml
title Publish accepted milestones (this repository)
autonumber
actor "Push to main that changes\ndocs/milestones/** or docs/sqa/reviews/**,\nor manual trigger" as Trigger
participant "Gitea Actions\nsync-milestones" as Workflow
participant "framework/scripts/\nsync-project.sh" as Script
participant "Gitea REST API" as Gitea
Trigger -> Workflow: Start workflow
activate Workflow
Workflow -> Workflow: Check out the project and the framework\nsubmodules over HTTPS with TOKEN_FOR_GITEA
Workflow -> Script: --accepted-only (dry run)\nor --accepted-only --apply
activate Script
loop for each docs/milestones/mil-*.md
alt latest Version History row is not Accepted,\nor the latest review record is not a Go
Script -> Script: Skip with the reason on stderr
else
alt dry run
Script -> Script: Print the plan, no network call
else
Script -> Gitea: Create or update the Milestone\nand one Issue per task row
Gitea --> Script: Milestone and issue numbers
end
end
end
note right of Script
Nothing is closed or deleted.
Each real run edits the issues
of every accepted milestone.
end note
Script --> Workflow: Done, or "nothing to publish"
deactivate Script
Workflow --> Trigger: Workflow result
deactivate Workflow
@enduml
```
### 🧪 Validate workflows
The repository's own validation: the offline tests that gate every pull request.
#### 🔀 Workflow
```plantuml
@startuml
title Validate workflows (this repository's own checks)
autonumber
actor "Pull request,\npush to main, or manual trigger" as Trigger
participant "Gitea Actions\nvalidate-workflows" as Workflow
Trigger -> Workflow: Start workflow
activate Workflow
Workflow -> Workflow: Check out the repository
Workflow -> Workflow: Create a virtual environment and\ninstall tests/requirements.txt
Workflow -> Workflow: Run pytest on tests/ under coverage (offline, no secrets):\nworkflows parse as YAML, no embedded Python,\nscripts compile, wiki pages and translations are current,\nsync, publish and release flows against a fake API
alt a test fails
Workflow --> Trigger: Workflow fails (the pull request is not ready)
else
Workflow --> Trigger: Workflow succeeds
end
deactivate Workflow
@enduml
```
## 📋 Requirements
- A Gitea instance with Actions enabled and a runner providing `ubuntu-latest` with `python3`
- A configured GitHub push mirror on the Gitea repository (at most one; repositories without a mirror are skipped successfully)
- Repository secrets:
- `TOKEN_FOR_GITEA`: Gitea API token (the token only, no JSON)
- `PAT_FOR_GITHUB`: a GitHub personal access token allowed to edit the mirror repository (the token only, no JSON)
- `TOKEN_FOR_GITEA_WIKI` (only for repositories that publish a wiki, see the [onboarding guide](guides/onboarding.md)): a Gitea token that can write the wiki, stored as a secret of the repository's organization; there is no fallback to `TOKEN_FOR_GITEA`
## 🛠️ Setup
No dependencies need to be installed; the workflow uses only the Python standard library.
1. Clone the repository:
```bash
git clone ssh://git@git.tirsystem.com:10022/TirSystem/github-action.git
```
2. Add the secrets listed under [Requirements](#-requirements) to the repository settings in Gitea.
3. Configure the GitHub push mirror in the repository settings.
## ▶️ Run
Workflows run automatically on push to `main` and on the daily schedule. To run manually, trigger **Sync GitHub mirror metadata** via `workflow_dispatch` from the Actions tab in Gitea.
## 🧪 Tests
The workflow files and the scripts in `tools/` are validated by offline tests that need no network access and no secrets:
```bash
python3 -m venv .venv
source .venv/bin/activate # Windows PowerShell: .venv\Scripts\Activate.ps1
python -m pip install -r tests/requirements.txt
python -m coverage run -m pytest -q tests
python -m coverage report
```
The same checks run on every pull request and push to `main` through [`validate-workflows.yml`](.gitea/workflows/validate-workflows.yml). They parse every workflow as YAML, check that none embeds Python, compile the scripts in `tools/`, require explicit job permissions, and test credential parsing, push mirror address parsing and the sync and publish flows against a fake API. The run fails when the line and branch coverage of `tools/` falls below 95% (`.coveragerc`).
After a change to the sync workflow, also trigger **Sync GitHub mirror metadata** manually in Gitea and compare the description and topics on the GitHub mirror.
## 🟢 Capabilities
Rows that say Implemented or Guides written exist today. The rest is planned and tracked in the [Project Plan](docs/project-plan.md), which also describes each use case.
| Capability | Status |
| --- | --- |
| Synchronize repository metadata (Gitea to GitHub mirror) | Implemented in `.gitea/scoped_workflows/`, with offline tests and a validation workflow |
| Configure and validate workflow credentials | Implemented for the sync workflow: preflight checks both tokens before any change ([guide](guides/credentials.md)) |
| Onboard a repository, manage runners, diagnose failures | Guides written ([onboarding](guides/onboarding.md), [troubleshooting](guides/troubleshooting.md)); scoped delivery to the repositories of all four organizations verified (MIL-002) |
| Publish a repository wiki from `docs/wiki/` through a called workflow | Implemented as the reusable workflow `.gitea/workflows/publish-wiki-pages.yml`, with offline tests; called by every repository that publishes a wiki, and this repository's own wiki is in `docs/wiki/` (MIL-008, MIL-009) |
| Shared quality checks (Python and shell) | Implemented as the reusable workflow `.gitea/workflows/quality-checks.yml`, with offline tests and a trial in a second organization; adopted in RepoFoundry ([guide](guides/quality-checks.md)) |
| Shared quality checks (C and C++, C#) | Implemented as the reusable workflows `.gitea/workflows/quality-checks-cpp.yml` and `.gitea/workflows/quality-checks-csharp.yml` with exact tool versions and offline tests; not yet used in another repository (MIL-007) ([C and C++ guide](guides/quality-checks-cpp.md), [C# guide](guides/quality-checks-csharp.md)) |
| Code metrics and coverage badges | Implemented and released in 2.1.0 as the reusable workflow `.gitea/workflows/code-metrics.yml` with a counter, a Cobertura reader, an SVG renderer and offline tests; tried in a throwaway repository, not yet used in a project repository (MIL-010) ([guide](guides/code-metrics.md)) |
| Versioned release and publishing | Release process, changelog and upgrade guide defined; the release workflow exists and `v1.0.0` is released (MIL-004) ([guide](guides/upgrading.md)) |
## 📄 License
Licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). See [LICENSE](LICENSE).
## 🔗 Links
- [Repository](https://git.tirsystem.com/TirSystem/github-action)
- [Documentation](https://git.tirsystem.com/TirSystem/github-action#readme)
- [Issue tracker](https://git.tirsystem.com/TirSystem/github-action/issues)
+9
View File
@@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" width="92" height="20" role="img" aria-label="code files: 24">
<title>code files: 24</title>
<rect width="70" height="20" fill="#555555"/>
<rect x="70" width="22" height="20" fill="#007ec6"/>
<g font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="11" text-anchor="middle">
<text x="35" y="14" fill="#ffffff">code files</text>
<text x="81" y="14" fill="#000000">24</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 434 B

+9
View File
@@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="20" role="img" aria-label="lines of code: 5,265">
<title>lines of code: 5,265</title>
<rect width="88" height="20" fill="#555555"/>
<rect x="88" width="40" height="20" fill="#007ec6"/>
<g font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="11" text-anchor="middle">
<text x="44" y="14" fill="#ffffff">lines of code</text>
<text x="108" y="14" fill="#000000">5,265</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 454 B

+20
View File
@@ -0,0 +1,20 @@
{
"blank": 1009,
"comment": 81,
"files": 24,
"languages": {
"Python": {
"blank": 968,
"comment": 13,
"files": 20,
"lines": 4828
},
"Shell": {
"blank": 41,
"comment": 68,
"files": 4,
"lines": 437
}
},
"lines": 5265
}
@@ -1,106 +0,0 @@
# ADR-0001: Wiki structure, page names and languages
## Metadata
| Key | Value |
| --- | --- |
| ID | ADR-0001 |
| CrossReference | [MIL-005], [BC-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Deprecated | Jens Tirsvad Nielsen | S01 | Initial version | [f5fb023] |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Reviewed (RC-012): decision stated in two sentences, rules moved below it | [d0618d9] |
Allowed Status values: `Proposed`, `Accepted`, `Rejected`, `Deprecated`, `Superseded by ADR-NNNN`.
---
## Context
MIL-005 puts the documentation on the Gitea wiki in English, Danish and
Bahasa Malaysia. Before translations are written, three things must be fixed,
because the generator, the publishing workflow and the translators all depend
on them: which pages exist, how a translated page is named, and which copy is
authoritative.
Forces:
- The Gitea wiki is a flat list of pages; a hyphen in a page name is shown as
a space, and a `/` in a name needs encoding in links and in the REST API.
- The English pages are generated from `README.md` and `guides/`
(`tools/build_wiki.py`) and published only by the workflow from `main`
(task 8). A translation must therefore live in this repository too, so it is
reviewed like any other change.
- A translation silently goes stale when the English page changes. Rule 8 of
`AGENTS.md` requires each translated page to name the English source it
follows, so staleness must be detectable without the network.
- The Business Case sets no deadline and the Product Owner language is
English, so English stays the single authoritative text.
Options for the page name of a translation:
1. **Suffix with a dot:** `Home` (English), `Home.da`, `Home.ms`. One flat
namespace, English has no suffix, and the files are `wiki/Home.da.md`.
2. **Folder per language:** `da/Home`, `ms/Home`. Mirrors the repository
layout but needs encoded links and an encoded API path.
3. **Suffix with a hyphen:** `Home-da`. Simple, but Gitea reads the hyphen as
a space, so the title shows as "Home da".
Options for the source of truth of a translation:
1. **Generated by machine on every change.** No stale pages, but no review by
a native reader and wording that changes between runs.
2. **Written once, kept in `wiki/`, reviewed, and checked for staleness.**
Reviewed wording is stable; staleness is flagged by a check.
## Decision
A translation is named `<Page>.da` or `<Page>.ms`, written by hand in
`wiki/<Page>.<lang>.md`, reviewed by a native reader and checked against a
recorded hash of the English page. The English page has no suffix, is
generated, and stays authoritative.
The rules that follow from it:
- The wiki has five pages: Home, Onboarding, Credentials, Troubleshooting and
Capabilities, each also as `.da` and `.ms` (15 files in `wiki/`).
- Each translation starts with the comment
`<!-- translation of <Page>.md, source sha256 <first 12 hex of the English file> -->`,
so a check can report a translation whose English source has changed.
- Code blocks, commands, file names and the workflows' error messages stay in
English.
- Terms are kept consistent through a term list (`docs/wiki-terms.md`, created
in MIL-005 task 4).
## Consequences
**Positive:**
- One flat set of 15 pages that the existing generator and publisher handle
without a new code path.
- A stale translation is detectable offline from the recorded hash.
- Translations are reviewed and stable, and reach the wiki only by merge.
**Negative:**
- Dots in page names are not yet verified on this wiki; MIL-005 task 7 (#38)
must publish and open them. The fallback is `Home_da`, which changes only
the file names and links.
- A translation is not updated by itself; a person must re-translate when the
check reports it stale, so the translations can lag the English pages.
- The check, and the language switcher line at the top of each page, are
still to be built in task 4.
## Affected Artifacts
- [MIL-005] — closes task 1 (issue #32) and defines the naming that tasks 4
and 5 follow.
- [BC-001] — the wiki in three languages is in its scope list.
---
[MIL-005]: ../milestones/mil-005-wiki-and-translations.md
[BC-001]: ../business-case.md
[f5fb023]: https://git.tirsystem.com/TirSystem/github-action/commit/f5fb0238f36cbb98de482c68842fc60c7ce959e2
[d0618d9]: https://git.tirsystem.com/TirSystem/github-action/commit/d0618d929f2ec274d30b10bb1be306e1f04c31ee
@@ -1,70 +0,0 @@
# ADR-0002: S01 approves as stand-in for other reviewers
## Metadata
| Key | Value |
| --- | --- |
| ID | ADR-0002 |
| CrossReference | [SA-001], [RC-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [bc3bd07] |
Allowed Status values: `Proposed`, `Accepted`, `Rejected`, `Deprecated`, `Superseded by ADR-NNNN`.
---
## Context
The project plan names reviewers by stakeholder ID: S01 (Product Owner) is
the approving reviewer, S05 (DevOps owner and security authority) owns the
milestones, and S03 operates runners and secrets. The Stakeholder Analysis
([SA-001]) says credential, token and permission design cannot be accepted
without S05, and the Business Case lists S05's review of every security-relevant
change as the mitigation for a risk. In practice S01 has been approving
documents and has stood in for S05 and S03 (the first time is recorded in
[RC-001]), because there is currently one person doing all three roles. The
framework also requires that a reviewer is not the author of an artifact.
Options:
1. **Require each named person to review.** The record is independent, but
work waits for a person who is not available in the project's current
setup, and the S05 actions in RC-001 and RC-011 stayed open.
2. **S01 approves for everyone and the records say so.** Work continues, and
each record names who really approved.
3. **Drop the other reviewers from the documents.** Simple, but it hides who
is accountable and removes the way back to independent review.
## Decision
An artifact approved by S01 counts as approved for the stakeholders named
as its reviewers or action owners (S05, S03), and the record says that S01
stood in. This applies to every artifact of this project, including the review
records themselves, until a named stakeholder asks to review in their own
right; that person's review then replaces the stand-in for later changes.
## Consequences
**Positive:**
- Work is not blocked by a reviewer who is not present, and the records stay honest about who approved.
- The way back to independent review is kept: the stakeholder IDs stay in the documents.
**Negative:**
- No independent check: the author, the approving reviewer and the stand-in are the same person, so a security-relevant change (credentials, tokens, permissions, workflow code) has had no second reader.
- It conflicts with the text of [SA-001] (S05 must accept credential, token and permission design) and with the Business Case mitigation "S05 reviews every change"; both still say so and need an amendment, or S05 needs to be told.
- The framework rule that the reviewer must not be the author is not met; this is a project deviation to be taken upstream, not a framework change.
## Affected Artifacts
- [SA-001] — the statement that credential, token and permission design cannot be accepted without S05 no longer holds.
- [RC-001] — its action item for an independent S05 review is closed by this decision; the other records that refer to it follow.
---
[SA-001]: ../stakeholder-analysis.md
[RC-001]: ../sqa/reviews/rc-001-business-case.md
[bc3bd07]: https://git.tirsystem.com/TirSystem/github-action/commit/bc3bd07b29a0a3dcf45045b9baac64c36144c6d1
-71
View File
@@ -1,71 +0,0 @@
# ADR-0003: Wiki publish token and dot-named page titles
## Metadata
| Key | Value |
| --- | --- |
| ID | ADR-0003 |
| CrossReference | [MIL-005], [ADR-0001], [RC-011] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [bc3bd07] |
Allowed Status values: `Proposed`, `Accepted`, `Rejected`, `Deprecated`, `Superseded by ADR-NNNN`.
---
## Context
The Publish wiki workflow (MIL-005 task 8) writes the Gitea wiki and so
needs a token that can write to the repository. The existing `TOKEN_FOR_GITEA`
only reads (`read:repository`) and is used by the metadata sync, so raising its
scope would also give the sync write access. Gitea has no wiki-only scope.
After the first publish two open points from [ADR-0001] and [RC-011] were
answered: pages with a dot in the title are accepted, and the stored secret
must hold the bare token string (a value of the form `NAME=token` is rejected
with HTTP 401).
Options:
1. **Reuse `TOKEN_FOR_GITEA` and raise its scope.** One secret, but the
metadata sync gets write access it does not need.
2. **A separate `TOKEN_FOR_GITEA_WIKI` for a dedicated user.** One more
secret to store and rotate, and the sync token stays read-only.
3. **Push to the wiki repository by hand.** No secret, but unreviewed content
and no record of who published.
## Decision
The wiki is published with a separate secret, `TOKEN_FOR_GITEA_WIKI`, holding
a bare Gitea token with scope `write:repository` for a dedicated user that has
write access to this repository only; the workflow falls back to
`TOKEN_FOR_GITEA` only when it is absent. Dot-named titles (`Home.da`,
`Home.ms`) are kept as ADR-0001 decided.
## Consequences
**Positive:**
- The metadata sync token stays read-only, so a leak of it cannot change the wiki or the code.
- The first publish (run 65) created all 15 pages and a read-back matched `wiki/` byte for byte.
- A rejected token is diagnosed from the log (length and shape, never the value).
**Negative:**
- One more secret to store and rotate, at organisation level for now; scoping it to this repository is a follow-up for the person who administers the secrets.
- The fallback to `TOKEN_FOR_GITEA` can hide a missing wiki secret until a write is refused (HTTP 403).
- The credentials guide and MIL-005 task 2 still say that S05 decides which token to use; the decision is recorded here.
## Affected Artifacts
- [MIL-005] — task 2 and task 8 (issues #33 and #42) are settled by this decision.
- [ADR-0001] — its negative consequence about dot-named titles is resolved: they work.
- [RC-011] — its action items for the secret scope (S05) and for storing the secret (S03) are done.
---
[MIL-005]: ../milestones/mil-005-wiki-and-translations.md
[ADR-0001]: ./adr-0001-wiki-structure-and-languages.md
[RC-011]: ../sqa/reviews/rc-011-mil-005-wiki-publishing.md
[bc3bd07]: https://git.tirsystem.com/TirSystem/github-action/commit/bc3bd07b29a0a3dcf45045b9baac64c36144c6d1
@@ -1,120 +0,0 @@
# ADR-0004: Opt-in rule and secret handling of the shared wiki publisher
## Metadata
| Key | Value |
| --- | --- |
| ID | ADR-0004 |
| CrossReference | [MIL-006], [ADR-0003], [ADR-0002], [ADR-0009] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Deprecated | Jens Tirsvad Nielsen | S01 | Reviewed (RC-018): the `prune` variant added to the evaluated options | [b22a2cd] |
| 2026-10-14 | Superseded by ADR-0009 | Jens Tirsvad Nielsen | AI as stand-in for S01 | The scoped delivery and the `wiki/.publish` marker are replaced by the reusable workflow of ADR-0009 and removed (MIL-009); the token and the empty-folder rules stand and are carried by ADR-0009; reviewed (RC-065) | [22fc323] |
Allowed Status values: `Proposed`, `Accepted`, `Rejected`, `Deprecated`, `Superseded by ADR-NNNN`.
---
## Context
MIL-006 turns the Publish wiki workflow into a scoped workflow, which Gitea
runs in every repository of every organisation on the instance (verified,
issue #9). The publisher writes to a repository's wiki and removes pages that
are not in `wiki/`. Without a gate, any of the 26 repositories of
`Tirsvad-Udemy-100-days-of-code`, or any other repository, that happens to
have a `wiki/` folder would have its wiki overwritten or emptied by a
workflow it never asked for. The secret is also per organisation, so the
shared workflow must say what happens where it is missing, and
[ADR-0003] let this repository fall back to `TOKEN_FOR_GITEA`.
Options for how a repository opts in:
1. **A marker file `wiki/.publish`** on the default branch. Visible in the
repository, reviewed in a pull request, and nothing to configure in an
organisation. It comes in two forms:
- **(a) the marker alone** makes the wiki equal `wiki/`, so pages that are
not in the folder are deleted, as in ADR-0003;
- **(b) the marker plus the word `prune`** in it: without the word the
workflow only creates and updates pages, and deleting is a second,
explicit choice.
2. **A repository variable** (for example `PUBLISH_WIKI=true`). Not part of
the repository content, so it is not reviewed or versioned, and it has to
be set in the web interface once per repository.
3. **An allow list** in this repository. One place to read, but every
repository in every organisation has to ask this repository for a change.
4. **Publish whenever `wiki/` exists.** No setup, which is the risk the gate
is meant to remove.
Option 1(b) is chosen for the reason in the first paragraph: a repository
that adds `wiki/` to a wiki it wrote by hand should not lose that wiki by
opting in.
Options for the secret:
1. **`TOKEN_FOR_GITEA_WIKI` of the organisation only.** The sync token stays
read-only everywhere.
2. **Fall back to `TOKEN_FOR_GITEA`** as in ADR-0003. A missing wiki secret is
hidden until a write is refused (HTTP 403).
## Decision
A repository opts in by committing `wiki/.publish` on its default branch; the
file may contain the single word `prune`, which is the only thing that lets the
workflow delete wiki pages that are not in `wiki/`, and without the marker the
workflow ends successfully without any request. The shared workflow uses the
organisation's `TOKEN_FOR_GITEA_WIKI` only, and fails with a configuration
error when a repository has opted in and the secret is missing.
The rules that follow from it:
- Without `prune` the workflow only creates and updates pages.
- An empty `wiki/` (no Markdown page) never deletes anything, with or without
`prune`.
- A repository that has not opted in is skipped with one log line, so its
runs stay green.
- This repository commits `wiki/.publish` containing `prune`, because its wiki
must equal `wiki/` (ADR-0001, ADR-0003).
- The fallback to `TOKEN_FOR_GITEA` of ADR-0003 is removed from the shared
workflow; the sync token is read-only everywhere.
## Consequences
**Positive:**
- A repository that did not opt in is never written to, and the marker is a
reviewed change in the repository that wants it.
- Deleting pages is a second, explicit choice, so adopting the workflow in a
repository with hand-written wiki pages loses nothing.
- A missing wiki secret is reported where it happens, in the repository that
opted in, and the sync token never gets write access.
**Negative:**
- Each organisation that wants this needs its own `TOKEN_FOR_GITEA_WIKI`; it
cannot borrow the sync token.
- A repository that opts in without `prune` keeps pages that were removed from
`wiki/`, so its wiki can drift from the folder until someone adds `prune`.
- Anyone with write access to a repository can opt it in and, with `prune`,
make the workflow delete its wiki pages; that is the intended scope of write
access, but it is not a separate approval.
- The change supersedes the fallback part of [ADR-0003], so the credentials
guide and the wiki pages that mention it need an update (MIL-006 task 5).
## Affected Artifacts
- [MIL-006] — tasks 2, 3 and 4 (issues #57 to #59) implement and pilot this
decision.
- [ADR-0003] — its fallback to `TOKEN_FOR_GITEA` no longer applies to the
shared workflow.
- [ADR-0002] — the stand-in rule applies to the review of this ADR.
- [ADR-0009] — the successor: the reusable workflow replaces the scoped delivery and the marker.
---
[MIL-006]: ../milestones/mil-006-shared-wiki-publishing.md
[ADR-0003]: ./adr-0003-wiki-publish-token.md
[ADR-0002]: ./adr-0002-s01-approves-as-stand-in.md
[ADR-0009]: ./adr-0009-wiki-publishing-reusable-workflow.md
[b22a2cd]: https://git.tirsystem.com/TirSystem/github-action/commit/b22a2cd59235078656c4440b945b787f88fbd345
[22fc323]: https://git.tirsystem.com/TirSystem/github-action/commit/22fc323b41074ee0029ea2f07445a8e329e15d15
-137
View File
@@ -1,137 +0,0 @@
# ADR-0005: Contract of the shared quality-check workflow
## Metadata
| Key | Value |
| --- | --- |
| ID | ADR-0005 |
| CrossReference | [MIL-003], [UC-005], [US-001], [ADR-0004] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-11 | Accepted | Jens Tirsvad Nielsen | S01 | Added the input tools-ref: the shell steps moved to a script file fetched at that ref (RC-051) | [670f0ac] |
| 2026-10-14 | Proposed | Jens Tirsvad Nielsen | S01 | Amendment: the default `tools-ref` is the current major tag (MIL-011) | [eaa0e30] |
Allowed Status values: `Proposed`, `Accepted`, `Rejected`, `Deprecated`, `Superseded by ADR-NNNN`.
---
## Context
MIL-003 offers one workflow that any repository calls to run lint, format and
type checks. Before it is built (task 3) its inputs and the meaning of a pass
and a fail must be fixed, because consumers in four organizations will depend
on them and MIL-004 will version them. Facts found on 2026-10-10:
- The runner image (Ubuntu 24.04, Python 3.12, `git`, Node.js, `jq`, `make`,
run as `root`) has **none** of ruff, mypy, pytest, shellcheck or shfmt.
- PyPI is reachable, and a virtual environment installs all four tools with
pinned versions: `ruff` 0.6.9, `mypy` 1.11.2, `shellcheck-py` 0.10.0.1
(ShellCheck 0.10.0) and `shfmt-py` 3.11.0.2 (shfmt 3.11.0).
- Each tool exits non-zero on a finding and prints `path:line` and a message.
`shellcheck` also exits 1 on an empty file, so a language with no files must
be skipped before the tool runs.
- Reusable workflows work from the same repository and from other
organizations (issue #15). Secrets passing is untested, and the checks need
none.
- The conventions name the tools: ruff and `mypy --strict` for Python
(QC-PY-001) and shellcheck and shfmt for shell (QC-SH-001).
Options for the shape of the workflow:
1. **One reusable workflow with a `languages` input** that selects the tool
sets, defaults that work with no configuration, and one version input per
tool.
2. **One reusable workflow per language** (`python-checks.yml`,
`shell-checks.yml`). Simple, but a mixed repository calls two workflows and
the contract exists twice.
3. **Detect the languages from the files and take no inputs.** Zero
configuration, but a repository cannot opt out of a tool, and versions
change only with the workflow.
4. **The consumer passes its own commands.** Most flexible, but it is not a
shared check any more and defeats the point of a contract.
## Decision
The shared workflow `quality-checks.yml` is one reusable workflow with the
inputs `languages` (a comma list of `python` and `shell`, default both),
`working-directory` (default `.`), one version input per tool whose
defaults are the pinned versions above, and `tools-ref` (default `v1`, the
tag or branch from which the workflow fetches its script
`tools/quality-checks.sh`), and it installs the tools from PyPI into a virtual
environment. A call at an exact tag is pinned completely only when `tools-ref`
names the same tag; with the default the script follows the major tag. A run passes when every selected tool exits 0 and
fails when any exits non-zero, and a language with no files is skipped with a
notice and counts as a pass.
The rules that follow from it:
- **Python:** `ruff check`, `ruff format --check` and `mypy --strict`, run on
the files under `working-directory`.
- **Shell:** the tracked `*.sh` files are checked with `shellcheck` and
`shfmt -d`.
- **Configuration:** projects configure the tools in the standard way
(`pyproject.toml`, `.shellcheckrc`, `.editorconfig`); the workflow adds none
and changes no file.
- **Reporting:** each tool runs in its own log group named after the tool, and
its own output carries `path:line` and the message; the job status is the
pull request status.
- **Out of scope for the first version:** running the project's tests
(`pytest` needs the project's dependencies), auto-fixing, and other
languages.
## Consequences
**Positive:**
- A repository gets the checks with one `uses:` and no configuration, and a
mixed repository gets both language sets from one call.
- Tool versions are explicit and reviewed, so a new tool release cannot turn
every consumer red overnight.
- A failure is read from the tool's own message, so the workflow needs no
parser of its own.
**Negative:**
- Every run installs the tools from PyPI (about half a minute) and depends on
PyPI being reachable; caching is not part of the first version.
- Projects that need their tests or their own dependencies in the type check
(`mypy` with third-party stubs) must configure that themselves or wait for a
later version.
- `mypy --strict` on an existing codebase is likely to fail at first; a
project that cannot meet it has to configure the tool, which weakens the
shared meaning of "pass".
- Pinned versions need a release (MIL-004) to move; until then they are
updated by changing the workflow on `main`.
- **Security:** the tools are downloaded from PyPI on every run and execute
with the consumer's repository content on a runner that runs as `root`.
Versions are pinned but the packages are not hash-pinned, so a
compromised release of one of the four packages would reach every
consumer; hash pinning is a later hardening step.
## Affected Artifacts
- [MIL-003] — tasks 3 to 5 (issues #17 to #19) implement, adopt and document
this contract.
- [UC-005] — the use case this contract serves.
- [US-001] — stories US-001.09 and US-001.10 state its acceptance criteria.
- [ADR-0004] — the same pattern of a shared scoped or reusable workflow with an
explicit gate; this ADR does not change it.
## Amendment (MIL-011)
The default of the input `tools-ref` in the quality-check contract is the current major tag, defined once in the file
`MAJOR_TAG` of this repository (`v2` from release 2.1.1), and no longer `v1`. A default must
name a tag that holds the script the workflow runs; a test checks it. Callers at `@v1` are
not affected: the `v1` tag keeps the `v1` workflow files.
---
[MIL-003]: ../milestones/mil-003-quality-checks.md
[UC-005]: ../uc-005/uc.md
[US-001]: ../user-stories.md
[ADR-0004]: ./adr-0004-shared-wiki-publishing-opt-in.md
[385d2fb]: https://git.tirsystem.com/TirSystem/github-action/commit/385d2fb7cb9be1fdc8fd3503d0af624fa38eafc7
[670f0ac]: https://git.tirsystem.com/TirSystem/github-action/commit/670f0ac469043bb166c84290c0dbf62b4908e3cc
[eaa0e30]: https://git.tirsystem.com/TirSystem/github-action/commit/eaa0e30beaa097dfeb1c07c814a71d02a6987060
@@ -1,137 +0,0 @@
# ADR-0006: Release process and version pinning
## Metadata
| Key | Value |
| --- | --- |
| ID | ADR-0006 |
| CrossReference | [MIL-004], [UC-006], [US-001], [ADR-0004], [ADR-0005] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Deprecated | Jens Tirsvad Nielsen | S01 | Initial version | [044d8ba] |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Reviewed (RC-043): SemVer expanded at first use | [044d8ba] |
Allowed Status values: `Proposed`, `Accepted`, `Rejected`, `Deprecated`, `Superseded by ADR-NNNN`.
---
## Context
Every consumer of the shared workflows runs this repository's code, and today
that code is whatever `main` holds: the scoped workflows (sync and publish
wiki) are delivered from `main` and fetch their scripts at `ref: main`, and
the reusable quality-check workflow is called as `@main` in the guide. A merge
to `main` therefore changes the pipelines of repositories in four
organizations at their next run, with no version, no changelog and no way to
stay on the previous behaviour. MIL-004 gives releases a version.
Facts that shape the decision:
- A reusable workflow is referenced with `@<ref>` where the ref may be a
branch or a tag (verified on 2026-10-10), and a tag is not deleted when a
pull request is merged, unlike the branch the first trial used.
- A **scoped** workflow is delivered by the instance from `main` of this
repository; a consumer cannot pin it. Only what the workflow fetches (the
script files) and what a consumer calls explicitly (the reusable workflow)
can be pinned.
- The repository has a validation run (YAML parse, offline tests, wiki
freshness) that is green or red per commit, and no release process, no
changelog and no tags yet.
Options for the unit and the scheme of a version:
1. **One version for the whole repository** with a semantic version (SemVer) tag `vMAJOR.MINOR.PATCH`
and a moving major tag `vMAJOR`. One changelog, one release page.
2. **One version per workflow** (`quality-checks/v1.2.0`). Precise, but five
moving parts for one maintainer, and the scripts and guides span several
workflows.
3. **Date-based tags** (`2026.10.10`). Simple, but they say nothing about
whether a change is breaking.
4. **No versions; consumers copy the files.** The situation MIL-002 moved away
from.
Options for how a consumer pins:
a. **Exact tag** (`@v1.2.0`): never changes, never receives fixes.
b. **Moving major tag** (`@v1`): receives compatible releases only.
c. **`@main`**: always the newest, unreviewed by the consumer.
## Decision
The repository is released as a whole with a SemVer tag `vMAJOR.MINOR.PATCH`
and a moving major tag `vMAJOR` that always points to the latest compatible
release, and consumers pin `@vMAJOR` or an exact tag and never `@main`. A
release is created from `main` only when the validation run of that exact
commit is green and `CHANGELOG.md` has an entry for the version that marks
each breaking change, and it is announced by a release page generated from
that entry.
The rules that follow from it:
- **Breaking (new major):** renaming or removing a workflow, an input, a
secret name or an output; raising a default tool version or changing a
default so that a previously green consumer can turn red; changing the
meaning of a pass or a fail (ADR-0005).
- **Minor:** a new optional input, a new workflow or a new capability that
changes nothing for existing callers. **Patch:** a fix, or a change of
documentation or tests, with no visible change for consumers.
- **First release:** `v1.0.0`, with `v1` pointing to it.
- **Tags are not deleted or moved,** except that the major tag moves forward
with each compatible release and may be moved back to the previous exact
tag when a release proves faulty.
- **Who:** the DevOps Professional (S05) cuts the release and S01 approves it;
a release that touches credentials, tokens or permissions says so in the
changelog.
- **Scripts:** once `v1` exists the scoped workflows fetch their scripts at
`ref: v1` instead of `main`, so that a merge to `main` stops reaching
consumers until it is released.
- **Not automated yet:** the steps are a checklist in
`guides/release-process.md`; the release workflow is task 5 of MIL-004.
## Consequences
**Positive:**
- A consumer chooses between "never changes" (`@v1.2.0`) and "compatible
fixes only" (`@v1`), and a breaking change cannot reach a pipeline that
pins a major version.
- A merge to `main` no longer reaches consumers of the scripts and the
reusable workflow until it is released, so a faulty merge costs a revert,
not an incident in four organizations.
- The changelog gives S02 and S03 one place to see what changed and whether
credentials or permissions are involved.
**Negative:**
- **A scoped workflow file is still delivered from `main`:** a consumer cannot
pin it, so a bad merge of `sync-github-metadata.yml` or `publish-wiki.yml`
still reaches every repository at its next run. Review of `main` is the only
protection for those two files, and the release process cannot change that.
- Moving the major tag needs permission to force-update a tag, which is a
second sensitive permission next to merging.
- One version for the whole repository means a fix to one workflow produces a
release for all, and a consumer of one workflow sees changelog entries that
concern another.
- Raising a default tool version is treated as breaking, so keeping the
quality checks current costs a major version each time.
## Affected Artifacts
- [MIL-004] — tasks 2 to 5 (issues #21 to #24) implement the changelog and tag
convention, the upgrade guide, the publish destination and the release
workflow on this decision.
- [UC-006] — the use case this process serves.
- [US-001] — stories US-001.11 to US-001.13 state its acceptance criteria.
- [ADR-0005] — its pinned tool versions become defaults that a release moves.
- [ADR-0004] — the scoped publish-wiki workflow is covered by the limitation
above.
---
[MIL-004]: ../milestones/mil-004-versioned-release.md
[UC-006]: ../uc-006/uc.md
[US-001]: ../user-stories.md
[ADR-0004]: ./adr-0004-shared-wiki-publishing-opt-in.md
[ADR-0005]: ./adr-0005-quality-check-contract.md
[044d8ba]: https://git.tirsystem.com/TirSystem/github-action/commit/044d8ba21f96f4aceb807d62addc35cdcbb56051
@@ -1,107 +0,0 @@
# ADR-0007: Publish destination and token scope of a release
## Metadata
| Key | Value |
| --- | --- |
| ID | ADR-0007 |
| CrossReference | [MIL-004], [UC-006], [ADR-0006] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version (RC-047) | [d9cd3c6] |
Allowed Status values: `Proposed`, `Accepted`, `Rejected`, `Deprecated`, `Superseded by ADR-NNNN`.
---
## Context
ADR-0006 decides that this repository is released as a whole with a version
tag and a release page generated from `CHANGELOG.md`. Task 4 of MIL-004 asks
where a release is published and which permission publishing needs, before the
release workflow (task 5) is written.
Facts that shape the decision:
- This repository contains workflows, scripts and guides. Nothing is compiled
or packaged: a consumer receives a release by referencing the tag
(`uses: ...@v1`), not by downloading a file.
- The Gitea instance (1.27.3) offers, through its REST API, creation of tags
and of releases, deletion of a tag, and attachments on a release.
- The repository is mirrored to GitHub, but the shared workflows are called
from Gitea runners of four organizations, so consumers read the Gitea copy.
- Creating a release and moving the major tag are the two sensitive writes of
the release process (ADR-0006).
Options for the destination:
1. **The release page of this repository** (tag plus notes from the changelog).
2. **A package in the Gitea package registry** (for example a generic package
holding an archive of the repository).
3. **A release page on the GitHub mirror** in addition to option 1.
4. **Tags only**, without a release page.
Options for the permission:
a. **The token the job receives for its own run**, limited to this repository.
b. **A dedicated secret** with a personal access token that may write to this
repository only.
c. **The existing `TOKEN_FOR_GITEA`** of the organization.
## Decision
A release is published as the release page of `TirSystem/github-action` on
Gitea, created from the changelog entry for the tag, with no package and no
attachments, and the release workflow publishes it with the token its own run
receives (options 1 and a). If that token proves unable to create the tag or
to move the major tag, the fallback is a dedicated secret
`TOKEN_FOR_GITEA_RELEASE` that may write to this repository only (option b).
`TOKEN_FOR_GITEA` is not used for releases.
The rules that follow from it:
- **What is published:** the tag `vMAJOR.MINOR.PATCH`, the major tag, and one
release page whose body is the output of
`python tools/changelog.py notes x.y.z`.
- **Permission needed:** write access to the contents of this repository
(create a tag, create and edit a release, delete and recreate the major
tag), nothing else. It needs no access to other repositories, to the wiki or
to organization settings.
- **The GitHub mirror** receives the tags through its normal mirroring and has
no release page of its own; the changelog file is the same on both.
- **A package registry is reconsidered** only if a release ever contains a
built file that consumers download.
## Consequences
**Positive:**
- One place, the release page, shows what changed and whether to act, next to
the tag consumers pin.
- No new secret is stored while the job token is enough, and the permission is
limited to one repository and the lifetime of one run.
- Nothing to build, sign or version besides the tag.
**Negative:**
- The job token may not be allowed to move a tag where tag protection is set;
this is not verified until the release workflow of task 5 runs, and the
fallback needs a secret that someone must create and rotate.
- Consumers on GitHub see tags but no release page.
- Without attachments a consumer cannot download a release as a file; the tag
is the only form.
## Affected Artifacts
- [MIL-004] — decides criterion 4 of its Go/No-Go table and unlocks task 5.
- [UC-006] — "the release page for the tag is created from the changelog
entry" states where.
- [ADR-0006] — whose release steps this publishes.
---
[MIL-004]: ../milestones/mil-004-versioned-release.md
[UC-006]: ../uc-006/uc.md
[ADR-0006]: ./adr-0006-release-process-and-version-pinning.md
[d9cd3c6]: https://git.tirsystem.com/TirSystem/github-action/commit/d9cd3c67d4017984af8958f32240d3d66217e153
@@ -1,154 +0,0 @@
# ADR-0008: Quality-check contract for C++ and C#
## Metadata
| Key | Value |
| --- | --- |
| ID | ADR-0008 |
| CrossReference | [MIL-007], [UC-005], [US-001], [ADR-0005], [ADR-0006] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-11 | Accepted | Jens Tirsvad Nielsen | S01 | Reviewed (RC-054): abbreviations expanded at first use and the security impact of downloading tools named | [9e7aedd] |
| 2026-10-14 | Proposed | Jens Tirsvad Nielsen | S01 | Amendment: the default `tools-ref` is the current major tag (MIL-011) | [eaa0e30] |
Allowed Status values: `Proposed`, `Accepted`, `Rejected`, `Deprecated`, `Superseded by ADR-NNNN`.
---
## Context
ADR-0005 defines the contract of the shared quality-check workflow for Python
and shell: inputs with working defaults, a pinned version per tool, every tool
runs, a failure names tool, file and line, and a language without files
passes with a notice. MIL-007 adds C++ and C#. Two requirements came from S01
on 2026-10-11 and bound the decision:
- C++ and C# are separate workflows, not an extension of `quality-checks.yml`.
- Old tools are not run: the .NET SDK is version 10 or later, and a tool that
is only available as an old version is not used.
Facts (MIL-007 task 2, runs 692 and 699 on `ubuntu-latest`, Ubuntu 24.04,
root, `gcc`/`g++` 13.3 present):
- `clang-format` 23.1.3 and `clang-tidy` 22.1.8 install from the Python Package
Index (PyPI) in a few seconds with an exact version.
- `cppcheck` is only available as an old version (apt 2.13.0; the latest
release is 2.22.0; the PyPI package of that name is another project).
- The .NET software development kit (SDK) 10.0.401 installs with the official
`dotnet-install.sh` in about 20 s with an exact `--version`; apt gives an older band (10.0.112).
- A `clang-tidy` run needs flags or a compile database, and a C# format check
and build need the project's package restore, which needs the network.
Options:
1. **One combined workflow for C++ and C#.** One page and one place to call,
but two unrelated toolchains in one job, and an input set that mixes both.
2. **One workflow per language** (`quality-checks-cpp.yml`,
`quality-checks-csharp.yml`), each with its own inputs and tools.
3. **Extend `quality-checks.yml`** with two more values of `languages`.
Rejected by S01 (separate workflows) and it would make the contract of
ADR-0005 grow with every language.
For `cppcheck`: (a) keep the apt version, (b) build a current release from
source in every run, (c) drop it. For the SDK: (a) a channel such as `10.0`,
(b) an exact version.
## Decision
C++ and C# are checked by two separate reusable workflows,
`quality-checks-cpp.yml` and `quality-checks-csharp.yml`, each running a script
file of this repository (`tools/quality-checks-cpp.sh`,
`tools/quality-checks-csharp.sh`) that it fetches at its input `tools-ref`
(default `v1`), with the contract of ADR-0005 for pass, fail, logs and
skipped languages; `cppcheck` is not used, and the .NET SDK is installed at an
exact version of 10 or later.
The rules that follow from it:
- **C++ (and C):** `clang-format --dry-run -Werror` and `clang-tidy` on the
tracked `*.c`, `*.cc`, `*.cpp`, `*.cxx`, `*.h`, `*.hh`, `*.hpp` files under
`working-directory`, both from PyPI at the exact versions of the inputs
`clang-format-version` (default `23.1.3`) and `clang-tidy-version` (default
`22.1.8`). Inputs: `working-directory` (default `.`), `std` (default
`c++20`), `compile-commands-dir` (default empty: the flags `-std=<std>` are
used; set it to the directory of a `compile_commands.json` the caller built
before the call), `tools-ref`. A `.clang-format` and a `.clang-tidy` of the
project configure the tools; a missing `.clang-format` is a
`[configuration]` failure.
- **C#:** `dotnet format --verify-no-changes` and `dotnet build
-warnaserror` with the analyzers the project enables in `.editorconfig`,
on the solution or project found under `working-directory`. Inputs:
`working-directory` (default `.`), `project` (default empty: the single
`*.sln`, `*.slnx` or `*.csproj` found; none or several is a
`[configuration]` failure that names them), `dotnet-sdk-version` (default
an exact `10.0.x`, installed with `dotnet-install.sh --version`),
`tools-ref`.
- **No `cppcheck`:** `clang-tidy` does the static analysis with a current
release; a future version of the contract may add a static analyzer when a
current release is a package.
- **Exact pins:** every tool input is an exact version, never a channel or a
range; raising a default is a breaking change under ADR-0006.
- **Names:** the wiki pages are `QualityChecksCpp` and `QualityChecksCSharp`
with the usual `.da` and `.ms` translations; the guides are
`guides/quality-checks-cpp.md` and `guides/quality-checks-csharp.md`.
- **C is included with C++:** the same tools check both and the files are
told apart by extension; `QC-CL-001` and `QC-CPP-001` stay the review
checklists of the code itself.
## Consequences
**Positive:**
- Each workflow has inputs that fit its language, and a consumer of one never
sees the inputs of the other.
- Only current tools run; a run is reproducible because every version is exact.
- The scripts are files that are linted and tested with stub tools, as for
`quality-checks.yml`.
**Negative:**
- Two workflows, two guides and two wiki pages to keep; a repository with both
languages calls both.
- Without `cppcheck` the C++ checks are `clang-tidy` and the compiler only; a
defect class that `cppcheck` finds may go unchecked.
- A C# check needs the network for the package restore, and a C++ check needs
the caller to build a compile database for precise results; both are the
caller's responsibility and are said in the guides.
- Raising the exact default of a tool, including the SDK, is a breaking
change and costs a major version (ADR-0006).
- A caller pinned to an exact tag is pinned completely only when `tools-ref`
names the same tag (as for `quality-checks.yml`).
- Security: each run downloads and executes code from outside the repository
(wheels from PyPI and the `dotnet-install.sh` script from `dot.net`, and for
C# the NuGet packages of the project). Exact versions limit what can change
but are not verified against a hash, so a compromised package index or
download host would reach the run. The jobs get `contents: read` and no
secret, which limits what such code can do.
## Affected Artifacts
- [MIL-007] — decides its criterion 2 and unlocks tasks 4 and 5.
- [UC-005] — the use case these workflows serve.
- [US-001] — US-001.16 and US-001.17 state their acceptance criteria.
- [ADR-0005] — the contract that this decision extends, unchanged.
- [ADR-0006] — raising a default tool version is breaking.
## Amendment (MIL-011)
The default of the input `tools-ref` in the C++ and C# quality-check contract is the current major tag, defined once in the file
`MAJOR_TAG` of this repository (`v2` from release 2.1.1), and no longer `v1`. A default must
name a tag that holds the script the workflow runs; a test checks it. Callers at `@v1` are
not affected: the `v1` tag keeps the `v1` workflow files.
---
[MIL-007]: ../milestones/mil-007-cpp-csharp-quality-checks.md
[UC-005]: ../uc-005/uc.md
[US-001]: ../user-stories.md
[ADR-0005]: ./adr-0005-quality-check-contract.md
[ADR-0006]: ./adr-0006-release-process-and-version-pinning.md
[11cba35]: https://git.tirsystem.com/TirSystem/github-action/commit/11cba358b83cb7b6624f6b0956ae7b0c112d3692
[9e7aedd]: https://git.tirsystem.com/TirSystem/github-action/commit/9e7aeddb11c2b41ac893d9f7893d663a53fbe470
[eaa0e30]: https://git.tirsystem.com/TirSystem/github-action/commit/eaa0e30beaa097dfeb1c07c814a71d02a6987060
@@ -1,113 +0,0 @@
# ADR-0009: Wiki publishing as a reusable workflow
## Metadata
| Key | Value |
| --- | --- |
| ID | ADR-0009 |
| CrossReference | [MIL-008], [ADR-0003], [ADR-0004], [ADR-0005], [ADR-0006] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | S01 | Review findings fixed (RC-063): the product owner's language is spelled out, the security consequence is named, and the secret passing is recorded as verified | [8c2c52e] |
| 2026-10-14 | Proposed | Jens Tirsvad Nielsen | S01 | Amendment: the default `tools-ref` is the current major tag (MIL-011) | [eaa0e30] |
Allowed Status values: `Proposed`, `Accepted`, `Rejected`, `Deprecated`, `Superseded by ADR-NNNN`.
---
## Context
[ADR-0004] chose a scoped workflow to publish wikis: Gitea runs it in every
repository of an organisation, and a marker file `wiki/.publish` is the opt-in.
That avoids a copy of the workflow, but it runs where nobody asked for it and
needs a safety gate for that reason; its trigger path (`wiki/**`) and the
version of the script (`v1`) are fixed centrally. The framework now prescribes
the wiki in `docs/wiki/` with English and the product owner's language as a
minimum, and
repositories need to say where their wiki is.
Options:
1. **Keep the scoped workflow and read both folders.** No file in consumers,
but the central trigger lists every location and the gate stays.
2. **A reusable workflow (`workflow_call`) that each repository calls.** One
source in this repository, called as `uses: ...@v1` the way
`quality-checks` and `release` already are ([ADR-0005], [ADR-0006]). The
caller sets its own trigger paths and the folder.
## Decision
Wiki publishing is the reusable workflow `publish-wiki-pages.yml`, called by
each repository that wants a published wiki; the caller file is the opt-in and
`docs/wiki/` is the default folder. The scoped `publish-wiki.yml` and the
`wiki/.publish` marker are deprecated and stay until every publishing repository
has a caller; they are then removed in a later major release.
The rules that follow from it:
- Inputs: `wiki_dir` (default `docs/wiki`), `prune` (default `false`) and
`tools-ref` (default `v1`). The secret `TOKEN_FOR_GITEA_WIKI` is declared and
passed by the caller; there is no fallback to another token.
- With the reusable workflow the marker is not read: the script treats the
`prune` input as the setting, and a missing folder is a configuration error
rather than a skip, because the caller asked for it.
- The script, the page-title rules, the empty-folder protection and the error
categories of [ADR-0004] and [ADR-0003] are unchanged.
## Consequences
**Positive:**
- A repository states its own folder and trigger paths, so the wiki can move
to `docs/wiki/` one repository at a time.
- Opting in is a file in the repository, reviewed in a pull request, and a
repository without a caller is never written to.
- Security: the token is passed explicitly by the caller and is never
inherited or taken from a fallback, so a repository that does not pass it
cannot write a wiki.
- One call convention for every shared workflow of this repository.
**Negative:**
- Every publishing repository needs a caller file, and the removal of the
scoped workflow stops publishing in any repository that still relies on the
marker; the list of those repositories is taken before the removal.
- Eight repositories still publish through the scoped workflow (checked on
2026-10-13), so it is deprecated and not removed here; removing it is a
breaking change under [ADR-0006] and belongs to a follow-up milestone with
their migrations.
- The owner chose a patch release (1.2.2) for this change although a new
workflow is a minor one under [ADR-0006]; the changelog states the deviation.
- Anyone who can change the caller file of a repository can change the folder
and `prune`, and so what the token deletes in that repository's wiki; this is
the same exposure as the marker had, and it is reviewed through the pull
request that changes the caller.
- Passing a declared secret through `workflow_call`, and a local `uses:` call,
were verified on this Gitea instance by run 316 of this repository on
2026-10-13.
## Affected Artifacts
- [MIL-008] — the plan this decision belongs to.
- [ADR-0004] — its scoped delivery and marker parts are replaced once the
scoped workflow is removed; its token and safety rules stand.
## Amendment (MIL-011)
The default of the input `tools-ref` in the wiki publishing contract is the current major tag, defined once in the file
`MAJOR_TAG` of this repository (`v2` from release 2.1.1), and no longer `v1`. A default must
name a tag that holds the script the workflow runs; a test checks it. Callers at `@v1` are
not affected: the `v1` tag keeps the `v1` workflow files.
---
[MIL-008]: ../milestones/mil-008-wiki-reusable-workflow.md
[ADR-0003]: ./adr-0003-wiki-publish-token.md
[ADR-0004]: ./adr-0004-shared-wiki-publishing-opt-in.md
[ADR-0006]: ./adr-0006-release-process-and-version-pinning.md
[ADR-0005]: ./adr-0005-quality-check-contract.md
[01b9c29]: https://git.tirsystem.com/TirSystem/github-action/commit/01b9c2972b4317bcc590540010aea0eaf7f30014
[8c2c52e]: https://git.tirsystem.com/TirSystem/github-action/commit/8c2c52ebd2a27e4d0edb4008c31c002718d280fb
[eaa0e30]: https://git.tirsystem.com/TirSystem/github-action/commit/eaa0e30beaa097dfeb1c07c814a71d02a6987060
@@ -1,226 +0,0 @@
# ADR-0010: Contract of the code metrics and coverage badges workflow
## Metadata
| Key | Value |
| --- | --- |
| ID | ADR-0010 |
| CrossReference | [MIL-010], [UC-008], [US-001], [ADR-0005], [ADR-0006] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-14 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | The report reaches the workflow as an artifact of the caller's run (input `coverage-artifact`), because a called workflow runs in its own job; reviewed (RC-073) | [0dc5132] |
| 2026-10-14 | Proposed | Jens Tirsvad Nielsen | S01 | Amendment: the default `tools-ref` is the current major tag (MIL-011) | [eaa0e30] |
Allowed Status values: `Proposed`, `Accepted`, `Rejected`, `Deprecated`, `Superseded by ADR-NNNN`.
---
## Context
MIL-010 adds a reusable workflow that shows the size of a repository's code
and its test coverage as badges (UC-008, US-001.18 to US-001.20). ADR-0005
defines the contract of the quality-check workflow: inputs with working
defaults, a pinned version per tool, a failure that names the cause, and a
script file of this repository, fetched at `tools-ref`, that the workflow runs.
Decisions the user took in chat on 2026-10-14 bound this one: the counter is a
Python script of this repository with no dependency outside the standard
library, the delivery is a reusable workflow, the badges are committed to a
`badges` branch, there are three badges (code files, lines of code, coverage),
and the coverage report is read in the Cobertura XML format.
Options for the counter:
1. **Wrap `cloc`, `tokei` or `scc`.** Many languages, mature rules, but a tool
to install and pin on every run and a download from outside the instance.
2. **A Python script of this repository.** No install, fully tested offline,
and the rules are ours; fewer languages and simple scanning rules.
Options for the delivery of the badges: a run artifact (disappears and has no
stable URL), a file on the default branch (a commit per change on the branch
that protects the code), or a dedicated branch (stable raw URL, no effect on
the default branch).
Facts: the job of a reusable workflow runs on `ubuntu-latest` with `python3`
3.12; a push made with the token of a run does not start another run; a
workflow checks the shared scripts out into the workspace (`shared-scripts`),
so the counter must not count them.
## Decision
A reusable workflow `code-metrics.yml` runs three script files of this
repository, fetched at its input `tools-ref` (default `v1`): `tools/count_loc.py`
counts the code, `tools/badges.py` reads the coverage report and writes the
badges, and `tools/code-metrics.sh` validates the inputs, calls both and
publishes the badge files to the `badges` branch of the calling repository
with the token of the run (`contents: write`, no other permission).
The rules that follow from it:
- **Code file.** A file under `working-directory` whose extension is in the
language table below, that is not excluded, and that contains no NUL byte
(it is text; it is read as UTF-8 and invalid bytes are replaced). Its
language comes from the extension. A file with a code extension but no
line is still a code file.
- **Languages and comments (first version).**
| Language | Extensions | Line comment | Block comment |
| --- | --- | --- | --- |
| Python | `.py` | `#` | none |
| Shell | `.sh`, `.bash` | `#` at the start of a word | none |
| PowerShell | `.ps1`, `.psm1` | `#` | `<#` ... `#>` |
| C | `.c`, `.h` | `//` | `/*` ... `*/` |
| C++ | `.cc`, `.cpp`, `.cxx`, `.hh`, `.hpp` | `//` | `/*` ... `*/` |
| C# | `.cs` | `//` | `/*` ... `*/` |
| Java | `.java` | `//` | `/*` ... `*/` |
| JavaScript | `.js`, `.mjs`, `.jsx` | `//` | `/*` ... `*/` |
| TypeScript | `.ts`, `.tsx` | `//` | `/*` ... `*/` |
| Go | `.go` | `//` | `/*` ... `*/` |
| Rust | `.rs` | `//` | `/*` ... `*/` |
| SQL | `.sql` | `--` | `/*` ... `*/` |
Markup, data and configuration files (Markdown, YAML, JSON, XML, HTML,
CSS) are not code files. A language is added by a minor release.
- **Line classes.** Every physical line is exactly one of: *blank* (only
white space, also inside a block comment), *comment* (not blank, and only
comment text and white space), or *code* (anything else, including a line
with code and a trailing comment). A comment marker inside a string literal
is not a comment. String literals are the quoted forms of the language that
end on the same line, plus the Python triple-quoted string and the backtick
string of JavaScript, TypeScript and Go, which may span lines; a Python
docstring is a string and so counts as code.
Raw-string and verbatim forms that differ from these (Rust `r#"..."#`, C#
`@"..."` with doubled quotes, C++ raw strings) are scanned as ordinary
strings and can be mis-counted; this is a stated limit.
- **Excluded by default.** Every directory whose name starts with `.`, and the
directories `node_modules`, `vendor`, `third_party`, `dist`, `build`, `out`,
`bin`, `obj`, `target`, `venv`, `__pycache__` and `shared-scripts`
(the checkout of the shared scripts); symbolic links are not followed. The
input `exclude` is a comma list of patterns that add to this: a pattern
without `/` matches a directory or file name anywhere, a pattern with `/`
matches the path relative to `working-directory` (`*` does not cross `/`).
The counter does not read `.gitignore` or generated-file markers; a caller
excludes generated code with `exclude`.
- **Totals.** `files` is the number of code files and `lines` is the sum of
their code lines (comment and blank lines are not in it); the result also
holds `comment` and `blank` totals and the same four numbers per language,
sorted by language name, in `code-metrics.json`.
- **Coverage report.** The input `coverage-report` is the path, relative to
the repository root, of a Cobertura XML file. The percentage is
`lines-covered / lines-valid` of the root `coverage` element, shown rounded
half up to a whole number; when a count is absent, `line-rate` is used.
A path that does not exist, a file that is not well-formed Cobertura XML,
and a report with no valid lines are failures with the category
`[configuration]` that names the file; no coverage badge is written. An
empty `coverage-report` means no coverage badge and a notice. The workflow
does not run tests. A called workflow runs in its own job, so it cannot see
the files of the caller's test job: the caller runs its tests in an earlier
job, uploads the report as an artifact and gives the artifact's name as the
input `coverage-artifact`. The workflow then downloads that artifact into
the directory `coverage-artifact` of its workspace and `coverage-report`
names the file inside the artifact. Without `coverage-artifact`,
`coverage-report` is a path in the checkout of the repository (a report the
repository commits). `coverage-artifact` without `coverage-report` is a
`[configuration]` failure.
- **Badges.** Three flat SVG files with a label and a value, written to the
root of the `badges` branch with fixed names: `code-files.svg` (label
`code files`), `code-lines.svg` (label `lines of code`) and `coverage.svg`
(label `coverage`); the values are the whole number with `,` between groups
of three digits and, for coverage, `%`. The value colour of the first two is
blue `#007ec6`; coverage is red `#e05d44` below the input `coverage-warn`
(default `60`), yellow `#dfb317` from there to below `coverage-good`
(default `80`) and green `#44cc11` from `coverage-good`. Each file has
`role="img"`, a `<title>` and an `aria-label` with the same text, a width
computed from the number of characters (no font is measured) and no
timestamp, script or external reference, so the same numbers give the same
bytes.
- **Publishing.** The `badges` branch holds only the three SVG files and
`code-metrics.json`; the script creates it as an orphan branch when it does
not exist. It writes the files, and when none differs from the branch it
commits nothing and says so; otherwise one commit, message
`Update code metrics badges [skip ci]`, changes only those files. The
commit is made with the token of the run, which does not start another run;
the guide tells a caller to start the workflow on pushes to its default
branch only.
- **Inputs.** `working-directory` (default `.`), `exclude` (default empty),
`coverage-report` (default empty), `coverage-artifact` (default empty),
`coverage-warn` (default `60`),
`coverage-good` (default `80`), `badges-branch` (default `badges`) and
`tools-ref` (default `v1`; pin it to the same exact tag as the workflow).
There is no tool version input: the tools are files of this repository and
Python 3 of the runner.
- **Pass, fail, empty.** The run passes when the badges were written or were
already current. It fails with a `[configuration]` message that names the
input and the value for an input that is invalid (a threshold that is not a
number from 0 to 100, `coverage-warn` above `coverage-good`, a
`working-directory` that is not a directory, a branch name that is not a
valid branch name) and for a coverage report as above. A repository with no
code file passes with a notice and badges that show `0`.
- **Not in the first version:** a badge per language (the JSON holds the
numbers), lcov and other report formats, branch or function coverage, and
counting only tracked files.
## Consequences
**Positive:**
- No tool is installed and nothing is downloaded: a run needs only the
checkout, Python 3 and the instance, so the counter and the renderer are
fully testable offline with fixtures.
- The same input gives the same bytes, so an unchanged repository produces no
commit and the `badges` branch history is the history of the numbers.
- The badges have stable URLs on the instance and on the mirror, and nothing
on the default branch changes.
- A broken or missing report is a failure that names the file, never a
misleading `0%`.
**Negative:**
- The counter knows only the listed languages and simple scanning rules; some
string forms are mis-counted (stated above), and results will differ a
little from `cloc` or `tokei`.
- The workflow needs `contents: write`, which is more than the
`contents: read` of the quality checks; a caller that grants less cannot use
it. The write is limited to the `badges` branch by the script, not by the
host.
- A caller must run its tests and produce a Cobertura XML report in an
earlier job and upload it as an artifact; other formats need a conversion
until a later release adds them. The download needs the artifact service
of the instance to serve a called workflow, which task 8 of MIL-010
verifies.
- A fixed set of thresholds and colours; a caller can move the two thresholds
only.
- Security: the script runs with a token that can write to the repository.
The files are ours and no code is downloaded (the artifact is a report that
is parsed as XML with entity declarations refused), but a caller that pins
`tools-ref` to a moving ref takes later changes of the script; the guide
says to pin the exact tag. The script writes only the four named files, and
the branch name input is validated so that it cannot name the default branch
(`main`, `master`) or a branch of the caller's code.
## Affected Artifacts
- [MIL-010] — decides its criterion 2 and unlocks tasks 4 to 6.
- [UC-008] — the use case this workflow serves.
- [US-001] — US-001.18 to US-001.20 state their acceptance criteria.
- [ADR-0005] — the contract style that this decision follows, unchanged.
- [ADR-0006] — adding a language, or changing a colour or a default, is a
release under its rules; raising a default threshold is breaking.
## Amendment (MIL-011)
The default of the input `tools-ref` in the code metrics contract is the current major tag, defined once in the file
`MAJOR_TAG` of this repository (`v2` from release 2.1.1), and no longer `v1`. A default must
name a tag that holds the script the workflow runs; a test checks it. Callers at `@v1` are
not affected: the `v1` tag keeps the `v1` workflow files.
---
[MIL-010]: ../milestones/mil-010-code-metrics-badges.md
[UC-008]: ../uc-008/uc.md
[US-001]: ../user-stories.md
[ADR-0005]: ./adr-0005-quality-check-contract.md
[ADR-0006]: ./adr-0006-release-process-and-version-pinning.md
[0dc5132]: https://git.tirsystem.com/TirSystem/github-action/commit/0dc5132a2ea419ba05035ee3594cec63335c240b
[eaa0e30]: https://git.tirsystem.com/TirSystem/github-action/commit/eaa0e30beaa097dfeb1c07c814a71d02a6987060
-48
View File
@@ -1,48 +0,0 @@
# Artifact Registry
This project's artifact state. Types, short names and `CrossReference
Candidates` come from the framework catalog
(`framework/registry/artifact-catalog.md`); this file only records where
each document lives in *this* project and the next version to use.
| Short Name | Artifact Type | Primary File | Next Available Version |
| --- | --- | --- | --- |
| BC | Business Case | docs/business-case.md | 002 |
| SA | Stakeholder Analysis | docs/stakeholder-analysis.md | 002 |
| PP | Project Plan | docs/project-plan.md | 002 |
| MIL | Milestone / Gateway | docs/milestones/*.md | 012 |
| RC | SQA Review Record | docs/sqa/reviews/rc-*.md | 079 |
| TM | Traceability Matrix | docs/sqa/traceability-matrix.md | 002 |
| ADR | Architecture Decision Record | docs/adr/adr-NNNN-*.md | 0011 |
| UCD | Use Case Diagram | docs/use-case-diagram.md | 002 |
| US | User Story | docs/user-stories.md | 002 |
| UC | Use Case | docs/uc-NNN/uc.md | 009 |
## Languages
| Setting | Value |
| --- | --- |
| PO language | en (English, IT) |
| High-level register | IT Executive English |
| Technical register | IT Professional English |
The PO language is English, so no PO-language translations are kept.
The Gitea wiki (MIL-005) is the one exception: its pages are kept in English
(authoritative), Danish (`da`) and Bahasa Malaysia (`ms`). A translation is named
`<Page>.<lang>` (`Home.da`) and names the English source it follows; see
`docs/adr/adr-0001-wiki-structure-and-languages.md`.
| Artifact types | Register | Also kept as a PO-language file |
| --- | --- | --- |
| BC, KPI, PP, MIL | IT Executive English | No (PO language is English) |
| SA, BMC, BPMN, UCD, US, UC, SSD, DM, RA, GOV, DICT | IT Professional English | No (PO language is English) |
| OC, SD, DCD, ERD, ADR, TM, RC, QC, source code | IT Professional English | No |
## Notes
- "Next Available Version" is the zero-padded (3-digit) version to use the
*next* time a new document of that type is created. Increment it only when
a brand-new document is created, not when an existing document's
`## Version History` gets a row.
- `ADR` uses 4 digits (`0001`); `RC` is sequential across all artifact types.
-158
View File
@@ -1,158 +0,0 @@
# Business Case: TirSystem Reusable Workflows
## Metadata
| Key | Value |
| --- | --- |
| ID | BC-001 |
| CrossReference | [SA-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Deprecated | Jens Tirsvad Nielsen | S01 | Scope: wiki pages in English, Danish and Bahasa Malaysia | [08ef26a] |
| 2026-10-14 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Objective O5, scope item and success criterion 5: shared workflow for code metrics and coverage badges (MIL-010); reviewed (RC-067) | [5002450] |
---
## Executive Summary
TirSystem repositories are hosted on a self-hosted Gitea instance and
push-mirrored to GitHub. Automation that every repository needs is currently
copied by hand. This project turns this repository into the single, reviewed
collection of reusable Gitea Actions workflows for DevOps professionals and
software engineers. Today it contains one workflow, which copies repository
description and topics from Gitea to the GitHub mirror. The proposal is to
harden that workflow first, document how repositories adopt it, and then add
shared quality-check and release workflows in priority order.
## Methodological and Standards Foundation
Documents follow the SQA and QC framework in `framework/` (use cases after
Larman, *Applying UML and Patterns*). Quality criteria are tagged with
ISO/IEC 25010:2023 characteristics. The domain language is English (IT).
## Problem Statement
- The only workflow exists as three diverging copies (`src/`,
`.gitea/scoped_workflows/`, and others), and the scoped copy
currently contains a Python syntax error (`exit 0`).
- There is no automated check of workflow files, so defects such as that one
are found only when the workflow runs.
- There is no documented way to onboard a repository, set up credentials,
choose runners or diagnose a failed run.
- Quality checks and release steps are not shared, so each project would
reinvent them.
## Business Opportunity
A small, versioned, documented workflow collection lets every TirSystem
repository adopt the same secure automation in minutes, and lets a fix be
made once.
## Objectives
- **O1:** Keep the existing metadata sync correct, tested and documented as
the single implemented capability.
- **O2:** Provide one canonical copy of each workflow with a defined way to
reach consuming repositories (scoped workflow or copy).
- **O3:** Document and validate credentials, runner labels and failure
diagnosis for every workflow.
- **O4:** Offer shared quality-check and release workflows, versioned so
consumers can adopt changes deliberately.
- **O5:** Offer a shared workflow that counts the code files and the lines of
code (without comment and blank lines) of a repository, reads its coverage
report and publishes the three results as SVG badges.
## Scope
### In Scope
- Gitea Actions workflows (and GitHub-compatible syntax where it is the same).
- Documentation for DevOps professionals and software engineers.
- A Gitea wiki with the same documentation in English, Danish and Bahasa Malaysia (MIL-005).
- Validation of workflow files and their documentation.
- A shared workflow for code metrics and coverage badges (MIL-010).
### Out of Scope
- Operating the Gitea instance or runners themselves.
- Application code of consuming repositories.
- Features not backed by an accepted milestone task.
- Behavior that is only proposed: documentation describes implemented
workflows only; planned ones are marked as planned.
## Expected Benefits
### Tangible Benefits
- One fix reaches all consuming repositories.
- Fewer failed runs caused by missing or over-broad credentials.
- Less time to onboard a repository.
### Intangible Benefits
- Consistent, reviewable automation across TirSystem projects.
- Higher trust in automation that touches credentials.
## Strategic Alignment
Supports TirSystem's practice of a self-hosted primary repository with
public GitHub mirrors, and its SQA framework requirement that code follows
accepted plans.
## Success Criteria
| # | Criterion | Target | Measure |
| --- | --- | --- | --- |
| 1 | Workflow files that fail static validation | 0 on the default branch | Result of the validation task in MIL-001 |
| 2 | Canonical copies per workflow | 1 | Count of files per workflow name |
| 3 | Documented use cases that are implemented or marked planned | 100% | README capability table against workflows present |
| 4 | Repositories consuming a shared workflow | At least 1 besides this one by MIL-002 | Consumer list in README |
| 5 | Repositories that show the code metrics and coverage badges from the shared workflow | At least 1 besides this one by MIL-010 | README of the consuming repository |
## Risks
| Risk | Impact | Mitigation |
| --- | --- | --- |
| Gitea scoped workflows behave differently from assumption (feature and version not verified) | Onboarding design is wrong | Verify against the actual instance in MIL-002 before documenting it as supported. |
| Token with excess scope is stored in secrets | Compromise of repositories | Document minimum scope; validate token permissions before use. |
| A breaking change reaches consumers unannounced | Consumer pipelines fail | Version and changelog every release (MIL-004). |
| Security-relevant change accepted without security review | Credential or permission defect reaches production | S05 reviews every change to credentials, tokens, permissions and workflow code. |
## Assumptions
- The Gitea instance has Actions enabled and an `ubuntu-latest` runner with `python3`.
- A mirrored repository has at most one GitHub push mirror. Repositories without a GitHub mirror are skipped successfully.
- S01 (Product Owner) and S05 (DevOps owner and security authority) are both maintainers.
## Constraints
- Workflows use only tools available on the runner; the current workflow uses the Python standard library only.
- Secrets are supplied as repository or organization secrets, never committed.
- Nothing is written under `src/` or `tests/` before the matching milestone is accepted.
## Cost–Benefit Assessment
| Costs | Benefits |
| --- | --- |
| Maintainer time for planning, documentation and tests (qualitative; no external cost) | Avoided duplication and fewer credential and configuration failures across repositories |
## Stakeholders
| Stakeholder ID (SA) | Interest in this project |
| --- | --- |
| S01 | Owns scope, accepts the documents and co-maintains the workflows |
| S02 | Consumes shared workflows |
| S03 | Operates runners and secrets |
| S05 | Co-maintains the workflows and reviews their security |
| S04 | Sees mirror metadata |
## Recommendation
Proceed — the first milestone fixes a known defect in the only existing workflow and the later ones add value only after it is accepted.
---
[SA-001]: ./stakeholder-analysis.md
[08ef26a]: https://git.tirsystem.com/TirSystem/github-action/commit/08ef26a6d3eb98c066b45634c2271e578e6c0a0b
[5002450]: https://git.tirsystem.com/TirSystem/github-action/commit/50024505fe788b1c5e3021c0d1fc3d079590070e
@@ -1,78 +0,0 @@
# MIL-001: Stabilise the metadata sync
## Metadata
| Key | Value |
| --- | --- |
| ID | MIL-001 |
| CrossReference | [BC-001], [ADR-0002] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Deprecated | Jens Tirsvad Nielsen | S01 | Task 1 decision amended: zero GitHub mirrors is a successful skip<br>Task 5 tests cover zero or several mirrors accordingly | [0c06789] |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Target date 2026-10-17 confirmed on 2026-10-10 by S01 (stand-in for S05) | [ea06eaa] |
---
## Purpose
Decide whether the only implemented workflow is correct, tested and has one
canonical copy, so later milestones build on a sound base.
## Deliverable
A single canonical metadata-sync workflow that passes automated validation
and tests, a README that separates implemented from planned behavior, and a
successful manual run on the Gitea instance.
## Go / No-Go Criteria
| # | Criterion (objectively checkable) | Go | No-Go |
| --- | --- | --- | --- |
| 1 | The embedded Python compiles and every workflow YAML parses in an automated check | Check passes | Any failure |
| 2 | Exactly one canonical source per workflow; other copies are generated or removed | Count is 1 | Count above 1 |
| 3 | Unit tests cover credential parsing and push mirror URL parsing, and run without network access or `.env` | Tests pass | Missing or failing |
| 4 | README capability table matches the workflows present | Matches | Claims unimplemented behavior |
| 5 | Manual `workflow_dispatch` run on Gitea succeeds and the GitHub description and topics match | Match | Mismatch or failure |
## Dependencies
| Depends on | Reason |
| --- | --- |
| None | First milestone |
## Traceability
| Business Case objective / KPI / user story | Reference |
| --- | --- |
| O1, O2 | [BC-001] |
## Ownership
| Role | Stakeholder ID (SA) |
| --- | --- |
| Owner | S05 |
| Approving reviewer | S01 |
## Target Date
2026-10-17 — confirmed on 2026-10-10 by S01, standing in for S05 (ADR-0002); the Business Case sets no deadline.
## Tasks
| # | Task | Summary | Needs its own Use Case/User Story? | Reference |
| --- | --- | --- | --- | --- |
| 1 | Decide behavior for an invalid push mirror response | The committed workflow fails with an error when Gitea returns a non-list push mirror response. The uncommitted scoped copy instead prints a message and tries to exit successfully, and the README diagram showed that. Choose fail or skip, record the decision, and align code and README. Decision: skip with a visible warning and a successful run, following the maintainer's edit to the scoped copy; several or malformed GitHub mirrors still fail. Amended 2026-10-10: zero GitHub mirrors is also a successful skip, because not every Gitea repository has a mirror; the GitHub secret is then not read. | No | |
| 2 | Fix the Python syntax error in the scoped workflow | `exit 0` is not valid Python, so the whole embedded script fails to compile in the scoped copy. Replace it according to the decision in task 1 (`sys.exit(0)` also needs `import sys`). | No | |
| 3 | Reduce the workflow to one canonical source | The same workflow exists in `src/` and `.gitea/scoped_workflows/` (and a legacy copy that is no longer documented), and the scoped copy has diverged. Choose the canonical location, and generate or remove the others. Decision: `.gitea/scoped_workflows/` is canonical because the script must be embedded in the YAML to work as a scoped workflow; the `src/` copy is removed. | No | |
| 4 | Add static validation of workflow files | Parse each workflow YAML and compile its embedded Python in an automated check that runs on pull requests, so defects such as task 2 fail before merge. | No | |
| 5 | Add offline unit tests for the sync logic | Move credential and mirror URL parsing into testable code and test bare token, JSON token, SSH and HTTPS mirror addresses, zero mirrors (skipped successfully) and several mirrors (fail). Replace `tests/test_.ps1`, which probes a hard-coded real repository and reads `.env`. | No | |
| 6 | Keep the README accurate | Maintain the capability table (implemented, partial, planned), and align the sequence diagram with the final behavior from task 1. | No | |
| 7 | Verify a live run | Trigger the workflow manually on Gitea and compare the GitHub description and topics with the Gitea repository. | No | |
---
[BC-001]: ../business-case.md
[0c06789]: https://git.tirsystem.com/TirSystem/github-action/commit/0c06789a2779382672712cd483f4964b28a0ebe9
[ADR-0002]: ../adr/adr-0002-s01-approves-as-stand-in.md
[ea06eaa]: https://git.tirsystem.com/TirSystem/github-action/commit/ea06eaaa698247d20e4a8e2694d7acbb1de58b63
@@ -1,78 +0,0 @@
# MIL-002: Onboarding and operations guide
## Metadata
| Key | Value |
| --- | --- |
| ID | MIL-002 |
| CrossReference | [BC-001], [ADR-0002] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-03 | Deprecated | Jens Tirsvad Nielsen | S01 | Recorded verification results for task 2 | [7dcb9c4] |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Target date 2026-10-31 confirmed on 2026-10-10 by S01 (stand-in for S05) | [ea06eaa] |
---
## Purpose
Decide whether a DevOps professional can onboard a repository, set up
credentials, choose runners and diagnose a failed run from the documentation
alone.
## Deliverable
An onboarding and operations guide verified against the real Gitea instance,
a credential validation step in the workflow, and categorized failure messages.
## Go / No-Go Criteria
| # | Criterion (objectively checkable) | Go | No-Go |
| --- | --- | --- | --- |
| 1 | Support for scoped workflows on the instance is verified and the Gitea version is recorded | Recorded | Unverified |
| 2 | A second repository is onboarded by following only the guide | Run succeeds | Needs undocumented steps |
| 3 | Minimum token permissions are documented for both secrets and checked by the workflow before use | Documented and checked | Missing |
| 4 | Every failure message names its category: configuration, credentials, permissions, API response or runner | Verified for all messages | Uncategorized message exists |
| 5 | Supported runner labels and prerequisites are listed | Listed | Missing |
## Dependencies
| Depends on | Reason |
| --- | --- |
| MIL-001 | The guide describes the stabilised workflow |
## Traceability
| Business Case objective / KPI / user story | Reference |
| --- | --- |
| O2, O3 | [BC-001] |
## Ownership
| Role | Stakeholder ID (SA) |
| --- | --- |
| Owner | S05 |
| Approving reviewer | S01 |
## Target Date
2026-10-31 — confirmed on 2026-10-10 by S01, standing in for S05 (ADR-0002); the Business Case sets no deadline.
## Tasks
| # | Task | Summary | Needs its own Use Case/User Story? | Reference |
| --- | --- | --- | --- | --- |
| 1 | Write brief use cases for the P1 candidates | Turn the DevOps use cases in the Project Plan appendix into use case documents under `docs/uc-NNN/`, after a use case diagram and user stories exist. | No | |
| 2 | Verify scoped workflow support on the instance | The Business Case lists this as an unverified assumption. Check the Gitea version and how a scoped workflow reaches a repository, then record the result. Result: Gitea 1.27.3 runs the scoped sync workflow in this repository (run 16); delivery to other repositories is not yet verified and is recorded in `guides/onboarding.md`. | No | |
| 3 | Write the repository onboarding steps | Describe how to consume the workflow (scoped or copied), which secrets to set and how to test the first run. | No | |
| 4 | Document least-privilege tokens | Determine the minimum Gitea token scope and GitHub fine-grained token permission that the sync needs, and document them. | No | |
| 5 | Add a credential preflight step | Before the sync, check that both tokens authenticate and have the needed access, and report the result without printing any secret. | No | |
| 6 | Categorize failure messages | Group the error messages and HTTP errors into configuration, credentials, permissions, API response and runner, and write the diagnosis table. | No | |
| 7 | Document runner labels and prerequisites | State the supported labels (`ubuntu-latest`), the required `python3`, and how to recognize an offline or incompatible runner. | No | |
---
[BC-001]: ../business-case.md
[7dcb9c4]: https://git.tirsystem.com/TirSystem/github-action/commit/7dcb9c4dfce712572aced281d0dfdfa435283646
[ADR-0002]: ../adr/adr-0002-s01-approves-as-stand-in.md
[ea06eaa]: https://git.tirsystem.com/TirSystem/github-action/commit/ea06eaaa698247d20e4a8e2694d7acbb1de58b63
-124
View File
@@ -1,124 +0,0 @@
# MIL-003: Shared quality checks
## Metadata
| Key | Value |
| --- | --- |
| ID | MIL-003 |
| CrossReference | [BC-001], [ADR-0002] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Deprecated | Jens Tirsvad Nielsen | S01 | Task 1 verified: workflow_call and uses work from the same repository, the same organization and another organization (RC-033) | [b3f006f] |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Task 4 recorded: adoption in RepoFoundry, the shfmt .editorconfig gap and the other findings (RC-039) | [3b8681d] |
---
## Purpose
Decide whether a software engineer can run the same quality checks on any
TirSystem project through a shared workflow.
## Deliverable
A reusable quality-check workflow for Python and shell, used by at least one
other repository, and a guide for reading its results.
## Go / No-Go Criteria
| # | Criterion (objectively checkable) | Go | No-Go |
| --- | --- | --- | --- |
| 1 | The instance supports reusable workflows (`workflow_call`), verified and recorded | Verified | Unsupported (re-plan as a copied template) |
| 2 | One other repository runs the workflow and its status check appears on pull requests | Appears | Does not run |
| 3 | A failing check shows the tool, file and message in the log | Verified with a seeded failure | Cause not visible |
| 4 | Inputs and defaults are documented | Documented | Missing |
## Dependencies
| Depends on | Reason |
| --- | --- |
| MIL-002 | Uses the onboarding guide and runner list |
## Traceability
| Business Case objective / KPI / user story | Reference |
| --- | --- |
| O4 | [BC-001] |
## Ownership
| Role | Stakeholder ID (SA) |
| --- | --- |
| Owner | S05 |
| Approving reviewer | S01 |
## Target Date
2026-11-14 — confirmed on 2026-10-10 by S01, standing in for S05 (ADR-0002); the Business Case sets no deadline.
## Tasks
| # | Task | Summary | Needs its own Use Case/User Story? | Reference |
| --- | --- | --- | --- | --- |
| 1 | Verify reusable workflow support | Check whether this Gitea version supports `workflow_call` and cross-repository `uses`; if not, choose a copied template instead. Verified on 2026-10-10: supported, so no copied template is needed (see Verification results). | No | Verification results |
| 2 | Define the quality-check contract | Decide the inputs (language, tool versions, working directory) and what a pass and a fail mean. Start with Python and shell. This is something an engineer does, so it needs a use case first. | Yes | Use case candidate: run project quality checks |
| 3 | Implement the reusable quality workflow | Create the workflow in the canonical location with pinned tool versions and least-privilege permissions. | No | |
| 4 | Adopt it in one other repository | Onboard a real project and fix the gaps in the guide that appear. Adopted in `TirSystem-BashScript/RepoFoundry` (its PR 76, run passes); see Adoption in a real repository. | No | Adoption in a real repository |
| 5 | Write the guide for reading results | Explain status checks, logs and typical fixes so an engineer can make a failing check pass. | No | |
## Verification results
Task 1 was run on 2026-10-10 on the instance (Gitea 1.27.3) with a throwaway
branch, `verify-reusable-workflows`, in `TirSystem/github-action`. The called
workflow declared `on: workflow_call` with one input and printed it; the
callers used `jobs.<job_id>.uses`. All branches were deleted afterwards.
| Call | Caller | Result |
| --- | --- | --- |
| `uses: ./.gitea/workflows/reuse-callee.yml` | `TirSystem/github-action` (same repository) | Called job ran; input received |
| `uses: TirSystem/github-action/.gitea/workflows/reuse-callee.yml@<branch>` | `TirSystem/github-action` | Called job ran; input received |
| the same, from another repository of the organization | `TirSystem/sqa-qc-checklists` | Called job ran; `gitea.repository` was the caller |
| the same, from a repository of another organization | `TirSystem-BashScript/RepoFoundry` | Called job ran; `gitea.repository` was the caller |
What the test did not cover: a provider repository that is private (the
provider here is public), passing secrets to a called workflow
(`secrets:` or `secrets: inherit`), and a reference by tag instead of a
branch. The quality checks of this milestone need none of the secrets; a
private provider and tag references are for the release milestone (MIL-004).
## Adoption in a real repository (task 4)
On 2026-10-10 the workflow was run against `TirSystem-BashScript/RepoFoundry`
(another organization; 39 shell files, no Python), first on a throwaway
branch and then as a pull request, RepoFoundry PR 76.
| Run | `shellcheck` | `shfmt -d` | Python |
| --- | --- | --- | --- |
| Unchanged repository | PASS on all 39 files | FAIL on 10 files | skipped with a notice (no files) |
| With `switch_case_indent = true` under `[*.sh]` in `.editorconfig` | PASS | PASS | skipped |
| The pull request itself (`languages: shell`) | PASS | PASS | not selected |
What the run showed:
- **`shellcheck` needs no help** when the project has a `.shellcheckrc`: the
workflow runs from the repository root, so the project's own settings
(`external-sources`, `source-path=SCRIPTDIR`) applied and files that share
variables across `src/lib/*.sh` produced no false positives.
- **`shfmt` follows the project's style only through `.editorconfig`.** All ten
differences were the indentation of `case` patterns: the workflow uses shfmt
defaults, the project's own check is `shfmt -i 2 -ci`. One `.editorconfig`
line fixed it without changing a script. A shell project with its own shfmt
flags should expect a first formatting failure and express the flags there.
- **Paths in the log are relative to `working-directory`**, and a caller must
reference the workflow at `main` or a tag, not at a branch that is deleted
when its pull request merges (the first trial lost its reference that way).
The task closes when RepoFoundry PR 76 is merged. The gaps above are for the
guide of task 5 (issue #19).
---
[BC-001]: ../business-case.md
[ADR-0002]: ../adr/adr-0002-s01-approves-as-stand-in.md
[b3f006f]: https://git.tirsystem.com/TirSystem/github-action/commit/b3f006f7a482392189a46c324ad4f28c4c3a2d2a
[3b8681d]: https://git.tirsystem.com/TirSystem/github-action/commit/3b8681d0236c669b794ffbba725433fff600a2d2
@@ -1,96 +0,0 @@
# MIL-004: Versioned release and publishing
## Metadata
| Key | Value |
| --- | --- |
| ID | MIL-004 |
| CrossReference | [BC-001], [ADR-0002] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-11 | Deprecated | Jens Tirsvad Nielsen | S01 | Added the verification results of the first release (v1.0.0) | [6933e91] |
| 2026-10-11 | Accepted | Jens Tirsvad Nielsen | S01 | Criterion 3 verified with pinned consumers after v1.0.1 and v1.1.0 (RC-048) | [05b635c] |
---
## Purpose
Decide whether workflow updates can be released with a version and adopted
safely, and whether a project can publish an artifact through a shared
workflow.
## Deliverable
A documented release process for this repository (validation, version tag,
changelog), a consumer upgrade guide and a reusable release workflow. The
scoped workflows run scripts that are files in this repository, fetched at a
reference that a release can pin, instead of Python embedded in their YAML.
## Go / No-Go Criteria
| # | Criterion (objectively checkable) | Go | No-Go |
| --- | --- | --- | --- |
| 1 | A release is validated by the MIL-001 checks before a tag is created | Enforced | Tag possible without checks |
| 2 | Each release has a version tag and a changelog entry that marks breaking changes | Present | Missing |
| 3 | A consumer pinned to the previous version keeps working after a release | Verified | Breaks |
| 4 | The publish destination (release page or package registry) is decided and its token scope documented | Decided | Open |
| 5 | The sync and publish-wiki workflows contain no embedded Python; each runs a script file of this repository, and the tests exercise the files | Count of embedded scripts is 0 and a run in another organization passes | Embedded script remains or a consumer run fails |
## Dependencies
| Depends on | Reason |
| --- | --- |
| MIL-003 | Reuses the reusable workflow mechanism |
## Traceability
| Business Case objective / KPI / user story | Reference |
| --- | --- |
| O2, O4 | [BC-001] |
## Ownership
| Role | Stakeholder ID (SA) |
| --- | --- |
| Owner | S05 |
| Approving reviewer | S01 |
## Target Date
2026-11-28 — confirmed on 2026-10-10 by S01, standing in for S05 (ADR-0002); the Business Case sets no deadline.
## Tasks
| # | Task | Summary | Needs its own Use Case/User Story? | Reference |
| --- | --- | --- | --- | --- |
| 1 | Define the release process for this repository | Describe how a workflow change is validated, tagged and announced, and how consumers pin a version. | Yes | Use case candidate: release a reusable workflow |
| 2 | Add a changelog and tag convention | Create `CHANGELOG.md` and a tag scheme (for example `v1` plus `v1.2.3`) that separates breaking from compatible changes. | No | |
| 3 | Write the consumer upgrade guide | Explain how to read a changelog entry, test an update in one repository and roll back. | Yes | Use case candidate: consume a workflow update |
| 4 | Decide the publish destination | Choose the release or package destination for built artifacts and document the token scope it needs. | No | |
| 5 | Implement the reusable release workflow | Validate the version, build release notes from the changelog and publish to the chosen destination. | Yes | Use case candidate: publish a release |
| 6 | Move the embedded scripts of the scoped workflows to files | The sync (`sync-github-metadata.yml`) and publish-wiki workflows embed 200 to 300 lines of Python in their YAML, which is hard to read, lint and review. Move the code to `tools/sync_github_metadata.py` and `tools/publish_wiki.py`; each scoped workflow then checks out `TirSystem/github-action` into its own folder with `actions/checkout` and runs the file, as verified on 2026-10-10 from repositories of two organizations. Keep the behaviour, the messages and the offline tests, which import the files instead of executing the YAML; use `ref: main` first, and let the release process of task 1 define how a consumer pins a tag. | No | |
## Verification results
The first release was cut on 2026-10-11 with the Release workflow (run 623 on
`97ffa49`, after a dry run, run 622): the tag `v1.0.0`, the moving tag `v1`
and the release page were created, and the job token was enough (ADR-0007).
| # | Criterion | Result |
| --- | --- | --- |
| 1 | A release is validated before a tag is created | Go: `tools/release.py` refuses unless the status `Validate workflows / validate (push)` of the tip of `main` is success; tested for failed and missing runs |
| 2 | Version tag and changelog entry that marks breaking changes | Go: `v1.0.0` and `CHANGELOG.md` `[1.0.0]`; `tools/changelog.py` checks the convention |
| 3 | A consumer pinned to the previous version keeps working | Go, verified on 2026-10-11 after `v1.0.1`: a caller in `TirSystem-BashScript/RepoFoundry` at `@v1.0.0` and one at `@v1` both passed (run 660); after `v1.1.0` a caller at `@v1.1.0` with `tools-ref: v1.1.0` and one at `@v1` passed (run 672). `v1.0.0` still points to `97ffa49` |
| 4 | Publish destination decided, token scope documented | Go: ADR-0007 |
| 5 | No embedded Python in the scoped workflows | Go: both run files of this repository, with offline tests that exercise the files (MIL-004 task 6) |
After the release the two scoped workflows fetch their scripts at `ref: v1`
(RC-043 action item).
---
[BC-001]: ../business-case.md
[ADR-0002]: ../adr/adr-0002-s01-approves-as-stand-in.md
[6933e91]: https://git.tirsystem.com/TirSystem/github-action/commit/6933e91c83075fb39b2dfbe41683cb2a0a0bce28
[05b635c]: https://git.tirsystem.com/TirSystem/github-action/commit/05b635c1b3d79390c794e62e781595fbe5f1a4ea
@@ -1,97 +0,0 @@
# MIL-005: Wiki and translations
## Metadata
| Key | Value |
| --- | --- |
| ID | MIL-005 |
| CrossReference | [BC-001], [ADR-0002] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Deprecated | Jens Tirsvad Nielsen | S01 | Target date 2026-12-12 confirmed on 2026-10-10 by S01 (stand-in for S05) | [ea06eaa] |
| 2026-10-11 | Accepted | Jens Tirsvad Nielsen | S01 | Criterion 4 amended (accepted by S01 as stand-in when no native reader exists); added the verification results | [ead3d98] |
---
## Purpose
Decide whether a reader can find the workflow documentation on the Gitea wiki
in English, Danish and Bahasa Malaysia, and whether the wiki stays current
because every pull request updates it.
## Deliverable
A Gitea wiki with the pages Home, Onboarding, Credentials, Troubleshooting
and Capabilities in English (authoritative), Danish and Bahasa Malaysia. The
page source lives in `wiki/` in this repository and is reviewed through pull
requests. A script builds the English pages from `README.md` and `guides/`,
a workflow publishes `wiki/` to the wiki repository when a change is merged
to `main`, and a pull request rule in `AGENTS.md` keeps the wiki current.
## Go / No-Go Criteria
| # | Criterion (objectively checkable) | Go | No-Go |
| --- | --- | --- | --- |
| 1 | The wiki is enabled and contains the five pages in all three languages | 15 pages present | Any page missing |
| 2 | Each English page is generated from `README.md` or `guides/`, and a check reports a page that differs from its source | Check passes | Hand-edited page drifts |
| 3 | Each Danish and Bahasa Malaysia page names the English source version it follows | Named on every page | Missing |
| 4 | The translations are reviewed and accepted: by a native reader of each language, or, when none is available, by S01 as the stand-in of ADR-0002, with the lack of a native reader stated | Acceptance recorded, and a native review where one exists | Unreviewed |
| 5 | `AGENTS.md` requires a wiki update in every pull request that changes a workflow, a guide or the README, and the PR description lists the pages changed | Rule present and used by one PR | Missing |
| 6 | The wiki is published only by the workflow from `main`; no agent or person pushes to the wiki repository by hand | Last wiki commit is by the workflow | A manual push exists |
## Dependencies
| Depends on | Reason |
| --- | --- |
| MIL-002 | The wiki pages are built from the onboarding, credentials and troubleshooting guides |
## Traceability
| Business Case objective / KPI / user story | Reference |
| --- | --- |
| O3 | [BC-001] |
## Ownership
| Role | Stakeholder ID (SA) |
| --- | --- |
| Owner | S05 |
| Approving reviewer | S01 |
## Target Date
2026-12-12 — confirmed on 2026-10-10 by S01, standing in for S05 (ADR-0002); the Business Case sets no deadline.
## Tasks
| # | Task | Summary | Needs its own Use Case/User Story? | Reference |
| --- | --- | --- | --- | --- |
| 1 | Decide wiki structure, languages and source of truth | Fix the page list, the page naming for `da` and `ms` (for example `Home`, `Home.da`, `Home.ms`) and that the English wiki pages are generated from `README.md` and `guides/`. Record the wiki languages in the `Languages` section of `docs/artifact-registry.md`, since the registry currently says no translations are kept. | No | |
| 2 | Enable the Gitea wiki and agree access | Decision (2026-10-10): the page source lives in `wiki/` in this repository and reaches the wiki repository (`github-action.wiki.git`) only through a workflow that runs on merge to `main`; the agent edits `wiki/` on a branch and opens a pull request and never pushes to the wiki repository. This task enables the wiki on the repository and creates a secret that can write to the wiki repository only, approved by S05 and stored by S03. Edits made in the Gitea web UI are overwritten on the next publish, and the wiki home page says so. | No | |
| 3 | Generate the English wiki pages | Add a script that builds the five pages into `wiki/` from `README.md` and `guides/`, rewrites links so they work inside the wiki, and reports a page that differs from its source. | No | |
| 4 | Draft the Danish and Bahasa Malaysia pages | Translate each page and name the English source version at the top of the page. Keep technical terms (workflow, secret, runner, mirror) consistent through a small term list. | No | |
| 5 | Have the translations reviewed | A native reader of Danish and of Bahasa Malaysia reviews the drafts and the findings are fixed before publishing. | No | |
| 6 | Add the wiki update rule to the pull request process | Add a rule to `AGENTS.md`: a pull request that changes a workflow, a guide or the README also updates the matching wiki pages in all three languages, and its description lists the pages changed. | No | |
| 7 | Publish and verify | Publish the pages, open them in the browser in each language and check that links, code blocks and the capability table render. | No | |
| 8 | Add the wiki publishing workflow | Add a Gitea workflow, canonical in `.gitea/scoped_workflows/`, that runs on push to `main` when `wiki/` changes and copies `wiki/` to the wiki repository with the secret from task 2. It needs least-privilege permissions, must not print the secret, and gets offline tests like the metadata sync, with the same categorized error messages. | No | |
## Verification results
Checked on 2026-10-11 against `main` at the merge of PR 83.
| # | Criterion | Result |
| --- | --- | --- |
| 1 | The wiki is enabled and contains the pages in all three languages | Go: 21 pages (seven pages in English, Danish and Bahasa Malaysia), more than the 15 the criterion names |
| 2 | Each English page is generated from `README.md` or `guides/`, and a check reports a page that differs | Go: `python tools/build_wiki.py --check` passes and the tests fail on a stale page |
| 3 | Each translation names the English source version it follows | Go: every `.da` and `.ms` file starts with `translation of X.md, source sha256`, and the tests check it |
| 4 | The translations are reviewed and accepted | Go on the stand-in: no native reader of Danish or Bahasa Malaysia reviewed the pages. S01 accepted them on 2026-10-11 (RC-050) and the checklist `docs/wiki-translation-review.md` stays available for a native reader. The accuracy of the text rests on the author and S01, not on a native reader |
| 5 | `AGENTS.md` requires a wiki update and the PR lists the pages | Go: rule 8 of `AGENTS.md`; used by PR 78, PR 82 and others, each listing the wiki pages it changed |
| 6 | The wiki is published only by the workflow from `main` | Go: the last commit of all 21 pages has the message `Publish wiki from the repository`, which only the publisher writes |
---
[BC-001]: ../business-case.md
[ADR-0002]: ../adr/adr-0002-s01-approves-as-stand-in.md
[ea06eaa]: https://git.tirsystem.com/TirSystem/github-action/commit/ea06eaaa698247d20e4a8e2694d7acbb1de58b63
[ead3d98]: https://git.tirsystem.com/TirSystem/github-action/commit/ead3d98d73fcab95fd57b0eb005a02aff9983256
@@ -1,99 +0,0 @@
# MIL-006: Shared wiki publishing
## Metadata
| Key | Value |
| --- | --- |
| ID | MIL-006 |
| CrossReference | [BC-001], [MIL-005], [ADR-0003], [ADR-0002] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-11 | Deprecated | Jens Tirsvad Nielsen | S01 | Criterion 1 evidence amended; added the verification results of the pilot | [d575f27] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Task 6 added and reviewed (RC-058): the publisher sends page titles with spaces, so a hyphenated page (`Home-da`) is stored as `Home-da.md` and its links resolve | [8051cc4] |
---
## Purpose
Decide whether any repository on the instance can publish its own wiki from a
`wiki/` folder through one shared workflow, without a copy of the workflow and
without risk to repositories that did not ask for it.
## Deliverable
A scoped workflow `publish-wiki.yml` in `.gitea/scoped_workflows/` with its
publish script embedded, an opt-in rule that leaves every repository without
it untouched, offline tests, updated guides and wiki pages, and one
repository other than this one that publishes its wiki through it.
## Go / No-Go Criteria
| # | Criterion (objectively checkable) | Go | No-Go |
| --- | --- | --- | --- |
| 1 | A repository without the opt-in marker is never written to, shown by offline tests and by the trigger rule (a run in such a repository cannot be started: a scoped workflow is not dispatchable through the API and runs only on a push that changes `wiki/**`) | No request writes to its wiki | Any write |
| 2 | The workflow exists once: the copy in `.gitea/workflows/` is removed and no script is needed from `tools/` | Count is 1 | A second copy exists |
| 3 | One repository outside this one publishes its wiki through the shared workflow | Pages on the wiki equal its `wiki/` | Pages differ or run fails |
| 4 | An empty or missing `wiki/` never deletes pages, and a failure names its category | Verified by tests | A wiki was emptied |
| 5 | The per-organisation secret `TOKEN_FOR_GITEA_WIKI` is documented, and stored in the pilot's organisation | Documented and stored | Missing |
| 6 | The onboarding and credentials guides and their three wiki languages describe opting in | Pages updated | Out of date |
## Dependencies
| Depends on | Reason |
| --- | --- |
| MIL-005 | The publisher, the page layout and the wiki rules come from it |
| MIL-002 | Scoped delivery across organisations was verified there (issue #9) |
## Traceability
| Business Case objective / KPI / user story | Reference |
| --- | --- |
| O2, O3 | [BC-001] |
## Ownership
| Role | Stakeholder ID (SA) |
| --- | --- |
| Owner | S05 |
| Approving reviewer | S01 |
## Target Date
2026-12-26 — confirmed on 2026-10-10 by S01, standing in for S05 (ADR-0002); the Business Case sets no deadline.
## Tasks
| # | Task | Summary | Needs its own Use Case/User Story? | Reference |
| --- | --- | --- | --- | --- |
| 1 | Decide the opt-in rule and the secret handling | A scoped workflow runs in every repository of an organisation, and the publisher deletes pages that are not in `wiki/`. Choose how a repository opts in (a marker file such as `wiki/.publish`, a repository variable, or an allow list), what happens when the secret is missing, and whether the pilot uses `TOKEN_FOR_GITEA_WIKI` or the fallback. Record it as an ADR that refines ADR-0003. | No | |
| 2 | Make the publisher a scoped workflow | Embed the publish script in `.gitea/scoped_workflows/publish-wiki.yml` as the metadata sync does, so it needs nothing from `tools/` in the target repository, and run it only on a change under `wiki/`. Remove `.gitea/workflows/publish-wiki.yml` and `tools/publish_wiki.py` so the workflow has one source, and keep this repository's drift check in the validation tests. | No | |
| 3 | Implement the opt-in gate and the safety limits | Skip, successfully and with a log line, any repository that has not opted in. Keep the refusal on an empty `wiki/` and the categorised errors, and add offline tests with a fake Gitea for opted-in, not opted-in and missing-secret runs. | No | |
| 4 | Pilot in one other repository | Choose one repository outside this one, add a `wiki/` folder with the marker, store `TOKEN_FOR_GITEA_WIKI` in its organisation (S03), publish, and read the pages back. Also confirm that a repository without the marker was not touched. | No | |
| 5 | Update the guides and the wiki | Describe how a repository opts in and which secrets its organisation needs in the onboarding and credentials guides, regenerate the wiki pages and update the Danish and Bahasa Malaysia translations (rule 8 of `AGENTS.md`). | No | |
| 6 | Fix the page title of hyphenated pages | Gitea keeps a hyphen in a title literal, so the publisher created `Home-da` as `Home-da.-.md`, addressed `Home%2Dda`, and every link to `Home-da` led to the page list (found on the `sqa-and-qc`, `sqa-qc-framework` and `sqa-qc-checklists` wikis). Send the title with spaces (`Home da`, stored `Home-da.md`), cover it with a test and a changelog entry. The stale `*.-.md` pages are deleted after the release, by hand. | No | |
## Verification results
The pilot was `TirSystem/sqa-qc-checklists` (its PR 10, merged 2026-10-11).
The scoped workflow ran as run 629 on `d4ddbb6`, fetched the scripts at `v1`,
passed the token preflight and reported `Published 13 page(s): 0 created,
0 updated, 0 deleted`. The 13 pages of the wiki were then read back through
the API and equal `wiki/*.md` on `main` (0 differences).
| # | Criterion | Result |
| --- | --- | --- |
| 1 | A repository without the marker is never written to | Go by the offline tests (`test_a_repository_without_the_marker_is_never_written_to`: no request, the existing page unchanged; `..._does_not_need_the_secret`; `..._without_a_wiki_directory_is_skipped`) and by the trigger rule. A live run was tried on 2026-10-11 in `TirSystem/IaC.server-setup-4-linux`: the API answered 404, the workflow is not listed for that repository and cannot be dispatched. S01 accepted the weaker evidence on 2026-10-11 (RC-049) |
| 2 | The workflow exists once | Go: only `.gitea/scoped_workflows/publish-wiki.yml`; no copy in `.gitea/workflows/` and nothing is needed from `tools/` in the target repository (the script is fetched from `TirSystem/github-action`, MIL-004 task 6) |
| 3 | One repository outside this one publishes its wiki | Go: `TirSystem/sqa-qc-checklists`, run 629, 13 pages equal |
| 4 | An empty or missing `wiki/` never deletes pages; a failure names its category | Go: `test_an_empty_source_never_deletes_pages_even_with_prune` and the category tests |
| 5 | `TOKEN_FOR_GITEA_WIKI` is documented and stored in the pilot's organisation | Go: `guides/credentials.md`; run 629 used the organisation secret |
| 6 | The onboarding and credentials guides and their wiki languages describe opting in | Go: `wiki/.publish` and `TOKEN_FOR_GITEA_WIKI` appear in the guides and the English, Danish and Bahasa Malaysia pages |
---
[BC-001]: ../business-case.md
[ADR-0002]: ../adr/adr-0002-s01-approves-as-stand-in.md
[ea06eaa]: https://git.tirsystem.com/TirSystem/github-action/commit/ea06eaaa698247d20e4a8e2694d7acbb1de58b63
[d575f27]: https://git.tirsystem.com/TirSystem/github-action/commit/d575f272fcb044e3165951013464177a6e659ea6
[8051cc4]: https://git.tirsystem.com/TirSystem/github-action/commit/8051cc4489ee9bcf3b6c62f2eafcb2013b7d2f90
@@ -1,152 +0,0 @@
# MIL-007: Quality checks for C++ and C#
## Metadata
| Key | Value |
| --- | --- |
| ID | MIL-007 |
| CrossReference | [BC-001], [US-001], [UC-005], [MIL-003], [MIL-004], [ADR-0005], [ADR-0006], [ADR-0008] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Task 7 results added and reviewed (RC-059): adoption in two throwaway repositories, seeded failures verified, a guide gap fixed | [2481c26] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Throwaway repositories of task 7 deleted at the user's request; action item of RC-059 closed | [daecb7b] |
---
## Purpose
Decide whether a C++ or C# project can run the same kind of quality checks
as a Python or shell project, through a shared workflow of this repository,
and whether the runners of the instance can run them.
## Deliverable
Reusable quality-check workflows for C++ and for C#, each with a documented
set of inputs and pinned tool versions, a guide for reading its results on the
wiki in English, Danish and Bahasa Malaysia, a use of each in at least one
other repository, and a release that makes them available at the major tag.
The existing workflow `quality-checks.yml` for Python and shell keeps its
name and contract. The workflows run current tools only: a .NET SDK of version
10 or later, and the latest stable release of each clang tool; a tool that
is only available as an old version is not used.
## Go / No-Go Criteria
| # | Criterion (objectively checkable) | Go | No-Go |
| --- | --- | --- | --- |
| 1 | The runner of the instance can run the tools of each language (installed in the run or provided by the image), verified and recorded | Verified for both, at current versions (.NET SDK 10 or later) | A tool cannot be had without changing the runner, or only as an old version |
| 2 | The contract (tools, versions, inputs, what a pass and a fail mean) is decided in an ADR, and a language that cannot be checked without a build system says what it needs | ADR accepted | Open |
| 3 | A failing check shows the tool, file and line in the log, verified with a seeded failure for each workflow | Verified | Cause not visible |
| 4 | One other repository runs each workflow and its status appears on pull requests | Appears for both | Does not run |
| 5 | The workflows embed no script: each runs a file of this repository, and the offline tests exercise the file | Count of embedded scripts is 0 | Embedded script remains |
| 6 | A release (a minor version) makes both available, and the changelog and the wiki name them | Released | Unreleased |
## Dependencies
| Depends on | Reason |
| --- | --- |
| MIL-003 | The contract, the reusable workflow mechanism and the guide for reading results |
| MIL-004 | The release process and the release workflow publish the result |
## Traceability
| Business Case objective / KPI / user story | Reference |
| --- | --- |
| O4 | [BC-001] |
| US-001.09, US-001.10 (extended to C++ and C#) | [US-001] |
## Ownership
| Role | Stakeholder ID (SA) |
| --- | --- |
| Owner | S05 |
| Approving reviewer | S01 |
## Target Date
2027-01-16 — confirmed on 2026-10-11 by S01, standing in for S05 (ADR-0002); it follows the last decision of the plan, 2026-12-26, with two weeks from 2027-01-04. The Business Case sets no deadline.
## Tasks
| # | Task | Summary | Needs its own Use Case/User Story? | Reference |
| --- | --- | --- | --- | --- |
| 1 | Write the use case and stories for C++ and C# checks | Extend UC-005 (Run Project Quality Checks) so that its Brief names C++ and C#, and add stories to US-001 for a C++ project and a C# project, each with a pass and a fail acceptance criterion. Review them with the checklists of the `artifact` skill. | Yes | UC-005, US-001.09, US-001.10, US-001.16, US-001.17 |
| 2 | Verify what the runner provides | On a throwaway branch, run a job on `ubuntu-latest` that prints which of `clang-format`, `clang-tidy`, `cppcheck` and the .NET SDK (`dotnet --version`) exist, and whether each can be installed in the run (for example from PyPI, apt or the dotnet install script) and how long that takes. Record the result in the milestone like MIL-003 task 1. | No | |
| 3 | Decide the contract | Decided in ADR-0008 (accepted on 2026-10-11, RC-054): two separate reusable workflows, `quality-checks-cpp.yml` for C and C++ and `quality-checks-csharp.yml`, each running a script file fetched at `tools-ref`; C++: `clang-format --dry-run -Werror` and `clang-tidy` at exact current versions, no `cppcheck`; C#: `dotnet format --verify-no-changes` and a build with analyzers and warnings as errors, with the .NET SDK installed at an exact `10.0.x`; the inputs, the names of the workflows, guides and wiki pages and the consequences are in the ADR. | No | ADR-0008 |
| 4 | Implement the C++ workflow | Add the reusable workflow `quality-checks-cpp.yml` and its script file `tools/quality-checks-cpp.sh` as ADR-0008 decides, exact tool versions, least-privilege permissions and offline tests with stub tools, as `quality-checks.yml` does. | No | |
| 5 | Implement the C# workflow | The same for C#: `quality-checks-csharp.yml`, `tools/quality-checks-csharp.sh` and tests, as ADR-0008 decides. | No | |
| 6 | Write the guides and the wiki pages | One guide per workflow in `guides/` for reading its results, the wiki pages in English, Danish and Bahasa Malaysia, the Home workflow list and diagrams (a test requires every workflow to be listed), and an update of the upgrade guide. | No | |
| 7 | Adopt each workflow in one other repository | Onboard a real C++ project and a real C# project, or a throwaway repository when none exists, and fix the gaps in the guides that appear. Verify a seeded failure. | No | |
| 8 | Release | Add the changelog entry (a new workflow is a minor change, ADR-0006) and run the Release workflow; record the results in this milestone and review it. | No | |
## Verification results
Task 2 was run on 2026-10-11 with a throwaway branch, `verify-runner-tools`,
in `TirSystem/github-action` (run 692, deleted afterwards). One job on
`ubuntu-latest` printed what the image has and tried each way of installing a
tool.
| Fact | Result |
| --- | --- |
| Image | Ubuntu 24.04, `x86_64`, the job runs as root, `sudo`, `curl`, `python3` 3.12 and `pip` present |
| Present in the image | `gcc` and `g++` 13.3, `make`; missing: `clang-format`, `clang-tidy`, `cppcheck`, `cmake`, `dotnet` |
| `clang-format` | from PyPI in 2 s (23.1.3); from apt in 9 s |
| `clang-tidy` | from PyPI in 5 s (22.1.8); from apt in 25 s |
| `cppcheck` | apt gives 2.13.0 in 6 s, which is old (the latest release is 2.22.0); the PyPI package named `cppcheck` is a different project (1.5.3) and is not used; a current release needs a build from source |
| .NET SDK | the official script `dot.net/v1/dotnet-install.sh` with `--channel 10.0` gives 10.0.401 in 20 s; apt `dotnet-sdk-10.0` gives 10.0.112 in 23 s, an older feature band; the same script also offers 11.0 as a release candidate, which is not used |
A first run (run 692) looked at .NET SDK 8, which is not used: the requirement
is a .NET SDK of version 10 or later, and old tools are not run. A second run
(run 699, also deleted afterwards) checked current versions. The current
clang tools come from PyPI in a few seconds with an exact version, as
`quality-checks.yml` already does for its tools, and the .NET SDK 10 comes from
the official script in 20 s, with no change to the runner. `cppcheck` is the
exception: only an old version is a package. ADR-0008 drops it, because
`clang-tidy` does the static analysis and a current `cppcheck` would have to
be built from source, which costs minutes per run.
Not covered by this task: running a tool against a real C++ project (a
`clang-tidy` run needs a compile database or flags) or a real C# solution
(`dotnet format` and a build need the project's restore of packages from the
network), a private runner with no internet, and an image that differs from
`ubuntu-latest`. Those belong to the contract (task 3) and to the adoption
(task 7).
Task 7 was run on 2026-10-13 in two throwaway private repositories of the
organisation, `TirSystem/qc-adoption-cpp` and `TirSystem/qc-adoption-csharp`
(no real C++ or C# project exists there; the user chose throwaways in chat).
Each holds a small passing project, a style file, and a workflow that calls the
released `v1.2.0` (`quality-checks-cpp.yml`, `quality-checks-csharp.yml`) with
the guide's call. A branch `seeded-failure` with a pull request added a
formatting error and a null dereference.
| Repository | Baseline on `main` | Seeded failure (pull request 1) |
| --- | --- | --- |
| `qc-adoption-cpp` | Pass (runs 899, 900) | Fail (run 906): `main.cpp:3:13: error: code should be clang-formatted`, `main.cpp:5:18: error: Dereference of null pointer ... [clang-analyzer-core.NullDereference]`, `FAIL clang-format`, `FAIL clang-tidy (C++)`, last line `Quality checks failed: clang-format clang-tidy (C++)` |
| `qc-adoption-csharp` | Pass (runs 901, 902) | Fail: `src/Program.cs(5,3): error WHITESPACE`, `src/Program.cs(8,27): error CS8602`, `FAIL dotnet format --verify-no-changes`, `FAIL dotnet build -warnaserror` |
Both statuses (`quality` and `quality-checks-cpp` / `quality-checks-csharp`)
appear on the pull requests. One gap in the guides was found and fixed: they
said the paths are relative to `working-directory`, but `clang-tidy` and
`dotnet` print absolute paths in the workspace of the runner. The guides and
their three wiki languages now say so.
Not covered: a real C++ project with a compile database and a real C# solution
with many packages; both stay open until a project of that kind adopts the
workflows. The throwaway repositories were deleted at the user's request on 2026-10-13;
the run numbers above are kept as the record.
---
[BC-001]: ../business-case.md
[US-001]: ../user-stories.md
[UC-005]: ../uc-005/uc.md
[MIL-003]: ./mil-003-quality-checks.md
[MIL-004]: ./mil-004-versioned-release.md
[ADR-0005]: ../adr/adr-0005-quality-check-contract.md
[ADR-0006]: ../adr/adr-0006-release-process-and-version-pinning.md
[ADR-0008]: ../adr/adr-0008-cpp-csharp-quality-check-contract.md
[7bcc67a]: https://git.tirsystem.com/TirSystem/github-action/commit/7bcc67a065ac5f67b4e13ebf243a4bbbe2af47d9
[faf13b2]: https://git.tirsystem.com/TirSystem/github-action/commit/faf13b2c2a4901c0171977de1ffc2841023f537a
[2481c26]: https://git.tirsystem.com/TirSystem/github-action/commit/2481c26d802464decd51d75539157093b60e08e8
[daecb7b]: https://git.tirsystem.com/TirSystem/github-action/commit/daecb7b452197643b39752b9b453a8c376562354
@@ -1,86 +0,0 @@
# MIL-008: Wiki publishing as a reusable workflow
## Metadata
| Key | Value |
| --- | --- |
| ID | MIL-008 |
| CrossReference | [BC-001], [MIL-006], [ADR-0004], [RC-060], [RC-061] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | S01 | Initial version; reviewed (RC-060) | [01b9c29] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | S01 | Task 5 changed to deprecate the scoped workflow (8 repositories still use it); reviewed (RC-061) | [01b9c29] |
---
## Purpose
Decide whether the wiki can be published by a reusable workflow that each
repository calls, from `docs/wiki/` (the location `process/wiki.md` of the
framework prescribes), instead of a scoped workflow that runs in every
repository of the organisation and reads `wiki/`.
## Deliverable
A reusable workflow `publish-wiki-pages.yml` in `.gitea/workflows/` with a
`wiki_dir` input, a caller template for projects, offline tests, a superseding
ADR, updated guides and wiki pages, this repository publishing its own wiki
from `docs/wiki/` through it, the scoped workflow marked deprecated (not
removed), and a release that projects can pin.
## Go / No-Go Criteria
| # | Criterion (objectively checkable) | Go | No-Go |
| --- | --- | --- | --- |
| 1 | The reusable workflow publishes the folder named by `wiki_dir` (default `docs/wiki`), and a repository that has no caller workflow is never written to | Offline tests pass; no caller means no run | Any write without a caller |
| 2 | An empty or missing folder never deletes pages, the failure names its category, and the secret is passed explicitly (criteria 1 and 4 of MIL-006 still hold) | Existing tests pass unchanged | A regression |
| 3 | This repository publishes its own wiki from `docs/wiki/` through a caller that uses the reusable workflow, and the pages on the host equal the folder | 0 differences read back through the API | Pages differ or the run fails |
| 4 | A caller template exists for projects, with the trigger `docs/wiki/**` and the secret named | File exists and is linted (QC-WF-001) | Missing |
| 5 | The scoped `publish-wiki.yml` is marked deprecated in its header, the README and ADR-0009, and the repositories that still use it are listed; it is not removed here | Notice present and the list recorded (8 repositories on 2026-10-13) | No notice, or the workflow was removed while a repository still depends on it |
| 6 | The change is released as patch 1.2.2 and the moving major tag points at it | `v1` includes the change | Not released |
## Dependencies
| Depends on | Reason |
| --- | --- |
| MIL-006 | The publisher script, the prune rule and the safety limits come from it |
| `TirSystem/sqa-qc-framework` `process/wiki.md` | Defines `docs/wiki/` and the English plus PO language minimum; unmerged when this was written |
## Traceability
| Business Case objective / KPI / user story | Reference |
| --- | --- |
| O2, O3 | [BC-001] |
## Ownership
| Role | Stakeholder ID (SA) |
| --- | --- |
| Owner | S05 |
| Approving reviewer | S01 |
## Target Date
2026-11-15 — the Business Case sets no deadline.
## Tasks
| # | Task | Summary | Needs its own Use Case/User Story? | Reference |
| --- | --- | --- | --- | --- |
| 1 | Record the decision | An ADR that supersedes the scoped-delivery part of ADR-0004: publishing is a reusable workflow called by each repository; the caller file is the opt-in, so `wiki/.publish` is no longer a gate; the `prune` setting becomes an input. Keep the rest of ADR-0004 (secret handling) as it stands. | No | |
| 2 | Add the reusable workflow | `.gitea/workflows/publish-wiki-pages.yml` with `on: workflow_call`, inputs `wiki_dir` (default `docs/wiki`) and `prune`, and the token as a declared secret. It runs `tools/publish_wiki.py` with `WIKI_DIR` and the prune setting from the inputs. Update the script and its tests: the marker is no longer required. | No | |
| 3 | Add the caller template | A `publish-wiki.yml` caller for projects (`uses: TirSystem/github-action/.gitea/workflows/publish-wiki-pages.yml@v1`, `paths: docs/wiki/**`, `secrets:` mapped). Proposed in `sqa-qc-framework` under `templates/ci/` once this is released. | No | |
| 4 | Move this repository's wiki and call the workflow | `git mv wiki docs/wiki`, check the links and the translation hash comments, add the caller, publish, read the pages back. | No | |
| 5 | Deprecate the scoped workflow | Do not remove it: on 2026-10-13, 8 repositories still publish through it with `wiki/.publish` (`sqa-and-qc`, `sqa-qc-framework`, `sqa-qc-checklists`, `github-action`, `repo-foundry` and three of `Tirsvad-Udemy-100-days-of-code`), and none calls the reusable workflow yet. Add a deprecation notice to its header, the README table and ADR-0009, and record the list. The migrations and the removal are a follow-up milestone after this release (ADR-0006: a removed workflow is a new major). | No | |
| 6 | Update guides and wiki pages | Describe the caller, `docs/wiki/` and the removed marker in the onboarding and credentials guides and in the English, Danish and Bahasa Malaysia pages (rule 8 of `AGENTS.md`). | No | |
| 7 | Release | Release as a patch, 1.2.1 to 1.2.2, as the owner instructed: changelog entry and a release through the release workflow; the `v1` tag moves with it. ADR-0006 classes a new workflow as minor, so the changelog entry states the deviation and the reason. Nothing is removed, so no consumer breaks. | No | |
---
[BC-001]: ../business-case.md
[MIL-006]: ./mil-006-shared-wiki-publishing.md
[ADR-0004]: ../adr/adr-0004-shared-wiki-publishing-opt-in.md
[RC-060]: ../sqa/reviews/rc-060-mil-008-plan.md
[RC-061]: ../sqa/reviews/rc-061-mil-008-task-5-deferred.md
[01b9c29]: https://git.tirsystem.com/TirSystem/github-action/commit/01b9c2972b4317bcc590540010aea0eaf7f30014
@@ -1,109 +0,0 @@
# MIL-009: Migrate the wiki callers and remove the scoped workflow
## Metadata
| Key | Value |
| --- | --- |
| ID | MIL-009 |
| CrossReference | [BC-001], [MIL-008], [ADR-0004], [ADR-0006], [ADR-0009] , [RC-066] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-14 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Plan accepted in chat with the defaults: target date 2026-11-30 confirmed, `027-sandbox` and `028-pomodoro` do not publish, framework release 0.7.0; reviewed (RC-064) | [2f267df] |
| 2026-10-14 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Verification results recorded for tasks 1 to 8; outcome reviewed (RC-066) | [95abc18] |
---
## Purpose
Decide whether the scoped `publish-wiki.yml` can be removed: every repository
that publishes its wiki through it has moved to `docs/wiki/` and calls the
reusable workflow `publish-wiki-pages.yml`, and ADR-0004 is superseded by
ADR-0009. MIL-008 deprecated the scoped workflow and kept it because seven
repositories still depended on it (checked on 2026-10-13).
## Deliverable
A released framework with the caller template; each of the seven repositories
publishing its wiki from `docs/wiki/` through a caller, with its marker removed;
the scoped workflow, its marker code path, its tests and every mention of the
marker as an opt-in removed; ADR-0004 marked superseded; and the major release
2.0.0 with the tag `v2`.
## Go / No-Go Criteria
| # | Criterion (objectively checkable) | Go | No-Go |
| --- | --- | --- | --- |
| 1 | The framework is released as 0.7.0 with `templates/ci/publish-wiki.yml` and `process/wiki.md`, as a tag | The tag exists and each migrating repository pins it | No tag, or a repository pins an unmerged commit |
| 2 | Each of the seven repositories publishes from `docs/wiki/` through a caller of `publish-wiki-pages.yml`, and has no `wiki/.publish` | A scan of the instance lists the seven with a caller and no marker | Any marker or missing caller remains |
| 3 | The wiki of each of the seven equals its `docs/wiki/` after the first run | 0 differences read back through the API for each | A difference, or a failed run |
| 4 | A scan of every repository of the four organisations finds no `wiki/.publish` and no run of the scoped workflow that wrote | None found | Any found |
| 5 | The scoped `publish-wiki.yml`, the marker code path of `tools/publish_wiki.py`, their tests and the marker text of the guides, README and wiki pages are removed | Offline tests pass; a search finds no `wiki/.publish` outside the changelog and ADRs | A mention remains, or a test fails |
| 6 | ADR-0004 is `Superseded by ADR-0009` with a review record, and ADR-0009 links back | Both rows and RC present | Missing |
| 7 | Release 2.0.0 is published with a Breaking entry, `v2` points to it, and `v1` still points to 1.2.2 | Tags read back through the API | `v1` moved, or no Breaking entry |
## Dependencies
| Depends on | Reason |
| --- | --- |
| MIL-008 | Provides the reusable workflow, the deprecation and the list of repositories |
| `TirSystem/sqa-qc-framework` release | The caller template and `process/wiki.md` must be a tag before a repository pins them |
## Traceability
| Business Case objective / KPI / user story | Reference |
| --- | --- |
| O2, O3 | [BC-001] |
## Ownership
| Role | Stakeholder ID (SA) |
| --- | --- |
| Owner | S05 |
| Approving reviewer | S01 |
## Target Date
2026-11-30 — confirmed on 2026-10-14 by S01 in chat; the Business Case sets no deadline.
## Tasks
| # | Task | Summary | Needs its own Use Case/User Story? | Reference |
| --- | --- | --- | --- | --- |
| 1 | Release the framework | `TirSystem/sqa-qc-framework` has the caller template and `process/wiki.md` merged (pull request 45). Add the changelog entry, tag the release and record the tag. Needed before any repository pins the template. | No | |
| 2 | Migrate the three TirSystem projects | `sqa-and-qc`, `sqa-qc-framework` and `sqa-qc-checklists`: move `wiki/` to `docs/wiki/`, copy the caller from `templates/ci/publish-wiki.yml`, remove `wiki/.publish`, fix the paths in their generators and documents, move the framework pin to the released tag, one pull request each. Confirm the organisation secret `TOKEN_FOR_GITEA_WIKI` is present. | No | |
| 3 | Migrate `repo-foundry` | Same steps for `TirSystem-BashScript/repo-foundry` (21 wiki files); the organisation `TirSystem-BashScript` needs its own `TOKEN_FOR_GITEA_WIKI` secret (S03). | No | |
| 4 | Migrate the three Udemy repositories | Same steps for `021-snake-game`, `024-snake` and `025-weather` of `Tirsvad-Udemy-100-days-of-code` (5 wiki files each). `027-sandbox` and `028-pomodoro`, which have `docs/wiki/` and no marker, do not publish (decided by S01 on 2026-10-14). | No | |
| 5 | Verify the migration | After each first run read the wiki back and compare it with `docs/wiki/`; then scan the four organisations for `wiki/.publish` and for repositories still publishing through the scoped workflow. Record the results in this milestone. | No | |
| 6 | Remove the scoped workflow | Delete `.gitea/scoped_workflows/publish-wiki.yml`, the marker path of `tools/publish_wiki.py` (the `WIKI_PRUNE` input becomes required), the tests that cover it and the marker text in the guides, the README and the three wiki languages. Keep the drift test for the remaining scoped workflow. | No | |
| 7 | Supersede ADR-0004 | Mark ADR-0004 `Superseded by ADR-0009` for the delivery and marker parts (new version row, review record), and make ADR-0009 link back. | No | |
| 8 | Release 2.0.0 | Breaking entry (a removed workflow and marker); upgrade guide for callers; release through the release workflow; `v2` is created and `v1` stays at 1.2.2. Move the examples in the guides to `@v2` where the guide describes the new major. | No | |
---
## Verification results
Recorded on 2026-10-14 by the autonomous run.
| # | Criterion | Result |
| --- | --- | --- |
| 1 | The framework is released as 0.7.0 with the template and `process/wiki.md`, and each repository pins it | Go: tag `v0.7.0` on `70fc558`. `sqa-and-qc`, `repo-foundry`, `021-snake-game`, `024-snake` and `025-weather` pin it; `sqa-qc-framework` and `sqa-qc-checklists` have no `framework/` submodule to pin |
| 2 | Each of the seven repositories publishes from `docs/wiki/` through a caller and has no `wiki/.publish` | Go: `sqa-and-qc` #168, `sqa-qc-framework` #47, `sqa-qc-checklists` #17, `repo-foundry` #96, `021-snake-game` #29, `024-snake` #46, `025-weather` #31 |
| 3 | The wiki of each equals its `docs/wiki/` after the first run | Go: 0 differences read back through the API (10, 16, 13, 19, 4, 4 and 4 pages); each first run succeeded |
| 4 | A scan of every repository of the four organisations finds no `wiki/.publish` | Go: 48 repositories scanned, none found |
| 5 | The scoped workflow, the marker path, their tests and the marker text are removed | Go with a note: pull request #151; `wiki/.publish` remains only in the changelog, the ADRs, the milestone and review records and the sentence of the upgrading guide that explains the removal |
| 6 | ADR-0004 is `Superseded by ADR-0009` with a review record, and ADR-0009 links back | Go: RC-065 |
| 7 | Release 2.0.0 is published with a Breaking entry, `v2` points to it, and `v1` still points to 1.2.2 | Go: `v2.0.0` and `v2` on `6e8e548`, `v1` and `v1.2.2` on `9bf0a2b`; the release page shows the Breaking group |
Things that did not go as planned: the three Udemy pull requests were opened through a script that hit a network timeout once and was repeated; the `repo-foundry` test suite fails two tests on `main` and on the branch alike (pre-existing, not caused by this milestone).
---
[BC-001]: ../business-case.md
[RC-066]: ../sqa/reviews/rc-066-mil-009-outcome.md
[MIL-008]: ./mil-008-wiki-reusable-workflow.md
[ADR-0004]: ../adr/adr-0004-shared-wiki-publishing-opt-in.md
[ADR-0009]: ../adr/adr-0009-wiki-publishing-reusable-workflow.md
[ADR-0006]: ../adr/adr-0006-release-process-and-version-pinning.md
[2f267df]: https://git.tirsystem.com/TirSystem/github-action/commit/2f267df2a270087cb7dc482af4ce4f4341e97b03
[95abc18]: https://git.tirsystem.com/TirSystem/github-action/commit/95abc18a95d70c065b979123b8f8de22173af90c
@@ -1,198 +0,0 @@
# MIL-010: Code metrics and coverage badges
## Metadata
| Key | Value |
| --- | --- |
| ID | MIL-010 |
| CrossReference | [BC-001], [US-001], [MIL-003], [MIL-004], [ADR-0005], [ADR-0006] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-14 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Results of tasks 3, 6 and 8 added: the report as an artifact of the caller (ADR-0010), adoption in a throwaway repository with seeded change and failure; reviewed (RC-074) | [5c5a1d1] |
| 2026-10-14 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Task 9 results added: released as 2.1.0; outcome reviewed (RC-075) | [aa20e56] |
---
## Purpose
Decide whether a repository can show, as SVG badges, how many code files and
how many lines of code (without comment and blank lines) it holds and how
much of that code its tests cover, produced by one shared workflow of this
repository, without a service outside the instance.
## Deliverable
A reusable workflow `code-metrics.yml` with a script file of this repository
behind it, which counts the code files and the lines of code, reads the
coverage report the caller supplies, writes the badges "code files", "lines
of code" and "coverage" as SVG files and commits them to a `badges` branch of
the calling repository. It comes with a documented set of inputs, a guide and
wiki pages in English, Danish and Bahasa Malaysia, a use in at least one other
repository, and a release that makes it available at the major tag. The
existing workflows keep their names and contracts.
Decisions taken by the user in chat on 2026-10-14, which the contract of task 2
records and does not reopen:
- The counter is a Python script of this repository with no dependency outside
the standard library (not `cloc`, `tokei` or `scc`).
- The delivery is a reusable workflow (`workflow_call`), as the quality-check
workflows are.
- The badges are committed to a `badges` branch, so a README can link to
them; they are not only a run artifact.
- Three badges: code files, lines of code and coverage. A badge per language
is optional and is decided in the ADR of task 2.
- The coverage report is read in the Cobertura XML format, which `coverage.py`,
`gcovr` and `coverlet` all write; the counter does not run tests itself, so a
caller that wants a coverage badge runs its tests first and passes the path
of the report.
## Go / No-Go Criteria
| # | Criterion (objectively checkable) | Go | No-Go |
| --- | --- | --- | --- |
| 1 | A job on the runner of the instance can push a commit to a `badges` branch of its own repository with the token the run provides, and the SVG renders as an image in a README on the instance and on the GitHub mirror, verified and recorded | Both render | The push needs a token with more than the contents of its own repository, or the image does not render |
| 2 | The contract (what a code file is, what a comment and a blank line are for each language, excluded paths, generated and vendored files, the coverage report format, the badge colours and text) is decided in an ADR | ADR accepted | Open |
| 3 | The counter gives the hand-counted numbers (files, code, comment, blank) for a fixture of each supported language, including a block comment, a trailing comment, a comment marker inside a string and a file with no final newline | Equal for every fixture | Any difference |
| 4 | The coverage reader gives the percentage of the fixture reports, and a missing or malformed report is a failure that names the file, never a badge showing 0% | Verified | A bad report produces a badge |
| 5 | The badges are valid SVG, carry a title and a text alternative, have a fixed width per text, and are byte-identical for the same input | Verified | Not valid or not stable |
| 6 | The workflow commits nothing when no badge changed, does not start itself again from its own push, and asks for the least permission that writes to its own repository | Verified in a run | A loop, or a wider permission |
| 7 | One other repository runs the workflow and its README shows the three badges, with a seeded change that moves the coverage badge to another colour | Shown | Does not run or does not change |
| 8 | The workflow embeds no script: it runs a file of this repository, and the offline tests exercise the file | Count of embedded scripts is 0 | Embedded script remains |
| 9 | A release (a minor version) makes it available, and the changelog, the README workflow table and the wiki name it | Released | Unreleased |
## Dependencies
| Depends on | Reason |
| --- | --- |
| MIL-003 | The reusable workflow mechanism, the `tools-ref` input and the guide for reading results |
| MIL-004 | The release process and the release workflow publish the result |
## Traceability
| Business Case objective / KPI / user story | Reference |
| --- | --- |
| O5 (added to the Business Case in the same change as this milestone) | [BC-001] |
| New stories of task 1, to be written in US-001 | [US-001] |
## Ownership
| Role | Stakeholder ID (SA) |
| --- | --- |
| Owner | S05 |
| Approving reviewer | S01 |
## Target Date
2027-01-30 — it follows the last decision of the plan, 2027-01-16, with two
weeks from 2027-01-18; proposed by the AI and accepted by the user in chat on
2026-10-14, recorded by the AI as stand-in for S05 (ADR-0002). The Business
Case sets no deadline.
## Tasks
| # | Task | Summary | Needs its own Use Case/User Story? | Reference |
| --- | --- | --- | --- | --- |
| 1 | Write the use case and stories for the metrics badges | Add a use case "Show code metrics and coverage badges" for the software engineer, add it to the use case diagram, and add stories to US-001: the badges appear after a push, a coverage report that is missing or malformed fails with the file named, and nothing is committed when the numbers are unchanged. Each story has a pass and a fail acceptance criterion. Review them with the checklists of the `artifact` skill. | Yes | US-001 |
| 2 | Decide the contract | Write an ADR with the definitions the counter needs (code file, comment, blank line, per language), the default includes and excludes, the languages of the first version, the Cobertura XML coverage input, the badge texts and colour thresholds, the inputs of the workflow, the name and content of the `badges` branch, and what a pass, a failure and a run without files mean, in the style of ADR-0005. Record the decisions of the Deliverable. | No | |
| 3 | Verify the delivery on the instance | On a throwaway branch, run a job that commits an SVG to a `badges` branch with the token of the run, then check that the raw URL serves it as an image on the instance, that a README shows it, and that it also shows on the GitHub mirror. Record the result in this milestone like MIL-007 task 2, together with the permission that was needed. | No | |
| 4 | Implement the counter | Add `tools/count_loc.py` and tests with a fixture per language under `tests/`: file and line counts split into code, comment and blank, an exclude list, and a machine-readable result on standard output. Standard library only, as the rules of the repository for tools say. | No | |
| 5 | Implement the coverage reader and the badge renderer | Add the reader of the Cobertura XML report and the SVG renderer, with the failure cases of Go/No-Go criterion 4 and a stable output (criterion 5), each with offline tests. | No | |
| 6 | Implement the workflow | Add the reusable workflow `code-metrics.yml` and its script file, which calls the counter, the reader and the renderer and commits to the `badges` branch as the contract of task 2 says, with least-privilege permissions and offline tests as `quality-checks.yml` has. | No | |
| 7 | Write the guides and the wiki pages | A guide in `guides/` with the call, the inputs, how to produce a coverage report for Python, C++ and C#, and the Markdown line that shows the badges; the wiki pages in `docs/wiki` in English, Danish and Bahasa Malaysia; the README table and diagram and the wiki Home workflow list (a test requires every workflow to be listed). | No | |
| 8 | Adopt the workflow in one other repository | Onboard a real repository, or a throwaway one when none fits, show the badges in its README and verify a seeded change that moves the coverage badge. Fix the gaps in the guide that appear. | No | |
| 9 | Release | Add the changelog entry (a new workflow is a minor change, ADR-0006) and run the Release workflow; record the results in this milestone and review it. | No | |
## Verification results
Task 3 was run on 2026-10-14 with a throwaway branch, `verify-badges-delivery`,
in `TirSystem/github-action` (run 1418, success). One job on `ubuntu-latest`
with `permissions: contents: write` checked the repository out, created an
orphan branch `badges-verify` with one SVG file and a commit message ending in
`[skip ci]`, and pushed it with the token of the run (the credential that
`actions/checkout` stores); it then requested the raw URL.
| Fact | Result |
| --- | --- |
| Push with the token of the run | Accepted: `git push origin HEAD:refs/heads/badges-verify` created the branch; no secret and no personal access token was needed |
| Raw URL on the instance | `https://git.tirsystem.com/TirSystem/github-action/raw/branch/badges-verify/code-files.svg` answers `200`, `Content-Type: image/svg+xml`, `Content-Security-Policy: default-src 'none'; style-src 'unsafe-inline'; sandbox`, `Cache-Control: public, max-age=21600` (six hours) |
| The branch on the GitHub mirror | The push mirror (`sync_on_commit`, every 8 h otherwise) copied the branch within seconds; `https://raw.githubusercontent.com/TirSystem/github-action/badges-verify/code-files.svg` answers `200`, `Content-Type: image/svg+xml`, `Cache-Control: max-age=300` |
| Repository visibility | Public; a README image on GitHub reads the raw URL, which needs no token |
The SVG is served as an image on both hosts, so it renders in a README on the
instance and on the mirror; the content security policy rules out script and
external references inside the file, as ADR-0010 requires. The six-hour
cache on the instance means a changed badge can show the old number for up to
six hours there; the guide says so. Not covered by this task: a private
repository (the raw URL then needs a login, so a badge does not render for an
anonymous reader), and the rendering inside a Gitea README, which is the same
`<img>` request. The throwaway branches `verify-badges-delivery` and
`badges-verify` are left in place because deleting a branch is an action the
run stops on; they are listed in the summary for the user to delete.
Task 6 changed the contract once while it was implemented. A called workflow
runs in its own job, so it cannot read a report that the caller's test job
wrote in its workspace; a report the repository commits is the only file it can
see. ADR-0010 was amended (RC-073): the caller uploads the report as an
artifact and names it in the new input `coverage-artifact`; the workflow
downloads it with `actions/download-artifact` into the directory
`coverage-artifact` and `coverage-report` names the file inside it. The scope
and the three badges did not change.
Task 8 was run on 2026-10-14 in a throwaway private repository of the
organisation, `TirSystem/code-metrics-adoption` (no repository of a project
fits, and the user's plan allows a throwaway). It holds a two-file Python
module with tests and a workflow of two jobs: the tests with `pytest-cov`
upload `coverage.xml` as the artifact `coverage`, and the second job calls
`code-metrics.yml` and `tools-ref` of the branch `mil-010-implementation` of
this repository, before its merge.
| Step | Result |
| --- | --- |
| Baseline (run 1423) | All steps pass, including `Download the coverage report` with `actions/download-artifact@v4.1.8` on Gitea 1.27.3; the `badges` branch is created with one commit by `code-metrics` and the message `Update code metrics badges [skip ci]`; `code-files.svg` shows 2, `code-lines.svg` 28 (the hand count of the two files), `coverage.svg` 100% in green `#44cc11` |
| The push of the badges | No run was started by it: the runs of the repository are the two of the push to `main` (the metrics workflow and the scoped sync) |
| Seeded change (run 1425): two tests removed | The coverage badge reads 60% in yellow `#dfb317`; one new commit on `badges` that changes the badge files; the files and the lines badges changed with the tests |
| Seeded failure (run 1429): `coverage-report` names a file that does not exist | The job `code-metrics` fails: `::error::[configuration] coverage-report 'coverage-artifact/nope.xml' does not exist.`; `badges` is unchanged (two commits) |
| README | Its three Markdown images render as `<img>` of the raw URLs of the `badges` branch (checked with the markdown API of the instance); the raw URLs answer `image/svg+xml` as in task 3 |
Not covered: a run that changes nothing (the unchanged case is covered by the
offline tests, not by a run), two runs that write the branch at the same time
(covered by an offline test with a rejecting remote, not on the instance), the
rendering for a reader who is not signed in to a private repository, and a
repository of a project with a real coverage report. The throwaway repository
`TirSystem/code-metrics-adoption` is left in place because deleting a
repository is an action the run stops on; it is listed in the summary for the
user to delete.
Task 9 was run on 2026-10-14. The implementation was merged in pull request
164 after its checks were green; the user merged it, because the host refused
the merge through the API with a required check `Publish wiki / *` that the
branch protection API does not list and that nothing in this repository
reports. The Release workflow was run for 2.1.0 on the merge commit
`16faffa`: a dry run (run 1462) and then the release (run 1463), both green.
| Check | Result |
| --- | --- |
| Tag | `v2.1.0` and the moved major tag `v2` both point at `16faffa` |
| Release page | `v2.1.0`, not a draft, with the changelog entry as its text (`Added`: the workflow `code-metrics.yml`) |
| Callable at the major tag | `.gitea/workflows/code-metrics.yml` and `tools/count_loc.py` are served at `v2` and `v2.1.0` |
| Checks on `main` after the merge | validation, milestone publishing, wiki publishing and the metadata sync all green (runs 1458 to 1461) |
Go/No-Go criteria of this milestone at its close: 1 to 8 as in the results
above; 9 (a release makes it available, and the changelog, the README table and
the wiki name it) is met by the release of 2.1.0. Success criterion 5 of the
Business Case (a repository besides this one shows the badges) is met in a
throwaway repository only; a project repository has not adopted it yet.
---
[BC-001]: ../business-case.md
[US-001]: ../user-stories.md
[MIL-003]: ./mil-003-quality-checks.md
[MIL-004]: ./mil-004-versioned-release.md
[ADR-0005]: ../adr/adr-0005-quality-check-contract.md
[ADR-0006]: ../adr/adr-0006-release-process-and-version-pinning.md
[5002450]: https://git.tirsystem.com/TirSystem/github-action/commit/50024505fe788b1c5e3021c0d1fc3d079590070e
[5c5a1d1]: https://git.tirsystem.com/TirSystem/github-action/commit/5c5a1d19d96a6979b4f6141e736957174ba686a9
[aa20e56]: https://git.tirsystem.com/TirSystem/github-action/commit/aa20e56110f4c2fab91a8432ba008ee8300926a2
@@ -1,119 +0,0 @@
# MIL-011: Fix the defaults of the code metrics workflow
## Metadata
| Key | Value |
| --- | --- |
| ID | MIL-011 |
| CrossReference | [BC-001], [US-001], [MIL-010], [ADR-0010], [ADR-0006] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-14 | Accepted | Jens Tirsvad Nielsen | S01 | Added the results of task 1 (reproduction and the defaults of the five workflows); reviewed (RC-077), accepted by the AI as stand-in for S01 in autonomous mode | [e11c43f] |
| 2026-10-14 | Proposed | Jens Tirsvad Nielsen | S01 | Added the results of tasks 2 to 5 (the fix, the test, the guides, the run on the instance); reviewed in RC-078, the release follows | [a6892c3] |
---
## Purpose
Decide whether the released code metrics workflow can be called with its documented defaults, and correct it if it cannot.
Release 2.1.0 ([MIL-010]) added `code-metrics.yml`. Its guide, its header comment and the default of its `tools-ref` input name `v1`, but the workflow and its scripts (`tools/code-metrics.sh`, `tools/count_loc.py`, `tools/badges.py`) exist only from `v2.1.0`. A caller who follows the guide (`@v1`) cannot resolve the workflow, and a caller at `@v2` that leaves `tools-ref` at its default fetches the scripts from `v1`, where they are absent, so the run fails. The offline tests of [MIL-010] did not see it, because they run the scripts from the checkout and never resolve a ref. The framework wiki page `Badges` works around it by telling callers to set `tools-ref: v2`.
The other four reusable workflows also default `tools-ref` to `v1`; their scripts exist at `v1`, but a default that follows an old major is the same kind of error, so this milestone checks them too.
## Deliverable
A patch release (`2.1.1`, [ADR-0006]) in which: the default `tools-ref` of every reusable workflow names a tag that holds the scripts it runs; the guide, the header comment of `code-metrics.yml`, the upgrading guide, the README and the wiki pages in English, Danish and Bahasa Malaysia call the workflow at `@v2`; a test fails when a default `tools-ref` names a tag without the script; and the changelog has a `Fixed` entry. In `TirSystem/sqa-qc-framework`: the `Badges` wiki page without the `tools-ref` workaround.
## Go / No-Go Criteria
| # | Criterion (objectively checkable) | Go | No-Go |
| --- | --- | --- | --- |
| 1 | The defect is reproduced before the fix: a call at the major tag with the defaults fails, and the failure names the missing script, recorded in this milestone | Reproduced and recorded | Not reproduced, or not recorded |
| 2 | Every reusable workflow's default `tools-ref` names a tag that contains the script file the workflow runs, listed per workflow in this milestone | All five checked and listed | A default names a tag without its script |
| 3 | The default is derived, not copied: one place gives the current major, and a test fails when a workflow default differs from it or names a tag without the script | Test fails on a seeded wrong default and passes on the fix | No such test |
| 4 | No guide, comment, README or wiki page tells a caller to use `@v1` for `code-metrics.yml`; a search of `guides/`, `README.md`, `docs/wiki/` and `.gitea/workflows/` finds none | Count is 0 | A page still says `@v1` for it |
| 5 | A call with the documented defaults runs on the instance and commits the badges to a `badges` branch, verified on a throwaway branch and recorded | Run succeeds | Fails or is not run |
| 6 | The release is a patch (`2.1.1`): the changelog has a `Fixed` entry, the major tag `v2` moves to it, and `v1` is not touched | Released | Released as another level, or `v1` moved |
| 7 | The framework `Badges` page no longer tells a caller to set `tools-ref`, in all three languages, and still calls the workflow at `@v2` | Page merged | The workaround remains |
| 8 | Reviewed | A review record (`RC-*`) for this milestone and the changed workflow, tests and guides, each with a verdict of Go | An instance without a record |
## Dependencies
| Depends on | Reason |
| --- | --- |
| [MIL-010] | The workflow and its guide are its deliverables; the defect is in release 2.1.0 |
| [ADR-0006] | The release process: a fix is a patch release, and a moving major tag follows it |
## Traceability
| Business Case objective / KPI / user story | Reference |
| --- | --- |
| Business Case objective O5: a shared workflow that counts the code files and lines of code, reads the coverage report and publishes the three results as SVG badges; the workflow cannot be called as documented until this milestone is done | [BC-001] |
| User stories | [US-001] (no new story: the tasks below are technical, and the story of [MIL-010] for the badges stays as written) |
## Ownership
| Role | Stakeholder ID (SA) |
| --- | --- |
| Owner | S05 |
| Approving reviewer | S01 |
## Target Date
2026-10-23 (Friday), one week of work: the fix is small and a caller cannot use the workflow until it is released. This precedes the planned decision date of [MIL-010] (2027-01-30) because that milestone was released on 2026-10-14, ahead of its date; the schedule row of [MIL-010] is not changed here. The Business Case sets no deadline.
## Tasks
| # | Task | Summary | Needs its own Use Case/User Story? | Reference |
| --- | --- | --- | --- | --- |
| 1 | Reproduce the defect and list the defaults | On a throwaway branch, call `code-metrics.yml` at `@v2` with the defaults and at `@v1`, and record both failures and the message. List, for each of the five reusable workflows, the default `tools-ref` and whether the script it runs exists at that tag. Record the result in this milestone. | No | [MIL-010] |
| 2 | Fix the defaults | Give the repository one definition of the current major (a file the workflows' tests and the release workflow read), set the default `tools-ref` of every reusable workflow from it, and change the header comment of `code-metrics.yml` to `@v2`. A workflow whose script is at the previous major keeps that tag only with a comment that says why. | No | [ADR-0006] |
| 3 | Add the test | An offline test that reads every workflow in `.gitea/workflows/`, takes the default `tools-ref` and the script it runs, and fails when the default differs from the current major or the script is not in that tag (checked with `git cat-file` against the tags of the checkout). Show it fails on a seeded wrong default and passes on the fix. | No | [MIL-010] |
| 4 | Correct the guides, README and wiki | Change `@v1` to `@v2` for `code-metrics.yml` in `guides/code-metrics.md`, `guides/upgrading.md`, `README.md` and `docs/wiki/CodeMetrics.md`, `.da.md` and `.ms.md`; say in the guide that `tools-ref` defaults to the current major. Search the repository for the remaining `@v1`. | No | |
| 5 | Verify on the instance | On a throwaway branch of a repository, call the fixed workflow at the branch with the defaults, and check that the `badges` branch gets the SVG files. Record the run. | No | [MIL-010] |
| 6 | Release 2.1.1 | Add the `Fixed` entry to the changelog (ADR-0006: a patch), run the Release workflow, and check that `v2` points at `v2.1.1` and `v1` at `v1.2.2`. | No | [ADR-0006] |
| 7 | Remove the workaround from the framework page | In `TirSystem/sqa-qc-framework`, remove the `tools-ref: v2` line and the two bullets about it from `docs/wiki/Badges.md`, `Badges-da.md` and `Badges-ms.md`, and add a changelog line. This is a change in another repository, made after release 2.1.1 and in its own pull request. | No | |
| 8 | Add MIL-011 to the Project Plan | Add the schedule row, the Gantt bar, the scope entry and the dependency to [PP-001], and its review to the traceability matrix. | No | |
| 9 | Review | Record `RC-*` for this milestone, the workflow and tests, and the guides, each with a verdict. | No | |
## Verification results
Task 1 was run on 2026-10-14 with the throwaway branch `verify-code-metrics-defaults` of `TirSystem/github-action`. It calls `code-metrics.yml` at the two refs a caller could use, with every input at its default.
| Call | Result | Evidence |
| --- | --- | --- |
| `...code-metrics.yml@v2`, defaults | Fails in the step "Validate the inputs": `bash: shared-scripts/tools/code-metrics.sh: No such file or directory`, exit code 127. The input `tools-ref` is `v1`, so the scripts are fetched from `v1`. | run 1499, job 1638 |
| `...code-metrics.yml@v1`, defaults | No run is created at all, and no error is shown: two pushes of a workflow that calls it (once with the `@v2` job beside it, once alone) made no run in over a minute, while the push of the `@v2` call alone made one | commits `5654905` and `46e752d` (no run), `9a17868` (run 1499) |
The defaults of the five reusable workflows at `v2.1.0` (`v1` is `1.2.2`, `v2` is `2.1.0`):
| Workflow | Default `tools-ref` | Script it runs | At the default | At `v2` |
| --- | --- | --- | --- | --- |
| `code-metrics.yml` | `v1` | `tools/code-metrics.sh` | **absent** | present |
| `quality-checks.yml` | `v1` | `tools/quality-checks.sh` | present | present |
| `quality-checks-cpp.yml` | `v1` | `tools/quality-checks-cpp.sh` | present | present |
| `quality-checks-csharp.yml` | `v1` | `tools/quality-checks-csharp.sh` | present | present |
| `publish-wiki-pages.yml` | `v1` | `tools/publish_wiki.py` | present | present |
Only `code-metrics.yml` is broken. The other four resolve, but a caller at `@v2` runs their scripts from `1.2.2` and not from `2.1.0`; `tools/publish_wiki.py` changed in `2.0.0` (it requires `WIKI_PRUNE` and no longer reads a marker). Whether that is a defect is decided in task 2.
Tasks 2 to 5 were done on 2026-10-14 on the branch `mil-011-fix`:
- **Fix (task 2):** the file `MAJOR_TAG` holds the current major (`v2`); the default `tools-ref` of the five reusable workflows is `v2`, and the header comment of `code-metrics.yml` calls it at `@v2`. The four workflows other than `code-metrics.yml` followed the older major only by default and changed no behaviour for a caller at `@v1`; for a caller at `@v2` the scripts now come from the same major as the workflow.
- **Test (task 3):** `tests/test_tools_ref.py` ties `MAJOR_TAG` to the highest major of the changelog and checks every reusable workflow's default and script. With `default: "v1"` seeded in `code-metrics.yml` three tests failed; restored, they pass. The suite passes (540 tests).
- **Guides (task 4):** `guides/code-metrics.md`, `guides/upgrading.md`, the three quality-check guides, `README.md` and the wiki pages in English, Danish and Bahasa Malaysia; the amendments of ADR-0005, ADR-0008, ADR-0009 and ADR-0010. A search for `code-metrics.yml@v1` finds none.
- **Instance (task 5):** the workflow at `@mil-011-fix` with every input at its default except `badges-branch` ran as run 1509 (job 1649): `tools-ref` resolved to `v2`, the scripts were fetched, and the badges were committed to `badges-verify` (commit `041d991`).
---
[BC-001]: ../business-case.md
[US-001]: ../user-stories.md
[MIL-010]: ./mil-010-code-metrics-badges.md
[ADR-0010]: ../adr/adr-0010-code-metrics-badges-contract.md
[ADR-0006]: ../adr/adr-0006-release-process-and-version-pinning.md
[PP-001]: ../project-plan.md
[e11c43f]: https://git.tirsystem.com/TirSystem/github-action/commit/e11c43f0a41e7dd9647f7804947d6e464407a597
[a6892c3]: https://git.tirsystem.com/TirSystem/github-action/commit/a6892c372aca9f2e12826a4c3b260290a0656ecb
-296
View File
@@ -1,296 +0,0 @@
# Project Plan: TirSystem Reusable Workflows
## Metadata
| Key | Value |
| --- | --- |
| ID | PP-001 |
| CrossReference | [BC-001], [SA-001], [ADR-0002], [US-001], [MIL-001], [MIL-002], [MIL-003], [MIL-004], [MIL-005], [MIL-006], [MIL-007], [MIL-008], [MIL-009], [MIL-010], [MIL-011] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-14 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Added MIL-010 (code metrics and coverage badges); reviewed (RC-068) | [5002450] |
| 2026-10-14 | Accepted | Jens Tirsvad Nielsen | S01 | Added MIL-011 (fix the defaults of the code metrics workflow); reviewed (RC-076), accepted by the author in chat as stand-in for S01 | [02e3794] |
---
## Purpose
This plan schedules eleven milestones that move the repository from one
workflow with known defects to a documented, versioned collection of shared
workflows. The Business Case sets no deadline, so the dates are the plan's own; they were confirmed on 2026-10-10 by S01, standing in for S05 (ADR-0002).
## Planning Assumptions
- Week 1 starts 2026-10-05; phases are two weeks long; the last decision is 2026-12-26; MIL-007 follows in January 2027 (2027-01-04 to 2027-01-16, confirmed on 2026-10-11 by S01). MIL-008 amends the shared wiki publishing of MIL-006 and runs in parallel with the October and November windows: its work started on 2026-10-13 and its decision date is its own Target Date, 2026-11-15. MIL-009 follows MIL-008 and runs from 2026-11-16 to its proposed Target Date, 2026-11-30, confirmed by S01 in chat on 2026-10-14. MIL-010 (code metrics and coverage badges) follows MIL-007 in January 2027, from 2027-01-18 to its Target Date, 2027-01-30, accepted by the user in chat on 2026-10-14.
- Work on a milestone starts only after its `MIL-*` document is `Accepted`.
- Dates were confirmed on 2026-10-10 by S01, standing in for S05 (ADR-0002).
## Gateway Schedule
| Gateway | Document | Window | Decision date | Owner | Stories | Main deliverable | Milestone |
| --- | --- | --- | --- | --- | --- | --- | --- |
| Stabilise the metadata sync | [MIL-001] | 2026-10-05 to 2026-10-17 | 2026-10-17 | S05 | None yet | Single tested workflow, accurate README | [Milestone MIL-001] |
| Onboarding and operations guide | [MIL-002] | 2026-10-19 to 2026-10-31 | 2026-10-31 | S05 | None yet | Verified onboarding, credential and diagnosis guide | [Milestone MIL-002] |
| Shared quality checks | [MIL-003] | 2026-11-02 to 2026-11-14 | 2026-11-14 | S05 | None yet | Reusable quality-check workflow | [Milestone MIL-003] |
| Versioned release and publishing | [MIL-004] | 2026-11-16 to 2026-11-28 | 2026-11-28 | S05 | None yet | Release process and reusable release workflow | [Milestone MIL-004] |
| Wiki and translations | [MIL-005] | 2026-11-30 to 2026-12-12 | 2026-12-12 | S05 | None yet | Wiki pages in English, Danish and Bahasa Malaysia, kept current by every pull request | [Milestone MIL-005] |
| Shared wiki publishing | [MIL-006] | 2026-12-14 to 2026-12-26 | 2026-12-26 | S05 | None yet | Scoped publish-wiki workflow with opt-in, piloted in one other repository | [Milestone MIL-006] |
| Quality checks for C++ and C# | [MIL-007] | 2027-01-04 to 2027-01-16 | 2027-01-16 | S05 | US-001.09, US-001.10 (to extend) | Reusable quality-check workflows for C++ and C#, released | [Milestone MIL-007] |
| Wiki publishing as a reusable workflow | [MIL-008] | 2026-10-13 to 2026-11-15 | 2026-11-15 | S05 | None yet | Reusable publish-wiki-pages workflow, wiki in docs/wiki, scoped workflow deprecated, released as 1.2.2 | [Milestone MIL-008] |
| Migrate the wiki callers and remove the scoped workflow | [MIL-009] | 2026-11-16 to 2026-11-30 | 2026-11-30 | S05 | None yet | Seven repositories publish through a caller, scoped workflow removed, ADR-0004 superseded, released as 2.0.0 | Not created yet (the sync creates it when MIL-009 is Accepted) |
| Code metrics and coverage badges | [MIL-010] | 2027-01-18 to 2027-01-30 | 2027-01-30 | S05 | None yet (task 1 writes them) | Reusable workflow that counts code files and lines of code, reads coverage and commits SVG badges, released | Not created yet (the sync creates it when MIL-010 is Accepted) |
| Fix the defaults of the code metrics workflow | [MIL-011] | 2026-10-14 to 2026-10-23 | 2026-10-23 | S05 | None (technical tasks) | Patch release 2.1.1: the default `tools-ref` of every reusable workflow names a tag that holds its scripts, a test for it, guides and wiki at `@v2`, the framework Badges page without the workaround | Not created yet (the sync creates it when MIL-011 is Accepted) |
```plantuml
@startgantt
Project starts 2026-10-05
[MIL-001 Stabilise] starts 2026-10-05 and ends 2026-10-17
[MIL-002 Onboarding] starts 2026-10-19 and ends 2026-10-31
[MIL-003 Quality checks] starts 2026-11-02 and ends 2026-11-14
[MIL-004 Release] starts 2026-11-16 and ends 2026-11-28
[MIL-001 Go/No-Go] happens 2026-10-17
[MIL-002 Go/No-Go] happens 2026-10-31
[MIL-003 Go/No-Go] happens 2026-11-14
[MIL-004 Go/No-Go] happens 2026-11-28
[MIL-005 Wiki] starts 2026-11-30 and ends 2026-12-12
[MIL-005 Go/No-Go] happens 2026-12-12
[MIL-006 Shared wiki] starts 2026-12-14 and ends 2026-12-26
[MIL-006 Go/No-Go] happens 2026-12-26
[MIL-007 C++ and C#] starts 2027-01-04 and ends 2027-01-16
[MIL-007 Go/No-Go] happens 2027-01-16
[MIL-008 Reusable wiki workflow] starts 2026-10-13 and ends 2026-11-15
[MIL-008 Go/No-Go] happens 2026-11-15
[MIL-009 Migrate and remove] starts 2026-11-16 and ends 2026-11-30
[MIL-009 Go/No-Go] happens 2026-11-30
[MIL-010 Badges] starts 2027-01-18 and ends 2027-01-30
[MIL-010 Go/No-Go] happens 2027-01-30
[MIL-011 Defaults fix] starts 2026-10-14 and ends 2026-10-23
[MIL-011 Go/No-Go] happens 2026-10-23
@endgantt
```
## Scope Coverage
| Business Case scope item | Gateway |
| --- | --- |
| Validation of workflow files and their documentation | [MIL-001] |
| Documentation for DevOps professionals | [MIL-002] |
| Gitea Actions workflows for software engineers (quality checks) | [MIL-003] |
| Gitea Actions workflows for software engineers (release and publishing) | [MIL-004] |
| Wiki pages in English, Danish and Bahasa Malaysia | [MIL-005] |
| The wiki publisher shared with other repositories through scoped delivery | [MIL-006] |
| Gitea Actions workflows for software engineers (quality checks for C++ and C#) | [MIL-007] |
| The wiki publisher as a workflow that repositories call, from docs/wiki | [MIL-008] |
| Moving every publishing repository to the called workflow and removing the scoped one | [MIL-009] |
| A shared workflow for code metrics and coverage badges | [MIL-010], [MIL-011] |
## Dependencies
```
MIL-001 → MIL-002 → MIL-003 → MIL-004
MIL-002 → MIL-005 → MIL-006
MIL-003 + MIL-004 → MIL-007
MIL-006 → MIL-008 → MIL-009
MIL-003 + MIL-004 → MIL-010 → MIL-011
```
A No-Go moves every later window by the rework time of the failed milestone.
## Plan Risks
| Risk | Impact | Mitigation |
| --- | --- | --- |
| The runner cannot provide the C++ or C# tools (MIL-007) | The workflows need a custom runner image or a longer install | MIL-007 task 2 verifies it first; the ADR of task 3 says what a build-dependent check needs from the caller. |
| Reusable workflow support is missing on the instance | MIL-003 and MIL-004 change shape | Verify first in each milestone (MIL-002 task 2, MIL-003 task 1); fall back to copied templates. |
| Eight repositories still publish through the scoped workflow that MIL-008 deprecates (MIL-008 task 5) | Removing it would stop their wikis | It is deprecated and kept; a follow-up milestone migrates them and removes it in a major release (RC-061). |
| An organisation has no `TOKEN_FOR_GITEA_WIKI` secret, or a repository fails its first run (MIL-009 tasks 3 and 4) | The wiki of that repository stops updating | MIL-009 task 5 reads each wiki back after the first run; the scoped workflow is removed only after every repository passes. |
| The token of a run cannot push to a `badges` branch, or the SVG does not render on the mirror (MIL-010) | The delivery of the badges changes shape | MIL-010 task 3 verifies it first; fall back to a badge file in a path of the default branch or to a run artifact. |
| Security review by S05 is a bottleneck | Milestone decisions slip | Keep milestones small and plan review time before each decision date. |
## Open Issues
- No QC checklist exists for the Project Plan.
- The P1 candidates are written as brief use cases (UC-001 to UC-004) with a use case diagram (UCD-001) and user stories (US-001). The P2 and P3 candidates have no use case document yet.
## Appendix: Use Case Candidates and Prioritisation
This appendix evaluates the candidate use cases against the repository as it
is today. It is analysis, not a use case document; formal use cases follow in
MIL-002 task 1. Priority: P1 do first, P2 next, P3 later.
**Recommended order:** (1) Synchronize repository metadata, because it is
the only implemented capability and has a defect, (2) Configure workflow
credentials, (3) Onboard a repository, (4) Diagnose a failed workflow, then
(5) Run project quality checks and (6) Release a reusable workflow. The first
four make the existing workflow dependable and adoptable; the others add new
workflows and only pay off once adoption works.
Current repository state used for the status column: one workflow
(`sync-github-metadata`), one manual probe script (`tests/test_.ps1`), no CI,
no tests, no release process.
| # | Use case | Actor | Priority | Status today |
| --- | --- | --- | --- | --- |
| 1 | Synchronize repository metadata | DevOps professional (S05) | P1 | Implemented in `.gitea/scoped_workflows/`; script has a syntax error |
| 2 | Configure workflow credentials | DevOps professional (S05, S03) | P1 | Partial: secrets are format-checked only |
| 3 | Onboard a repository to standard workflows | DevOps professional (S05) | P1 | Not documented; scoped workflow support unverified |
| 4 | Diagnose a failed workflow | DevOps professional (S05, S03) | P1 | Partial: errors are messages only, uncategorized |
| 5 | Run project quality checks | Software engineer (S02) | P2 | Planned |
| 6 | Release a reusable workflow | DevOps professional (S05) | P2 | Planned |
| 7 | Manage workflow runners | DevOps professional (S03, S05) | P2 | Partial: only `ubuntu-latest` with `python3` assumed |
| 8 | Consume a workflow update | Software engineer (S02) | P2 | Planned; needs versioning |
| 9 | Review workflow results | Software engineer (S02) | P3 | Gitea provides logs; guidance planned |
| 10 | Create a project workflow | Software engineer (S02) | P3 | Planned; needs MIL-003 |
| 11 | Build and publish an artifact | Software engineer (S02) | P3 | Planned; destination undecided |
| 12 | Publish a release | Software engineer (S02) | P3 | Planned; overlaps with use case 6 and 11 |
### UC candidate 1: Synchronize repository metadata (P1)
- **Actor:** DevOps professional. **Goal:** the GitHub mirror shows the Gitea description and topics.
- **Trigger:** push to `main`, manual dispatch, or daily at 03:17 UTC.
- **Preconditions:** both secrets set; at most one GitHub push mirror configured (none: the run is skipped successfully); runner available.
- **Success:** description and topics on GitHub equal those on Gitea.
- **Main flow:** the workflow validates the secrets, reads description and topics from Gitea, finds the GitHub mirror (if none, ends successfully without syncing), updates the description, replaces the topics.
- **Alternatives and failures:** missing or invalid secret: fail with a message; no GitHub mirror: successful run, nothing synced; several GitHub mirrors: fail; non-list mirror response: behavior undecided (MIL-001 task 1); Gitea or GitHub API error: fail with the HTTP code.
- **Dependencies:** none.
### UC candidate 2: Configure workflow credentials (P1)
- **Actor:** DevOps professional. **Goal:** least-privilege tokens that a workflow accepts.
- **Trigger:** onboarding a repository or rotating a token.
- **Preconditions:** access to Gitea and GitHub settings.
- **Success:** a workflow run passes credential checks with the documented minimum permissions.
- **Main flow:** create the tokens, store `TOKEN_FOR_GITEA` and `PAT_FOR_GITHUB`, run the workflow, read the validation result.
- **Alternatives and failures:** empty value, wrong or expired token (rejected with HTTP 401), missing permission: the check names the category without printing the secret.
- **Dependencies:** use case 1.
### UC candidate 3: Onboard a repository to standard workflows (P1)
- **Actor:** DevOps professional. **Goal:** a repository consumes the shared workflows.
- **Trigger:** a new or existing repository needs standard automation.
- **Preconditions:** Actions enabled; runner available; secrets possible to set.
- **Success:** the first run in the repository passes using only the guide.
- **Main flow:** choose scoped or copied delivery, set secrets, configure the push mirror, trigger a run.
- **Alternatives and failures:** scoped workflows unsupported: use a copied template; no runner: see use case 7.
- **Dependencies:** use cases 1 and 2; verification of scoped workflow support.
### UC candidate 4: Diagnose a failed workflow (P1)
- **Actor:** DevOps professional. **Goal:** find the cause of a failed run.
- **Trigger:** a failed or missing run.
- **Preconditions:** access to the run log.
- **Success:** the cause is placed in one category: configuration, credentials, permissions, API response or runner.
- **Main flow:** open the log, read the categorized message, look up the category in the guide, apply the fix, re-run.
- **Alternatives and failures:** no run starts: check runner and trigger; message uncategorized: raise as a defect.
- **Dependencies:** use cases 1 and 2.
### UC candidate 5: Run project quality checks (P2)
- **Actor:** software engineer. **Goal:** tests, lint, format and type checks run on every change.
- **Trigger:** pull request or push.
- **Preconditions:** shared workflow available; project onboarded.
- **Success:** a status check reports pass or fail.
- **Main flow:** the shared workflow detects inputs, runs the checks, reports the result.
- **Alternatives and failures:** a check fails: the log names tool, file and message; unsupported language: workflow fails with a clear message.
- **Dependencies:** use case 3; reusable workflow support.
### UC candidate 6: Release a reusable workflow (P2)
- **Actor:** DevOps professional. **Goal:** a validated, versioned workflow update that consumers can pin.
- **Trigger:** a workflow change is ready.
- **Preconditions:** validation checks exist; version scheme defined.
- **Success:** a tag and changelog entry exist and pinned consumers are unaffected.
- **Main flow:** run validation, update the changelog, tag, announce.
- **Alternatives and failures:** validation fails: no tag; breaking change: new major version.
- **Dependencies:** use case 1 (validation from MIL-001).
### UC candidate 7: Manage workflow runners (P2)
- **Actor:** DevOps professional (runner operator). **Goal:** workflows run on a supported runner.
- **Trigger:** a job waits, fails to start, or a new label is needed.
- **Preconditions:** access to the runner list.
- **Success:** a runner with the required label and tools is online.
- **Main flow:** compare the workflow's `runs-on` label with online runners, check prerequisites such as `python3`, fix or register a runner.
- **Alternatives and failures:** runner offline: restart or replace; label missing: add the label or change the workflow.
- **Dependencies:** use case 3.
### UC candidate 8: Consume a workflow update (P2)
- **Actor:** software engineer. **Goal:** adopt a new workflow version safely.
- **Trigger:** a new release or a changelog notice.
- **Preconditions:** releases are versioned and have a changelog.
- **Success:** the project uses the new version and its pipeline still passes.
- **Main flow:** read the changelog, change the pinned version in one branch, run, merge.
- **Alternatives and failures:** breaking change: follow upgrade notes; failure: roll back to the previous pin.
- **Dependencies:** use case 6.
### UC candidate 9: Review workflow results (P3)
- **Actor:** software engineer. **Goal:** understand a failed check and make it pass.
- **Trigger:** a failed status check on a pull request.
- **Preconditions:** a run exists.
- **Success:** the next run passes.
- **Main flow:** open the check, read the failing step, fix locally, push.
- **Alternatives and failures:** the cause is infrastructure, not code: hand over to use case 4.
- **Dependencies:** use case 5.
### UC candidate 10: Create a project workflow (P3)
- **Actor:** software engineer. **Goal:** compose shared workflows into a project pipeline.
- **Trigger:** a project needs build and delivery steps.
- **Preconditions:** shared workflows are documented with inputs.
- **Success:** the project workflow runs the chosen shared workflows in order.
- **Main flow:** pick workflows, set inputs, set triggers and permissions, test.
- **Alternatives and failures:** missing input: the workflow fails with the input name.
- **Dependencies:** use cases 5 and 8.
### UC candidate 11: Build and publish an artifact (P3)
- **Actor:** software engineer. **Goal:** a package or binary is built and published.
- **Trigger:** a tag or a manual run.
- **Preconditions:** destination decided; token with write access.
- **Success:** the artifact is available at the destination with a version.
- **Main flow:** build, test, package, publish, report the location.
- **Alternatives and failures:** publish denied: permission failure; version exists: fail without overwrite.
- **Dependencies:** use cases 5 and 6; destination decision (MIL-004 task 4).
### UC candidate 12: Publish a release (P3)
- **Actor:** software engineer. **Goal:** a release with validated version and notes.
- **Trigger:** a version tag.
- **Preconditions:** changelog entry exists.
- **Success:** a release page with notes from the changelog.
- **Main flow:** validate the version, build notes, create the release.
- **Alternatives and failures:** invalid version or missing notes: fail. This overlaps with use cases 6 and 11 and should be merged with one of them when the use cases are written.
- **Dependencies:** use cases 6 and 11.
---
[BC-001]: ./business-case.md
[SA-001]: ./stakeholder-analysis.md
[US-001]: ./user-stories.md
[ADR-0002]: ./adr/adr-0002-s01-approves-as-stand-in.md
[MIL-001]: ./milestones/mil-001-stabilise-metadata-sync.md
[MIL-002]: ./milestones/mil-002-onboarding-and-operations.md
[MIL-003]: ./milestones/mil-003-quality-checks.md
[MIL-004]: ./milestones/mil-004-versioned-release.md
[MIL-005]: ./milestones/mil-005-wiki-and-translations.md
[MIL-006]: ./milestones/mil-006-shared-wiki-publishing.md
[MIL-007]: ./milestones/mil-007-cpp-csharp-quality-checks.md
[MIL-008]: ./milestones/mil-008-wiki-reusable-workflow.md
[MIL-009]: ./milestones/mil-009-migrate-wiki-callers-and-remove-scoped-workflow.md
[MIL-010]: ./milestones/mil-010-code-metrics-badges.md
[MIL-011]: ./milestones/mil-011-code-metrics-default-tools-ref.md
[Milestone MIL-001]: https://git.tirsystem.com/TirSystem/github-action/milestone/18
[Milestone MIL-002]: https://git.tirsystem.com/TirSystem/github-action/milestone/19
[Milestone MIL-003]: https://git.tirsystem.com/TirSystem/github-action/milestone/20
[Milestone MIL-004]: https://git.tirsystem.com/TirSystem/github-action/milestone/21
[Milestone MIL-005]: https://git.tirsystem.com/TirSystem/github-action/milestone/93
[Milestone MIL-006]: https://git.tirsystem.com/TirSystem/github-action/milestone/94
[Milestone MIL-007]: https://git.tirsystem.com/TirSystem/github-action/milestone/95
[Milestone MIL-008]: https://git.tirsystem.com/TirSystem/github-action/milestone/152
[b74ee0e]: https://git.tirsystem.com/TirSystem/github-action/commit/b74ee0e5cfd04f25ba5f2c1addc80699147c479a
[2f267df]: https://git.tirsystem.com/TirSystem/github-action/commit/2f267df2a270087cb7dc482af4ce4f4341e97b03
[5002450]: https://git.tirsystem.com/TirSystem/github-action/commit/50024505fe788b1c5e3021c0d1fc3d079590070e
[02e3794]: https://git.tirsystem.com/TirSystem/github-action/commit/02e3794d7b05799af2544ca303c99271da788e82
-50
View File
@@ -1,50 +0,0 @@
# Review Record: BC-001 Business Case
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-001 |
| CrossReference | [BC-001], [QC-BC-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Deprecated | Jens Tirsvad Nielsen | S05 | S05 review approved (reported by S01)<br>Independence action item closed | [ba1c6be] |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S05 | S01 stood in for S05<br>Independence of the review is still open | [0799b43] |
---
## Artifact Under Review
- Instance reviewed: [BC-001]
- Checklist used: [QC-BC-001] (`QC-BC-001`)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | ROI/Cost-Benefit analysis is quantitative, or where qualitative, is explicitly justified | Pass | The Cost–Benefit Assessment states costs as qualitative with no external cost and lists benefits; the qualitative form is labelled. |
| 2 | Risks are identified with documented impact and mitigation | Pass | Risks table has Risk, Impact and Mitigation for every row. |
| 3 | Success criteria are measurable, stating explicit targets rather than vague aspirations | Pass | Four criteria, each with a target and a measure. |
| 4 | Scope explicitly separates In Scope vs Out of Scope | Pass | Scope has separate In Scope and Out of Scope lists. |
| 5 | Stakeholders are cross-referenced to Stakeholder Analysis IDs rather than re-described inline | Pass | Stakeholders table uses S01 to S05; the ID, not a role description, identifies each. |
| 6 | Methodology and quality-standard foundation are stated explicitly (e.g. ISO/IEC 25010, Larman) | Pass | Methodological and Standards Foundation cites the framework, Larman and ISO/IEC 25010:2023. |
| 7 | Assumptions and constraints are explicit and clearly distinguished from one another | Pass | Separate Assumptions and Constraints sections. The 2026-10-10 change edits the mirror assumption only. |
| 8 | Document supports executive decision-making with a clear, unambiguous recommendation | Pass | Recommendation section: Proceed, with the reason. |
## Overall Verdict
Go — all eight criteria pass. S01 gave the Go in chat on 2026-10-10 for the revision that changes the mirror assumption to at most one GitHub push mirror. The author and the approving reviewer are the same person (S01); S01 stood in for S05 on 2026-10-10; this is not an independent review because the author and S01 are the same person.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Independent review of this record and of BC-001 by a person other than the author (the rule that the reviewer must not be the author) | S05 | 2026-10-17 |
---
[BC-001]: ../../business-case.md
[QC-BC-001]: ../../../framework/qc/qc-business-case.md
[ba1c6be]: https://git.tirsystem.com/TirSystem/github-action/commit/ba1c6bea7491884899d55a3f86364c6a7811649a
[0799b43]: https://git.tirsystem.com/TirSystem/github-action/commit/0799b43888a1fef02fe135818a4a38eff3452a09
-50
View File
@@ -1,50 +0,0 @@
# Review Record: PP-001 Project Plan
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-002 |
| CrossReference | [PP-001], [BC-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Deprecated | Jens Tirsvad Nielsen | S05 | Initial version | [c017c06] |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S05 | S01 stood in for S05<br>Independence of the review is still open | [0799b43] |
---
## Artifact Under Review
- Instance reviewed: [PP-001]
- Checklist used: none: the Project Plan has no QC checklist (catalog and `PP.md` reference). Validated against the Business Case [BC-001] constraints and the Go / No-Go criteria of each listed milestone, as `PP.md` prescribes.
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Every milestone in the plan has a `MIL-*` document and the plan's dates equal that document's target date | Pass | MIL-001 to MIL-004 exist; decision dates 2026-10-17, 10-31, 11-14, 11-28 match the Target Date of each milestone. |
| 2 | Every Business Case scope item is covered by a gateway | Pass | Scope Coverage maps validation, documentation, quality checks and release to MIL-001 to MIL-004. |
| 3 | The schedule respects the Business Case constraints | Pass | The Business Case sets no deadline; the plan states its dates are proposals. The constraint that nothing is written before a milestone is accepted is repeated in Planning Assumptions. |
| 4 | Dependencies between milestones are stated | Pass | Dependencies section gives MIL-001 to MIL-002 to MIL-003 to MIL-004. |
| 5 | Every gateway has an owner who is a stakeholder ID | Pass | All four gateways are owned by S05. |
| 6 | Plan content is consistent with the revised mirror behaviour | Pass | UC candidate 1 now describes no GitHub mirror as a successful skip and several mirrors as a failure. |
| 7 | Open Issues are current | Fail | Open Issues still lists the decisions for MIL-001 task 1 and task 3 as open; both were decided and recorded in MIL-001. |
## Overall Verdict
Go — S01 gave the Go in chat on 2026-10-10 for the revision to UC candidate 1. One stale entry in Open Issues does not affect the schedule or the changed use case; it is recorded as an action item. The author and the approving reviewer are the same person (S01); the S05 stand-in review is recorded in RC-001 and applies here too; independence is still open.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Remove the answered MIL-001 task 1 and task 3 items from Open Issues in PP-001, with a Version History row | S01 | 2026-10-17 |
| Confirm the proposed dates and the start week (already listed in Open Issues) | S01 | 2026-10-17 |
---
[PP-001]: ../../project-plan.md
[BC-001]: ../../business-case.md
[c017c06]: https://git.tirsystem.com/TirSystem/github-action/commit/c017c06789424305b31f19e48238ad14231e8113
[0799b43]: https://git.tirsystem.com/TirSystem/github-action/commit/0799b43888a1fef02fe135818a4a38eff3452a09
-48
View File
@@ -1,48 +0,0 @@
# Review Record: MIL-001 Stabilise the metadata sync
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-003 |
| CrossReference | [MIL-001], [QC-MIL-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Deprecated | Jens Tirsvad Nielsen | S05 | Initial version | [c017c06] |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S05 | S01 stood in for S05<br>Independence of the review is still open | [0799b43] |
---
## Artifact Under Review
- Instance reviewed: [MIL-001]
- Checklist used: [QC-MIL-001] (`QC-MIL-001`)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | A concrete deliverable is defined for every gate | Pass | Deliverable section: one canonical workflow, passing validation and tests, an accurate README and a manual run. |
| 2 | Explicit Go/No-Go criteria are stated for each gate | Pass | Five criteria, each with an objectively checkable Go and No-Go column. |
| 3 | Dependencies on other milestones are explicitly mapped | Pass | Dependencies: none, first milestone. |
| 4 | Each milestone is traceable to a Business Case objective or KPI | Pass | Traceability maps MIL-001 to O1 and O2 of BC-001. |
| 5 | Milestone owner and approving reviewer are identified | Pass | Owner S05 and approving reviewer S01. |
| 6 | Milestone has a defined target date consistent with project constraints | Pass | Target date 2026-10-17, marked proposed; the Business Case sets no deadline, so there is nothing to contradict. |
## Overall Verdict
Go — all six criteria pass. S01 gave the Go in chat on 2026-10-10 for the amendment of the task 1 decision (zero GitHub mirrors is a successful skip) and the matching task 5 test scope. Go / No-Go criterion 5 (manual run on Gitea) is still open as task 7 (issue 7) and is not changed by this amendment. The author and the approving reviewer are the same person (S01); the S05 stand-in review is recorded in RC-001 and applies here too; independence is still open.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Run the manual `workflow_dispatch` check on Gitea for the amended behaviour: a repository with a GitHub mirror and one without (task 7) | S05 | 2026-10-17 |
---
[MIL-001]: ../../milestones/mil-001-stabilise-metadata-sync.md
[QC-MIL-001]: ../../../framework/qc/qc-milestones-gateways.md
[c017c06]: https://git.tirsystem.com/TirSystem/github-action/commit/c017c06789424305b31f19e48238ad14231e8113
[0799b43]: https://git.tirsystem.com/TirSystem/github-action/commit/0799b43888a1fef02fe135818a4a38eff3452a09
@@ -1,51 +0,0 @@
# Review Record: SA-001 Stakeholder Analysis
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-004 |
| CrossReference | [SA-001], [QC-SA-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Deprecated | Jens Tirsvad Nielsen | S05 | Initial version | [aa3f088] |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S05 | S01 stood in for S05<br>Independence of the review is still open | [0799b43] |
---
## Artifact Under Review
- Instance reviewed: [SA-001]
- Checklist used: [QC-SA-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Power/Interest grid is filled for every stakeholder, with no gaps or unclassified entries | Pass | S01 to S05 each have Power, Interest and Quadrant. |
| 2 | Each stakeholder is assigned a unique, stable ID reusable for RACI assignments in other artifacts | Pass | IDs S01 to S05 are used by BC-001, PP-001 and the milestones. |
| 3 | Roles and organizational context are defined with explicit Power and Interest levels, not just narrative description | Pass | Role, organization and HIGH/MEDIUM/LOW levels per stakeholder, with a rationale section. |
| 4 | Communication needs (channel, frequency, deliverable type) are mapped to project phases or milestones | Pass | Communication Requirements table maps each stakeholder to a milestone. |
| 5 | Conflicting stakeholder interests are identified with documented mitigation or resolution strategies | Pass | Four conflicts, each with stakeholders and a mitigation. |
| 6 | Stakeholder concerns are explicitly traced to Business Case objectives | Pass | Business Goal Alignment maps each concern to O1 to O4 of BC-001. |
| 7 | Primary concerns are expressed in both business language and a recognized quality-attribute mapping (e.g. FURPS+) | Pass | Primary Concern column plus a FURPS+ mapping table. |
| 8 | Document is understandable and navigable by non-technical stakeholders reviewing their own entry | Pass | Plain-language summary table and one section per topic. |
## Overall Verdict
Go — all eight criteria pass, with two follow-ups that do not affect the criteria. Retrospective review prepared 2026-10-10 at the request of S01; the instance has been `Accepted` since 2026-10-03 and this record confirms it against the checklist. The author and the approving reviewer are the same person (S01); the S05 stand-in review is recorded in RC-001 and applies here too; independence is still open.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Update the Sign-Off section, which still says 'Pending review by S01 and S05', with a Version History row | S01 | 2026-10-17 |
| Identify the holders of the S03 role (listed as 'holders to be confirmed') | S01 | 2026-10-17 |
---
[SA-001]: ../../stakeholder-analysis.md
[QC-SA-001]: ../../../framework/qc/qc-stakeholder-analysis.md
[aa3f088]: https://git.tirsystem.com/TirSystem/github-action/commit/aa3f08876d55fa5f008e93f65176a496601c00ca
[0799b43]: https://git.tirsystem.com/TirSystem/github-action/commit/0799b43888a1fef02fe135818a4a38eff3452a09
-48
View File
@@ -1,48 +0,0 @@
# Review Record: MIL-002
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-005 |
| CrossReference | [MIL-002], [QC-MIL-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Deprecated | Jens Tirsvad Nielsen | S05 | Initial version | [aa3f088] |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S05 | S01 stood in for S05<br>Independence of the review is still open | [0799b43] |
---
## Artifact Under Review
- Instance reviewed: [MIL-002]
- Checklist used: [QC-MIL-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | A concrete deliverable is defined for every gate | Pass | Deliverable: verified onboarding and operations guide, credential validation step and categorized failure messages. |
| 2 | Explicit Go/No-Go criteria are stated for each gate | Pass | Five criteria, each with an objectively checkable Go and No-Go column. |
| 3 | Dependencies on other milestones are explicitly mapped | Pass | Dependencies: depends on MIL-001, with the reason stated. |
| 4 | Each milestone is traceable to a Business Case objective or KPI | Pass | Traceability maps MIL-002 to O2 and O3 of BC-001. |
| 5 | Milestone owner and approving reviewer are identified | Pass | Owner S05 and approving reviewer S01. |
| 6 | Milestone has a defined target date consistent with project constraints | Pass | Target date 2026-10-31, marked proposed; the Business Case sets no deadline, so nothing contradicts it. |
## Overall Verdict
Go — all six criteria pass. Retrospective review prepared 2026-10-10 at the request of S01; the instance has been `Accepted` since 2026-10-03 and this record confirms it against the checklist. The author and the approving reviewer are the same person (S01); the S05 stand-in review is recorded in RC-001 and applies here too; independence is still open.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Confirm the proposed target date with S01 and S05 (the date is still marked proposed) | S05 | 2026-10-17 |
---
[MIL-002]: ../../milestones/mil-002-onboarding-and-operations.md
[QC-MIL-001]: ../../../framework/qc/qc-milestones-gateways.md
[aa3f088]: https://git.tirsystem.com/TirSystem/github-action/commit/aa3f08876d55fa5f008e93f65176a496601c00ca
[0799b43]: https://git.tirsystem.com/TirSystem/github-action/commit/0799b43888a1fef02fe135818a4a38eff3452a09
-48
View File
@@ -1,48 +0,0 @@
# Review Record: MIL-003
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-006 |
| CrossReference | [MIL-003], [QC-MIL-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Deprecated | Jens Tirsvad Nielsen | S05 | Initial version | [aa3f088] |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S05 | S01 stood in for S05<br>Independence of the review is still open | [0799b43] |
---
## Artifact Under Review
- Instance reviewed: [MIL-003]
- Checklist used: [QC-MIL-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | A concrete deliverable is defined for every gate | Pass | Deliverable: a reusable quality-check workflow used by one other repository, and a results guide. |
| 2 | Explicit Go/No-Go criteria are stated for each gate | Pass | Four criteria, each with an objectively checkable Go and No-Go column. |
| 3 | Dependencies on other milestones are explicitly mapped | Pass | Dependencies: depends on MIL-002, with the reason stated. |
| 4 | Each milestone is traceable to a Business Case objective or KPI | Pass | Traceability maps MIL-003 to O4 of BC-001. |
| 5 | Milestone owner and approving reviewer are identified | Pass | Owner S05 and approving reviewer S01. |
| 6 | Milestone has a defined target date consistent with project constraints | Pass | Target date 2026-11-14, marked proposed; the Business Case sets no deadline, so nothing contradicts it. |
## Overall Verdict
Go — all six criteria pass. Retrospective review prepared 2026-10-10 at the request of S01; the instance has been `Accepted` since 2026-10-03 and this record confirms it against the checklist. The author and the approving reviewer are the same person (S01); the S05 stand-in review is recorded in RC-001 and applies here too; independence is still open.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Confirm the proposed target date with S01 and S05 (the date is still marked proposed) | S05 | 2026-10-17 |
---
[MIL-003]: ../../milestones/mil-003-quality-checks.md
[QC-MIL-001]: ../../../framework/qc/qc-milestones-gateways.md
[aa3f088]: https://git.tirsystem.com/TirSystem/github-action/commit/aa3f08876d55fa5f008e93f65176a496601c00ca
[0799b43]: https://git.tirsystem.com/TirSystem/github-action/commit/0799b43888a1fef02fe135818a4a38eff3452a09
-48
View File
@@ -1,48 +0,0 @@
# Review Record: MIL-004
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-007 |
| CrossReference | [MIL-004], [QC-MIL-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Deprecated | Jens Tirsvad Nielsen | S05 | Initial version | [aa3f088] |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S05 | S01 stood in for S05<br>Independence of the review is still open | [0799b43] |
---
## Artifact Under Review
- Instance reviewed: [MIL-004]
- Checklist used: [QC-MIL-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | A concrete deliverable is defined for every gate | Pass | Deliverable: documented release process, consumer upgrade guide and a reusable release workflow. |
| 2 | Explicit Go/No-Go criteria are stated for each gate | Pass | Four criteria, each with an objectively checkable Go and No-Go column. |
| 3 | Dependencies on other milestones are explicitly mapped | Pass | Dependencies: depends on MIL-003, with the reason stated. |
| 4 | Each milestone is traceable to a Business Case objective or KPI | Pass | Traceability maps MIL-004 to O4 of BC-001. |
| 5 | Milestone owner and approving reviewer are identified | Pass | Owner S05 and approving reviewer S01. |
| 6 | Milestone has a defined target date consistent with project constraints | Pass | Target date 2026-11-28, marked proposed; the Business Case sets no deadline, so nothing contradicts it. |
## Overall Verdict
Go — all six criteria pass. Retrospective review prepared 2026-10-10 at the request of S01; the instance has been `Accepted` since 2026-10-03 and this record confirms it against the checklist. The author and the approving reviewer are the same person (S01); the S05 stand-in review is recorded in RC-001 and applies here too; independence is still open.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Confirm the proposed target date with S01 and S05 (the date is still marked proposed) | S05 | 2026-10-17 |
---
[MIL-004]: ../../milestones/mil-004-versioned-release.md
[QC-MIL-001]: ../../../framework/qc/qc-milestones-gateways.md
[aa3f088]: https://git.tirsystem.com/TirSystem/github-action/commit/aa3f08876d55fa5f008e93f65176a496601c00ca
[0799b43]: https://git.tirsystem.com/TirSystem/github-action/commit/0799b43888a1fef02fe135818a4a38eff3452a09
@@ -1,48 +0,0 @@
# Review Record: BC-001 Business Case (wiki scope)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-008 |
| CrossReference | [BC-001], [QC-BC-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [ae4e257] |
---
## Artifact Under Review
- Instance reviewed: [BC-001]
- Checklist used: [QC-BC-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | ROI/Cost-Benefit analysis is quantitative, or where qualitative, is explicitly justified | Pass | Unchanged; the Cost-Benefit Assessment labels its qualitative form. |
| 2 | Risks are identified with documented impact and mitigation | Pass | Unchanged; every risk has an impact and a mitigation. |
| 3 | Success criteria are measurable, stating explicit targets rather than vague aspirations | Pass | Unchanged; four criteria with targets and measures. None measures the wiki; MIL-005 traces it to O3. |
| 4 | Scope explicitly separates In Scope vs Out of Scope | Pass | The wiki in three languages is a new In Scope bullet; Out of Scope is unchanged and does not contradict it. |
| 5 | Stakeholders are cross-referenced to Stakeholder Analysis IDs rather than re-described inline | Pass | Unchanged. |
| 6 | Methodology and quality-standard foundation are stated explicitly (e.g. ISO/IEC 25010, Larman) | Pass | Unchanged. |
| 7 | Assumptions and constraints are explicit and clearly distinguished from one another | Pass | Unchanged. |
| 8 | Document supports executive decision-making with a clear, unambiguous recommendation | Pass | Unchanged: Proceed. |
## Overall Verdict
Go - all eight criteria pass for the revision that adds the wiki (English, Danish, Bahasa Malaysia) to the in-scope list. S01 gave the Go in chat on 2026-10-10. The author and S01 are the same person, so the independent S05 review recorded in RC-001 is still open.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | - | - |
---
[BC-001]: ../../business-case.md
[QC-BC-001]: ../../../framework/qc/qc-business-case.md
[ae4e257]: https://git.tirsystem.com/TirSystem/github-action/commit/ae4e257236095e76132980fad1e9a661b1d082c7
@@ -1,47 +0,0 @@
# Review Record: PP-001 Project Plan (MIL-005)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-009 |
| CrossReference | [PP-001], [BC-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [ae4e257] |
---
## Artifact Under Review
- Instance reviewed: [PP-001]
- Checklist used: none: the Project Plan has no QC checklist. Validated against the Business Case [BC-001] and the Go / No-Go criteria of each listed milestone, as `PP.md` prescribes.
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Every milestone in the plan has a `MIL-*` document and the plan's dates equal that document's target date | Pass | MIL-001 to MIL-005 exist; the MIL-005 decision date 2026-12-12 equals its Target Date. |
| 2 | Every Business Case scope item is covered by a gateway | Pass | The new scope item (wiki in three languages) maps to MIL-005 in Scope Coverage. |
| 3 | The schedule respects the Business Case constraints | Pass | The Business Case sets no deadline. MIL-005 is scheduled after MIL-004 although it only depends on MIL-002. |
| 4 | Dependencies between milestones are stated | Pass | The Dependencies diagram adds MIL-002 to MIL-005. |
| 5 | Every gateway has an owner who is a stakeholder ID | Pass | MIL-005 is owned by S05. |
| 6 | Plan content is internally consistent | Pass | Finding fixed during this review: Planning Assumptions still said the last decision is 2026-11-28; it now says 2026-12-12. The purpose text says five milestones. |
| 7 | Open Issues are current | Fail | Open Issues still lists the answered MIL-001 task 1 and task 3 decisions (carried over from RC-002). |
## Overall Verdict
Go - S01 gave the Go in chat on 2026-10-10 for the revision that adds MIL-005. The open-issues finding is carried over from RC-002 and does not affect MIL-005. The author and S01 are the same person, so the independent S05 review recorded in RC-001 is still open.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Remove the answered MIL-001 task 1 and task 3 items from Open Issues in PP-001, with a Version History row | S01 | 2026-10-17 |
---
[PP-001]: ../../project-plan.md
[BC-001]: ../../business-case.md
[ae4e257]: https://git.tirsystem.com/TirSystem/github-action/commit/ae4e257236095e76132980fad1e9a661b1d082c7
-47
View File
@@ -1,47 +0,0 @@
# Review Record: MIL-005 Wiki and translations
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-010 |
| CrossReference | [MIL-005], [QC-MIL-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [ae4e257] |
---
## Artifact Under Review
- Instance reviewed: [MIL-005]
- Checklist used: [QC-MIL-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | A concrete deliverable is defined for every gate | Pass | Fifteen wiki pages, a generation script and the `AGENTS.md` rule. |
| 2 | Explicit Go/No-Go criteria are stated for each gate | Pass | Five criteria, each with a checkable Go and No-Go column. |
| 3 | Dependencies on other milestones are explicitly mapped | Pass | Depends on MIL-002, with the reason. |
| 4 | Each milestone is traceable to a Business Case objective or KPI | Pass | Traceability maps MIL-005 to O3 of BC-001. |
| 5 | Milestone owner and approving reviewer are identified | Pass | Owner S05, approving reviewer S01. |
| 6 | Milestone has a defined target date consistent with project constraints | Pass | 2026-12-12, marked proposed; the Business Case sets no deadline. |
## Overall Verdict
Go - all six criteria pass. S01 gave the Go in chat on 2026-10-10. Accepting the milestone is what unlocks its tasks under the plan-first gate; the issues are still to be created with `sync-project.sh --apply`. The author and S01 are the same person, so the independent S05 review recorded in RC-001 is still open.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Decide how the agent publishes to the wiki repository (task 2): push with a token or prepare changes for review | S01 | 2026-10-17 |
| Confirm the proposed target date with S01 and S05 | S05 | 2026-10-17 |
---
[MIL-005]: ../../milestones/mil-005-wiki-and-translations.md
[QC-MIL-001]: ../../../framework/qc/qc-milestones-gateways.md
[ae4e257]: https://git.tirsystem.com/TirSystem/github-action/commit/ae4e257236095e76132980fad1e9a661b1d082c7
@@ -1,47 +0,0 @@
# Review Record: MIL-005 Wiki and translations (publishing decision)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-011 |
| CrossReference | [MIL-005], [QC-MIL-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [20361e8] |
---
## Artifact Under Review
- Instance reviewed: [MIL-005]
- Checklist used: [QC-MIL-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | A concrete deliverable is defined for every gate | Pass | Fifteen wiki pages in `wiki/`, the generation script, the publishing workflow and the `AGENTS.md` rule. |
| 2 | Explicit Go/No-Go criteria are stated for each gate | Pass | Six criteria, each checkable. The new criterion 6 is checked by the author of the last wiki commit. |
| 3 | Dependencies on other milestones are explicitly mapped | Pass | Depends on MIL-002; task 8 adds no new milestone dependency. |
| 4 | Each milestone is traceable to a Business Case objective or KPI | Pass | Traceability maps MIL-005 to O3 of BC-001; the wiki is in the BC-001 scope list. |
| 5 | Milestone owner and approving reviewer are identified | Pass | Owner S05, approving reviewer S01. |
| 6 | Milestone has a defined target date consistent with project constraints | Pass | 2026-12-12, marked proposed; the Business Case sets no deadline. |
## Overall Verdict
Go - all six criteria pass for the amendment that records how the wiki is published (source in `wiki/`, workflow on merge, no direct push) and adds task 8. S01 gave the Go in chat on 2026-10-10. The author and S01 are the same person, so the independent S05 review recorded in RC-001 is still open. This review closes the RC-010 action item to decide how the agent publishes.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Approve the scope of the wiki publish secret (write access to the wiki repository only) and store it (task 2) | S05 | 2026-10-17 |
| Store the approved secret on the Gitea repository (task 2) | S03 | 2026-10-24 |
---
[MIL-005]: ../../milestones/mil-005-wiki-and-translations.md
[QC-MIL-001]: ../../../framework/qc/qc-milestones-gateways.md
[20361e8]: https://git.tirsystem.com/TirSystem/github-action/commit/20361e881ebd0dc52e1d1c358ceb792c41b76c60
-51
View File
@@ -1,51 +0,0 @@
# Review Record: ADR-0001 Wiki structure, page names and languages
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-012 |
| CrossReference | [ADR-0001], [QC-ADR-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [d0618d9] |
---
## Artifact Under Review
- Instance reviewed: [ADR-0001]
- Checklist used: [QC-ADR-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The ID (`ADR-NNNN`, 4-digit) matches the filename number and is unique and sequential | Pass | ADR-0001 in `adr-0001-wiki-structure-and-languages.md`; the first ADR. |
| 2 | Context states the problem, the forces (cost, risk, constraints) and the options evaluated | Pass | Names the three things to fix, the forces and the options. |
| 3 | At least two options were considered, or the absence of alternatives is justified | Pass | Three naming options and two source-of-truth options. |
| 4 | Decision is stated in one or two unhedged sentences and matches one of the evaluated options | Pass | Finding fixed during this review: the decision ran to several sentences. It is now two sentences (naming option 1, source option 2), and the details are listed under it as rules. |
| 5 | Consequences list both Positive and Negative outcomes | Pass | Three positive and three negative. |
| 6 | Quality-attribute impacts (performance, security, portability, etc.) are named where the decision affects them | Pass | Maintainability is the affected attribute and is named: stale translations are detectable but not self-updating. Performance and security are not affected. |
| 7 | Affected Artifacts are listed as links, and each is also in CrossReference | Pass | MIL-005 and BC-001 are linked and cited. |
| 8 | Status changes are recorded as new Version History rows with a Change summary and Commit link; retained rows are never rewritten | Pass | The earlier row is kept and only its status changed. |
| 9 | A superseded or deprecated ADR names its successor, and the successor links back | N-A | Nothing is superseded. |
| 10 | Written in business or technical language of the domain, with no unexplained abbreviations | Pass | IT Professional English; `da`, `ms` and `sha256` are explained in the text. |
| 11 | Status is one of `Proposed`, `Accepted`, `Rejected`, `Deprecated` or `Superseded by ADR-NNNN`, and every Version History row uses only these | Pass | Rows use Deprecated and Accepted only. |
## Overall Verdict
Go - all applicable criteria pass; the one finding (criterion 4) was fixed during the review. S01 gave the Go in chat on 2026-10-10. The author and S01 are the same person, so the independent S05 review recorded in RC-001 is still open.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Publish and open a page with a dot in its name (`Home.da`) on the wiki; if Gitea rejects it, supersede this ADR with the `Home_da` form (MIL-005 task 7) | S05 | 2026-12-12 |
---
[ADR-0001]: ../../adr/adr-0001-wiki-structure-and-languages.md
[QC-ADR-001]: ../../../framework/qc/qc-adr.md
[d0618d9]: https://git.tirsystem.com/TirSystem/github-action/commit/d0618d929f2ec274d30b10bb1be306e1f04c31ee
-51
View File
@@ -1,51 +0,0 @@
# Review Record: ADR-0002 S01 approves as stand-in
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-013 |
| CrossReference | [ADR-0002], [QC-ADR-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [bc3bd07] |
---
## Artifact Under Review
- Instance reviewed: [ADR-0002]
- Checklist used: [QC-ADR-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The ID (`ADR-NNNN`, 4-digit) matches the filename number and is unique and sequential | Pass | ADR-0002 in `adr-0002-s01-approves-as-stand-in.md`. |
| 2 | Context states the problem, the forces (cost, risk, constraints) and the options evaluated | Pass | Names the roles, the conflicting text in SA-001 and the Business Case, and the framework rule. |
| 3 | At least two options were considered, or the absence of alternatives is justified | Pass | Three options. |
| 4 | Decision is stated in one or two unhedged sentences and matches one of the evaluated options | Pass | Two sentences; matches option 2. |
| 5 | Consequences list both Positive and Negative outcomes | Pass | Two positive, three negative. |
| 6 | Quality-attribute impacts (performance, security, portability, etc.) are named where the decision affects them | Pass | Security and accountability impacts are named; the missing second reader is the first negative. |
| 7 | Affected Artifacts are listed as links, and each is also in CrossReference | Pass | SA-001 and RC-001 are linked and cited. |
| 8 | Status changes are recorded as new Version History rows with a Change summary and Commit link; retained rows are never rewritten | Pass | Initial row only. |
| 9 | A superseded or deprecated ADR names its successor, and the successor links back | N-A | Nothing is superseded. |
| 10 | Written in business or technical language of the domain, with no unexplained abbreviations | Pass | IT Professional English; roles are given by ID. |
| 11 | Status is one of `Proposed`, `Accepted`, `Rejected`, `Deprecated` or `Superseded by ADR-NNNN`, and every Version History row uses only these | Pass | Accepted only. |
## Overall Verdict
Go - all applicable criteria pass. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader. This record is itself approved under the rule it records, which is the weakness the ADR lists.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Tell S05 (Michael Kragh) about this ADR, and amend SA-001 and the Business Case mitigation, or have S05 accept the stand-in rule | S01 | 2026-10-17 |
---
[ADR-0002]: ../../adr/adr-0002-s01-approves-as-stand-in.md
[QC-ADR-001]: ../../../framework/qc/qc-adr.md
[bc3bd07]: https://git.tirsystem.com/TirSystem/github-action/commit/bc3bd07b29a0a3dcf45045b9baac64c36144c6d1
-51
View File
@@ -1,51 +0,0 @@
# Review Record: ADR-0003 Wiki publish token
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-014 |
| CrossReference | [ADR-0003], [QC-ADR-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [bc3bd07] |
---
## Artifact Under Review
- Instance reviewed: [ADR-0003]
- Checklist used: [QC-ADR-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The ID (`ADR-NNNN`, 4-digit) matches the filename number and is unique and sequential | Pass | ADR-0003 in `adr-0003-wiki-publish-token.md`; follows ADR-0002. |
| 2 | Context states the problem, the forces (cost, risk, constraints) and the options evaluated | Pass | States the need, the scope problem, the two answered open points and the options. |
| 3 | At least two options were considered, or the absence of alternatives is justified | Pass | Three options. |
| 4 | Decision is stated in one or two unhedged sentences and matches one of the evaluated options | Pass | Finding fixed during this review: the decision had three sentences. It is now two sentences (option 2). |
| 5 | Consequences list both Positive and Negative outcomes | Pass | Three positive, three negative. |
| 6 | Quality-attribute impacts (performance, security, portability, etc.) are named where the decision affects them | Pass | Security is named: sync token stays read-only; fallback may hide a missing secret. |
| 7 | Affected Artifacts are listed as links, and each is also in CrossReference | Pass | MIL-005, ADR-0001 and RC-011 are linked and cited. |
| 8 | Status changes are recorded as new Version History rows with a Change summary and Commit link; retained rows are never rewritten | Pass | Initial row only. |
| 9 | A superseded or deprecated ADR names its successor, and the successor links back | N-A | Nothing is superseded. |
| 10 | Written in business or technical language of the domain, with no unexplained abbreviations | Pass | IT Professional English; `NAME=token`, `HTTP 401` and `403` are explained. |
| 11 | Status is one of `Proposed`, `Accepted`, `Rejected`, `Deprecated` or `Superseded by ADR-NNNN`, and every Version History row uses only these | Pass | Accepted only. |
## Overall Verdict
Go - all applicable criteria pass; the one finding (criterion 4) was fixed during the review. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Scope `TOKEN_FOR_GITEA_WIKI` to this repository instead of the organisation, and update the credentials guide and MIL-005 task 2 text (new version rows, retranslated wiki pages) | S03 | 2026-10-24 |
---
[ADR-0003]: ../../adr/adr-0003-wiki-publish-token.md
[QC-ADR-001]: ../../../framework/qc/qc-adr.md
[bc3bd07]: https://git.tirsystem.com/TirSystem/github-action/commit/bc3bd07b29a0a3dcf45045b9baac64c36144c6d1
@@ -1,47 +0,0 @@
# Review Record: PP-001 Project Plan (PAT_FOR_GITHUB, open issues)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-015 |
| CrossReference | [PP-001], [BC-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [b282e10] |
---
## Artifact Under Review
- Instance reviewed: [PP-001]
- Checklist used: none: the Project Plan has no QC checklist. Validated against the Business Case [BC-001] and the Go / No-Go criteria of each listed milestone, as `PP.md` prescribes.
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Every milestone in the plan has a `MIL-*` document and the plan's dates equal that document's target date | Pass | MIL-001 to MIL-005 exist; decision dates equal each Target Date. |
| 2 | Every Business Case scope item is covered by a gateway | Pass | Unchanged; Scope Coverage maps all items. |
| 3 | The schedule respects the Business Case constraints | Pass | The Business Case sets no deadline; dates are marked as proposals. |
| 4 | Dependencies between milestones are stated | Pass | Unchanged. |
| 5 | Every gateway has an owner who is a stakeholder ID | Pass | All five gateways are owned by S05. |
| 6 | Plan content is internally consistent | Pass | Finding fixed during this review: UC candidate 2 still listed "malformed JSON" as a credential failure although no secret is JSON any more. It now lists the empty value, a wrong or expired token (HTTP 401) and a missing permission. The secret names match the code and the guides. |
| 7 | Open Issues are current | Pass | Finding fixed during this review: the MIL-001 task 1 and task 3 decisions were made and are recorded in MIL-001, so they are removed. The remaining items are still open: confirm dates, no QC checklist for the Project Plan, formal use cases wait for a diagram and user stories. This closes the RC-009 action item. |
## Overall Verdict
Go - all seven criteria pass; the two findings were fixed during the review. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Confirm the proposed dates and the start week (already in Open Issues) | S01 | 2026-10-17 |
---
[PP-001]: ../../project-plan.md
[BC-001]: ../../business-case.md
[b282e10]: https://git.tirsystem.com/TirSystem/github-action/commit/b282e107416a890d6df27e6bdf23ab8a65e17123
-47
View File
@@ -1,47 +0,0 @@
# Review Record: MIL-006 Shared wiki publishing
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-016 |
| CrossReference | [MIL-006], [QC-MIL-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [676a262] |
---
## Artifact Under Review
- Instance reviewed: [MIL-006]
- Checklist used: [QC-MIL-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | A concrete deliverable is defined for every gate | Pass | A scoped `publish-wiki.yml` with embedded script, an opt-in rule, tests, guides and one pilot repository. |
| 2 | Explicit Go/No-Go criteria are stated for each gate | Pass | Six criteria, each with a checkable Go and No-Go column. |
| 3 | Dependencies on other milestones are explicitly mapped | Pass | Depends on MIL-005 (publisher and wiki rules) and MIL-002 (scoped delivery verified, #9), with reasons. |
| 4 | Each milestone is traceable to a Business Case objective or KPI | Pass | Maps to O2 (a defined way to reach consuming repositories) and O3 of BC-001; also cites MIL-005 and ADR-0003. |
| 5 | Milestone owner and approving reviewer are identified | Pass | Owner S05, approving reviewer S01. |
| 6 | Milestone has a defined target date consistent with project constraints | Pass | 2026-12-26, marked proposed; the Business Case sets no deadline. |
## Overall Verdict
Go - all six criteria pass. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader. Accepting the milestone unlocks its tasks under the plan-first gate; the issues are still to be created with `sync-project.sh --apply`. The PP-001 row that adds MIL-006 is `Proposed` and was not part of this review.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Decide the opt-in mechanism (recommended: a `wiki/.publish` marker file) and the pilot repository (task 1) | S01 | 2026-12-14 |
| Store `TOKEN_FOR_GITEA_WIKI` in the pilot repository's organisation (task 4) | S03 | 2026-12-21 |
---
[MIL-006]: ../../milestones/mil-006-shared-wiki-publishing.md
[QC-MIL-001]: ../../../framework/qc/qc-milestones-gateways.md
[676a262]: https://git.tirsystem.com/TirSystem/github-action/commit/676a26240563338307c0454c3bf15b960bdb58ca
@@ -1,47 +0,0 @@
# Review Record: PP-001 Project Plan (MIL-006)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-017 |
| CrossReference | [PP-001], [BC-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [676a262] |
---
## Artifact Under Review
- Instance reviewed: [PP-001]
- Checklist used: none: the Project Plan has no QC checklist. Validated against the Business Case [BC-001] and the Go / No-Go criteria of each listed milestone, as `PP.md` prescribes.
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Every milestone in the plan has a `MIL-*` document and the plan's dates equal that document's target date | Pass | MIL-001 to MIL-006 exist; the MIL-006 decision date 2026-12-26 equals its Target Date. |
| 2 | Every Business Case scope item is covered by a gateway | Pass | The shared publisher (O2, O3) is mapped to MIL-006 in Scope Coverage; the wiki scope item stays on MIL-005. |
| 3 | The schedule respects the Business Case constraints | Pass | The Business Case sets no deadline; the dates are proposals and the plan says so. |
| 4 | Dependencies between milestones are stated | Pass | The Dependencies diagram shows MIL-002 to MIL-005 to MIL-006; MIL-006 also lists them in its own document. |
| 5 | Every gateway has an owner who is a stakeholder ID | Pass | MIL-006 is owned by S05. |
| 6 | Plan content is internally consistent | Pass | "Six milestones", the last decision date 2026-12-26, the Gantt entries and the Gateway Schedule agree. |
| 7 | Open Issues are current | Pass | Three items remain and are all still open: confirm dates, no QC checklist for the Project Plan, formal use cases wait for a diagram and user stories. |
## Overall Verdict
Go - all seven criteria pass; no findings. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Confirm the proposed dates and the start week (already in Open Issues) | S01 | 2026-12-14 |
---
[PP-001]: ../../project-plan.md
[BC-001]: ../../business-case.md
[676a262]: https://git.tirsystem.com/TirSystem/github-action/commit/676a26240563338307c0454c3bf15b960bdb58ca
-52
View File
@@ -1,52 +0,0 @@
# Review Record: ADR-0004 Opt-in rule and secret handling of the shared wiki publisher
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-018 |
| CrossReference | [ADR-0004], [QC-ADR-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [b22a2cd] |
---
## Artifact Under Review
- Instance reviewed: [ADR-0004]
- Checklist used: [QC-ADR-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The ID (`ADR-NNNN`, 4-digit) matches the filename number and is unique and sequential | Pass | ADR-0004 in `adr-0004-shared-wiki-publishing-opt-in.md`; follows ADR-0003. |
| 2 | Context states the problem, the forces (cost, risk, constraints) and the options evaluated | Pass | States the scoped delivery, the deletion risk, the per-organisation secret and the fallback. |
| 3 | At least two options were considered, or the absence of alternatives is justified | Pass | Four options for opting in (one with two forms) and two for the secret. |
| 4 | Decision is stated in one or two unhedged sentences and matches one of the evaluated options | Pass | Finding fixed during this review: the `prune` form was not among the evaluated options. It is now option 1(b), with the reason. The decision is two sentences. |
| 5 | Consequences list both Positive and Negative outcomes | Pass | Three positive, four negative. |
| 6 | Quality-attribute impacts (performance, security, portability, etc.) are named where the decision affects them | Pass | Security is named: no write without opt-in, no write access for the sync token, write access of anyone with repository write rights. |
| 7 | Affected Artifacts are listed as links, and each is also in CrossReference | Pass | MIL-006, ADR-0003 and ADR-0002 are linked and cited. |
| 8 | Status changes are recorded as new Version History rows with a Change summary and Commit link; retained rows are never rewritten | Pass | The earlier row is kept and only its status changed. |
| 9 | A superseded or deprecated ADR names its successor, and the successor links back | N-A | ADR-0003 is superseded only in part and stays in force for this repository's local workflow until MIL-006 task 2 lands; see the action item. |
| 10 | Written in business or technical language of the domain, with no unexplained abbreviations | Pass | IT Professional English; `prune` and the marker are explained where they are introduced. |
| 11 | Status is one of `Proposed`, `Accepted`, `Rejected`, `Deprecated` or `Superseded by ADR-NNNN`, and every Version History row uses only these | Pass | Deprecated and Accepted only. |
## Overall Verdict
Go - all applicable criteria pass; the one finding (criterion 4) was fixed during the review. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| When MIL-006 task 2 (#57) merges, mark ADR-0003 as superseded by ADR-0004 for the shared workflow (new version row and review record) | S01 | 2026-12-26 |
| Choose the pilot repository (MIL-006 task 4, already an action item in RC-016) | S01 | 2026-12-14 |
---
[ADR-0004]: ../../adr/adr-0004-shared-wiki-publishing-opt-in.md
[QC-ADR-001]: ../../../framework/qc/qc-adr.md
[b22a2cd]: https://git.tirsystem.com/TirSystem/github-action/commit/b22a2cd59235078656c4440b945b787f88fbd345
-48
View File
@@ -1,48 +0,0 @@
# Review Record: UCD-001
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-019 |
| CrossReference | [UCD-001], [QC-UCD-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [a2bf2d4] |
---
## Artifact Under Review
- Instance reviewed: [UCD-001]
- Checklist used: [QC-UCD-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Actors are defined with correct UML stereotypes (e.g. `<<System>>`, `<<Actor>>`) | Pass | DevOps Professional and Platform Operator are `<<Actor>>`; Gitea Instance and GitHub are `<<System>>`. |
| 2 | System boundary is clearly drawn and labeled | Pass | Boundary "Reusable Workflow Collection". |
| 3 | Include/extend relationships are used correctly per UML 2.5.1, not as generic "uses" arrows | Pass | One include and one extend, each with a justification in the Relationships table; the extend applies only on failure. |
| 4 | Every actor participates in at least one use case (no orphan actors) | Pass | All four actors appear in the Actor Table with goals. |
| 5 | Diagram is traceable to a documented stakeholder need | Pass | S05, S03 and S04 in the Actor Table; SA-001 and BC-001 cited. |
| 6 | Use case names are verb phrases describing actor goals, not internal system operations | Pass | Four goal names, none a system operation. |
| 7 | Diagram is free of implementation detail (e.g. UI widgets, database tables) | Pass | No tool, file or UI detail. |
| 8 | Actor and use case naming is consistent with corresponding Use Case and User Story documents | Pass | Checked mechanically: all four titles and both story roles match. |
## Overall Verdict
Go - all eight criteria pass. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | - | - |
---
[UCD-001]: ../../use-case-diagram.md
[QC-UCD-001]: ../../../framework/qc/qc-use-case-diagram.md
[a2bf2d4]: https://git.tirsystem.com/TirSystem/github-action/commit/a2bf2d420416f7aff2badc6fe32a7690e2e523fd
-47
View File
@@ -1,47 +0,0 @@
# Review Record: US-001
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-020 |
| CrossReference | [US-001], [QC-US-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [a2bf2d4] |
---
## Artifact Under Review
- Instance reviewed: [US-001]
- Checklist used: [QC-US-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Follows INVEST criteria (Independent, Negotiable, Valuable, Estimable, Small, Testable) | Pass | INVEST check present; US-001.05 and US-001.06 depend on US-001.04 and say so. |
| 2 | Written in "As a / I want / So that" form | Pass | All eight. |
| 3 | Clear, testable acceptance criteria are included | Pass | Two Given/When/Then criteria per story, each checked by a run or the guide. |
| 4 | Traceable to a use case or epic | Pass | Each story traces to one of UC-001 to UC-004 and to MIL-002. |
| 5 | Story is sized to fit within a single iteration | Pass | Each is one goal; two are already implemented and only tested. |
| 6 | Story statement avoids technical implementation detail | Pass | Domain terms only (mirror, token, runner). |
| 7 | Role named in the story matches an actor defined in the Use Case Diagram | Pass | DevOps Professional and Platform Operator both appear in UCD-001. |
## Overall Verdict
Go - all seven criteria pass. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | - | - |
---
[US-001]: ../../user-stories.md
[QC-US-001]: ../../../framework/qc/qc-user-story.md
[a2bf2d4]: https://git.tirsystem.com/TirSystem/github-action/commit/a2bf2d420416f7aff2badc6fe32a7690e2e523fd
-52
View File
@@ -1,52 +0,0 @@
# Review Record: UC-001
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-021 |
| CrossReference | [UC-001], [QC-UC-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [a2bf2d4] |
---
## Artifact Under Review
- Instance reviewed: [UC-001]
- Checklist used: [QC-UC-001] (Brief format)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Consists of a single, concise paragraph summarizing only the primary success scenario | Pass | Finding fixed during this review: the paragraph also described the no-mirror alternative; it now summarizes only the main success scenario (the alternative is US-001.02). |
| 2 | Written as an informal multi-paragraph narrative; may mention some alternate flows without formal structure | N-A | Format is Brief. |
| 3 | All standard sections are present: actors, preconditions, postconditions, main success scenario, alternative/exception flows | N-A | Format is Brief; the sections of a Brief use case are present (actor, stakeholders, pre- and postconditions, paragraph). |
| 4 | Preconditions and postconditions are explicitly defined | Pass | Both stated. |
| 5 | Primary actor is explicitly stated | Pass | DevOps Professional. |
| 6 | Stakeholders and their interests are stated | Pass | S-IDs from SA-001 with an interest each. |
| 7 | Main success scenario is written as clear, numbered steps | N-A | Format is Brief: one paragraph. |
| 8 | Alternative/exception flows correctly reference `<<include>>`/`<<extend>>` use cases where relevant, per UML 2.5.1 | N-A | No alternative flows in a Brief use case; the relationships are in UCD-001. |
| 9 | Explicit business rules are captured per step where applicable, rather than embedded loosely in narrative text | N-A | No steps in a Brief use case. |
| 10 | Naming of actors and use case title is consistent with the corresponding Use Case Diagram and User Stories | Pass | Title and actor match UCD-001 and US-001 exactly. |
| 11 | Scope/level (e.g. summary, user-goal, subfunction) is explicitly stated | Pass | Scope and user-goal level stated. |
| 12 | Use case is written from the actor's goal perspective, free of UI or implementation detail | Pass | Goal wording; the guides and secrets are named, no UI. |
## Overall Verdict
Go - all applicable criteria pass; the one finding (criterion 1) was fixed during the review. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | - | - |
---
[UC-001]: ../../uc-001/uc.md
[QC-UC-001]: ../../../framework/qc/qc-use-case.md
[a2bf2d4]: https://git.tirsystem.com/TirSystem/github-action/commit/a2bf2d420416f7aff2badc6fe32a7690e2e523fd
-52
View File
@@ -1,52 +0,0 @@
# Review Record: UC-002
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-022 |
| CrossReference | [UC-002], [QC-UC-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [a2bf2d4] |
---
## Artifact Under Review
- Instance reviewed: [UC-002]
- Checklist used: [QC-UC-001] (Brief format)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Consists of a single, concise paragraph summarizing only the primary success scenario | Pass | Finding fixed during this review: the paragraph also described the failure alternatives; it now summarizes only the main success scenario (the alternatives are in US-001.03). |
| 2 | Written as an informal multi-paragraph narrative; may mention some alternate flows without formal structure | N-A | Format is Brief. |
| 3 | All standard sections are present: actors, preconditions, postconditions, main success scenario, alternative/exception flows | N-A | Format is Brief; the sections of a Brief use case are present (actor, stakeholders, pre- and postconditions, paragraph). |
| 4 | Preconditions and postconditions are explicitly defined | Pass | Both stated. |
| 5 | Primary actor is explicitly stated | Pass | DevOps Professional. |
| 6 | Stakeholders and their interests are stated | Pass | S-IDs from SA-001 with an interest each. |
| 7 | Main success scenario is written as clear, numbered steps | N-A | Format is Brief: one paragraph. |
| 8 | Alternative/exception flows correctly reference `<<include>>`/`<<extend>>` use cases where relevant, per UML 2.5.1 | N-A | No alternative flows in a Brief use case; the relationships are in UCD-001. |
| 9 | Explicit business rules are captured per step where applicable, rather than embedded loosely in narrative text | N-A | No steps in a Brief use case. |
| 10 | Naming of actors and use case title is consistent with the corresponding Use Case Diagram and User Stories | Pass | Title and actor match UCD-001 and US-001 exactly. |
| 11 | Scope/level (e.g. summary, user-goal, subfunction) is explicitly stated | Pass | Scope and user-goal level stated. |
| 12 | Use case is written from the actor's goal perspective, free of UI or implementation detail | Pass | Goal wording; the guides and secrets are named, no UI. |
## Overall Verdict
Go - all applicable criteria pass; the one finding (criterion 1) was fixed during the review. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | - | - |
---
[UC-002]: ../../uc-002/uc.md
[QC-UC-001]: ../../../framework/qc/qc-use-case.md
[a2bf2d4]: https://git.tirsystem.com/TirSystem/github-action/commit/a2bf2d420416f7aff2badc6fe32a7690e2e523fd
-52
View File
@@ -1,52 +0,0 @@
# Review Record: UC-003
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-023 |
| CrossReference | [UC-003], [QC-UC-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [a2bf2d4] |
---
## Artifact Under Review
- Instance reviewed: [UC-003]
- Checklist used: [QC-UC-001] (Brief format)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Consists of a single, concise paragraph summarizing only the primary success scenario | Pass | Finding fixed during this review: the paragraph also described the defect alternative; it now summarizes only the main success scenario (see US-001.06). |
| 2 | Written as an informal multi-paragraph narrative; may mention some alternate flows without formal structure | N-A | Format is Brief. |
| 3 | All standard sections are present: actors, preconditions, postconditions, main success scenario, alternative/exception flows | N-A | Format is Brief; the sections of a Brief use case are present (actor, stakeholders, pre- and postconditions, paragraph). |
| 4 | Preconditions and postconditions are explicitly defined | Pass | Both stated. |
| 5 | Primary actor is explicitly stated | Pass | DevOps Professional. |
| 6 | Stakeholders and their interests are stated | Pass | S-IDs from SA-001 with an interest each. |
| 7 | Main success scenario is written as clear, numbered steps | N-A | Format is Brief: one paragraph. |
| 8 | Alternative/exception flows correctly reference `<<include>>`/`<<extend>>` use cases where relevant, per UML 2.5.1 | N-A | No alternative flows in a Brief use case; the relationships are in UCD-001. |
| 9 | Explicit business rules are captured per step where applicable, rather than embedded loosely in narrative text | N-A | No steps in a Brief use case. |
| 10 | Naming of actors and use case title is consistent with the corresponding Use Case Diagram and User Stories | Pass | Title and actor match UCD-001 and US-001 exactly. |
| 11 | Scope/level (e.g. summary, user-goal, subfunction) is explicitly stated | Pass | Scope and user-goal level stated. |
| 12 | Use case is written from the actor's goal perspective, free of UI or implementation detail | Pass | Goal wording; the guides and secrets are named, no UI. |
## Overall Verdict
Go - all applicable criteria pass; the one finding (criterion 1) was fixed during the review. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | - | - |
---
[UC-003]: ../../uc-003/uc.md
[QC-UC-001]: ../../../framework/qc/qc-use-case.md
[a2bf2d4]: https://git.tirsystem.com/TirSystem/github-action/commit/a2bf2d420416f7aff2badc6fe32a7690e2e523fd
-52
View File
@@ -1,52 +0,0 @@
# Review Record: UC-004
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-024 |
| CrossReference | [UC-004], [QC-UC-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [a2bf2d4] |
---
## Artifact Under Review
- Instance reviewed: [UC-004]
- Checklist used: [QC-UC-001] (Brief format)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Consists of a single, concise paragraph summarizing only the primary success scenario | Pass | Finding fixed during this review: the paragraph also described the runner and no-category alternatives; it now summarizes only the main success scenario (the alternatives are in US-001.07 and US-001.08). |
| 2 | Written as an informal multi-paragraph narrative; may mention some alternate flows without formal structure | N-A | Format is Brief. |
| 3 | All standard sections are present: actors, preconditions, postconditions, main success scenario, alternative/exception flows | N-A | Format is Brief; the sections of a Brief use case are present (actor, stakeholders, pre- and postconditions, paragraph). |
| 4 | Preconditions and postconditions are explicitly defined | Pass | Both stated. |
| 5 | Primary actor is explicitly stated | Pass | DevOps Professional. |
| 6 | Stakeholders and their interests are stated | Pass | S-IDs from SA-001 with an interest each. |
| 7 | Main success scenario is written as clear, numbered steps | N-A | Format is Brief: one paragraph. |
| 8 | Alternative/exception flows correctly reference `<<include>>`/`<<extend>>` use cases where relevant, per UML 2.5.1 | N-A | No alternative flows in a Brief use case; the relationships are in UCD-001. |
| 9 | Explicit business rules are captured per step where applicable, rather than embedded loosely in narrative text | N-A | No steps in a Brief use case. |
| 10 | Naming of actors and use case title is consistent with the corresponding Use Case Diagram and User Stories | Pass | Title and actor match UCD-001 and US-001 exactly. |
| 11 | Scope/level (e.g. summary, user-goal, subfunction) is explicitly stated | Pass | Scope and user-goal level stated. |
| 12 | Use case is written from the actor's goal perspective, free of UI or implementation detail | Pass | Goal wording; the guides and secrets are named, no UI. |
## Overall Verdict
Go - all applicable criteria pass; the one finding (criterion 1) was fixed during the review. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | - | - |
---
[UC-004]: ../../uc-004/uc.md
[QC-UC-001]: ../../../framework/qc/qc-use-case.md
[a2bf2d4]: https://git.tirsystem.com/TirSystem/github-action/commit/a2bf2d420416f7aff2badc6fe32a7690e2e523fd
@@ -1,47 +0,0 @@
# Review Record: PP-001 Project Plan (P1 use cases)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-025 |
| CrossReference | [PP-001], [BC-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [a2bf2d4] |
---
## Artifact Under Review
- Instance reviewed: [PP-001]
- Checklist used: none: the Project Plan has no QC checklist. Validated against the Business Case [BC-001] and the Go / No-Go criteria of each listed milestone, as `PP.md` prescribes.
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Every milestone in the plan has a `MIL-*` document and the plan's dates equal that document's target date | Pass | Unchanged. |
| 2 | Every Business Case scope item is covered by a gateway | Pass | Unchanged. |
| 3 | The schedule respects the Business Case constraints | Pass | Unchanged. |
| 4 | Dependencies between milestones are stated | Pass | Unchanged. |
| 5 | Every gateway has an owner who is a stakeholder ID | Pass | Unchanged. |
| 6 | Plan content is internally consistent | Pass | The appendix's use case candidates 1 to 4 correspond to UC-001 to UC-004; the plan cites US-001. |
| 7 | Open Issues are current | Pass | Finding fixed during this review: the item about use cases said the documents "need review". It now states that the P1 candidates are written as UC-001 to UC-004 with UCD-001 and US-001, and that P2 and P3 have none. |
## Overall Verdict
Go - all seven criteria pass; the one finding was fixed during the review. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | - | - |
---
[PP-001]: ../../project-plan.md
[BC-001]: ../../business-case.md
[a2bf2d4]: https://git.tirsystem.com/TirSystem/github-action/commit/a2bf2d420416f7aff2badc6fe32a7690e2e523fd
-46
View File
@@ -1,46 +0,0 @@
# Review Record: MIL-001 (target date)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-026 |
| CrossReference | [MIL-001], [QC-MIL-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [ea06eaa] |
---
## Artifact Under Review
- Instance reviewed: [MIL-001]
- Checklist used: [QC-MIL-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | A concrete deliverable is defined for every gate | Pass | Unchanged. |
| 2 | Explicit Go/No-Go criteria are stated for each gate | Pass | Unchanged. |
| 3 | Dependencies on other milestones are explicitly mapped | Pass | Unchanged. |
| 4 | Each milestone is traceable to a Business Case objective or KPI | Pass | Unchanged. |
| 5 | Milestone owner and approving reviewer are identified | Pass | Unchanged. |
| 6 | Milestone has a defined target date consistent with project constraints | Pass | Target date 2026-10-17 is now confirmed on 2026-10-10 by S01, standing in for S05 (ADR-0002); it was marked proposed. The Business Case sets no deadline. |
## Overall Verdict
Go - all six criteria pass; the only change reviewed is the confirmation of the target date. This closes the earlier action item to confirm it. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | - | - |
---
[MIL-001]: ../../milestones/mil-001-stabilise-metadata-sync.md
[QC-MIL-001]: ../../../framework/qc/qc-milestones-gateways.md
[ea06eaa]: https://git.tirsystem.com/TirSystem/github-action/commit/ea06eaaa698247d20e4a8e2694d7acbb1de58b63
-46
View File
@@ -1,46 +0,0 @@
# Review Record: MIL-002 (target date)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-027 |
| CrossReference | [MIL-002], [QC-MIL-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [ea06eaa] |
---
## Artifact Under Review
- Instance reviewed: [MIL-002]
- Checklist used: [QC-MIL-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | A concrete deliverable is defined for every gate | Pass | Unchanged. |
| 2 | Explicit Go/No-Go criteria are stated for each gate | Pass | Unchanged. |
| 3 | Dependencies on other milestones are explicitly mapped | Pass | Unchanged. |
| 4 | Each milestone is traceable to a Business Case objective or KPI | Pass | Unchanged. |
| 5 | Milestone owner and approving reviewer are identified | Pass | Unchanged. |
| 6 | Milestone has a defined target date consistent with project constraints | Pass | Target date 2026-10-31 is now confirmed on 2026-10-10 by S01, standing in for S05 (ADR-0002); it was marked proposed. The Business Case sets no deadline. |
## Overall Verdict
Go - all six criteria pass; the only change reviewed is the confirmation of the target date. This closes the earlier action item to confirm it. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | - | - |
---
[MIL-002]: ../../milestones/mil-002-onboarding-and-operations.md
[QC-MIL-001]: ../../../framework/qc/qc-milestones-gateways.md
[ea06eaa]: https://git.tirsystem.com/TirSystem/github-action/commit/ea06eaaa698247d20e4a8e2694d7acbb1de58b63
-46
View File
@@ -1,46 +0,0 @@
# Review Record: MIL-003 (target date)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-028 |
| CrossReference | [MIL-003], [QC-MIL-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [ea06eaa] |
---
## Artifact Under Review
- Instance reviewed: [MIL-003]
- Checklist used: [QC-MIL-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | A concrete deliverable is defined for every gate | Pass | Unchanged. |
| 2 | Explicit Go/No-Go criteria are stated for each gate | Pass | Unchanged. |
| 3 | Dependencies on other milestones are explicitly mapped | Pass | Unchanged. |
| 4 | Each milestone is traceable to a Business Case objective or KPI | Pass | Unchanged. |
| 5 | Milestone owner and approving reviewer are identified | Pass | Unchanged. |
| 6 | Milestone has a defined target date consistent with project constraints | Pass | Target date 2026-11-14 is now confirmed on 2026-10-10 by S01, standing in for S05 (ADR-0002); it was marked proposed. The Business Case sets no deadline. |
## Overall Verdict
Go - all six criteria pass; the only change reviewed is the confirmation of the target date. This closes the earlier action item to confirm it. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | - | - |
---
[MIL-003]: ../../milestones/mil-003-quality-checks.md
[QC-MIL-001]: ../../../framework/qc/qc-milestones-gateways.md
[ea06eaa]: https://git.tirsystem.com/TirSystem/github-action/commit/ea06eaaa698247d20e4a8e2694d7acbb1de58b63
-46
View File
@@ -1,46 +0,0 @@
# Review Record: MIL-004 (target date)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-029 |
| CrossReference | [MIL-004], [QC-MIL-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [ea06eaa] |
---
## Artifact Under Review
- Instance reviewed: [MIL-004]
- Checklist used: [QC-MIL-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | A concrete deliverable is defined for every gate | Pass | Unchanged. |
| 2 | Explicit Go/No-Go criteria are stated for each gate | Pass | Unchanged. |
| 3 | Dependencies on other milestones are explicitly mapped | Pass | Unchanged. |
| 4 | Each milestone is traceable to a Business Case objective or KPI | Pass | Unchanged. |
| 5 | Milestone owner and approving reviewer are identified | Pass | Unchanged. |
| 6 | Milestone has a defined target date consistent with project constraints | Pass | Target date 2026-11-28 is now confirmed on 2026-10-10 by S01, standing in for S05 (ADR-0002); it was marked proposed. The Business Case sets no deadline. |
## Overall Verdict
Go - all six criteria pass; the only change reviewed is the confirmation of the target date. This closes the earlier action item to confirm it. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | - | - |
---
[MIL-004]: ../../milestones/mil-004-versioned-release.md
[QC-MIL-001]: ../../../framework/qc/qc-milestones-gateways.md
[ea06eaa]: https://git.tirsystem.com/TirSystem/github-action/commit/ea06eaaa698247d20e4a8e2694d7acbb1de58b63
-46
View File
@@ -1,46 +0,0 @@
# Review Record: MIL-005 (target date)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-030 |
| CrossReference | [MIL-005], [QC-MIL-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [ea06eaa] |
---
## Artifact Under Review
- Instance reviewed: [MIL-005]
- Checklist used: [QC-MIL-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | A concrete deliverable is defined for every gate | Pass | Unchanged. |
| 2 | Explicit Go/No-Go criteria are stated for each gate | Pass | Unchanged. |
| 3 | Dependencies on other milestones are explicitly mapped | Pass | Unchanged. |
| 4 | Each milestone is traceable to a Business Case objective or KPI | Pass | Unchanged. |
| 5 | Milestone owner and approving reviewer are identified | Pass | Unchanged. |
| 6 | Milestone has a defined target date consistent with project constraints | Pass | Target date 2026-12-12 is now confirmed on 2026-10-10 by S01, standing in for S05 (ADR-0002); it was marked proposed. The Business Case sets no deadline. |
## Overall Verdict
Go - all six criteria pass; the only change reviewed is the confirmation of the target date. This closes the earlier action item to confirm it. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | - | - |
---
[MIL-005]: ../../milestones/mil-005-wiki-and-translations.md
[QC-MIL-001]: ../../../framework/qc/qc-milestones-gateways.md
[ea06eaa]: https://git.tirsystem.com/TirSystem/github-action/commit/ea06eaaa698247d20e4a8e2694d7acbb1de58b63
-46
View File
@@ -1,46 +0,0 @@
# Review Record: MIL-006 (target date)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-031 |
| CrossReference | [MIL-006], [QC-MIL-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [ea06eaa] |
---
## Artifact Under Review
- Instance reviewed: [MIL-006]
- Checklist used: [QC-MIL-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | A concrete deliverable is defined for every gate | Pass | Unchanged. |
| 2 | Explicit Go/No-Go criteria are stated for each gate | Pass | Unchanged. |
| 3 | Dependencies on other milestones are explicitly mapped | Pass | Unchanged. |
| 4 | Each milestone is traceable to a Business Case objective or KPI | Pass | Unchanged. |
| 5 | Milestone owner and approving reviewer are identified | Pass | Unchanged. |
| 6 | Milestone has a defined target date consistent with project constraints | Pass | Target date 2026-12-26 is now confirmed on 2026-10-10 by S01, standing in for S05 (ADR-0002); it was marked proposed. The Business Case sets no deadline. |
## Overall Verdict
Go - all six criteria pass; the only change reviewed is the confirmation of the target date. This closes the earlier action item to confirm it. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | - | - |
---
[MIL-006]: ../../milestones/mil-006-shared-wiki-publishing.md
[QC-MIL-001]: ../../../framework/qc/qc-milestones-gateways.md
[ea06eaa]: https://git.tirsystem.com/TirSystem/github-action/commit/ea06eaaa698247d20e4a8e2694d7acbb1de58b63
-47
View File
@@ -1,47 +0,0 @@
# Review Record: PP-001 Project Plan (dates confirmed)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-032 |
| CrossReference | [PP-001], [BC-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [ea06eaa] |
---
## Artifact Under Review
- Instance reviewed: [PP-001]
- Checklist used: none: the Project Plan has no QC checklist. Validated against the Business Case [BC-001] and the Go / No-Go criteria of each listed milestone, as `PP.md` prescribes.
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Every milestone in the plan has a `MIL-*` document and the plan's dates equal that document's target date | Pass | MIL-001 to MIL-006 now state their target dates as confirmed (RC-026 to RC-031). |
| 2 | Every Business Case scope item is covered by a gateway | Pass | Unchanged. |
| 3 | The schedule respects the Business Case constraints | Pass | The Business Case sets no deadline. |
| 4 | Dependencies between milestones are stated | Pass | Unchanged. |
| 5 | Every gateway has an owner who is a stakeholder ID | Pass | Unchanged. |
| 6 | Plan content is internally consistent | Pass | Purpose and Planning Assumptions say the dates were confirmed; no remaining text calls them proposals. |
| 7 | Open Issues are current | Pass | The item to confirm the proposed dates is removed; the two remaining items are still open (no QC checklist for the Project Plan; P2 and P3 use cases). |
## Overall Verdict
Go - all seven criteria pass. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | - | - |
---
[PP-001]: ../../project-plan.md
[BC-001]: ../../business-case.md
[ea06eaa]: https://git.tirsystem.com/TirSystem/github-action/commit/ea06eaaa698247d20e4a8e2694d7acbb1de58b63
@@ -1,46 +0,0 @@
# Review Record: MIL-003 (reusable workflow support verified)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-033 |
| CrossReference | [MIL-003], [QC-MIL-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [b3f006f] |
---
## Artifact Under Review
- Instance reviewed: [MIL-003]
- Checklist used: [QC-MIL-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | A concrete deliverable is defined for every gate | Pass | Unchanged. |
| 2 | Explicit Go/No-Go criteria are stated for each gate | Pass | Unchanged; criterion 1 (reusable workflows verified and recorded) is now evidenced by the Verification results. |
| 3 | Dependencies on other milestones are explicitly mapped | Pass | Unchanged. |
| 4 | Each milestone is traceable to a Business Case objective or KPI | Pass | Unchanged. |
| 5 | Milestone owner and approving reviewer are identified | Pass | Unchanged. |
| 6 | Milestone has a defined target date consistent with project constraints | Pass | Unchanged. |
## Overall Verdict
Go - all six criteria pass; the reviewed change records the result of task 1 and its limits (private provider, secrets, tag references not tested). S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Test a private provider repository, `secrets: inherit` and a tag reference before MIL-004 relies on them | S05 | 2026-11-28 |
---
[MIL-003]: ../../milestones/mil-003-quality-checks.md
[QC-MIL-001]: ../../../framework/qc/qc-milestones-gateways.md
[b3f006f]: https://git.tirsystem.com/TirSystem/github-action/commit/b3f006f7a482392189a46c324ad4f28c4c3a2d2a
@@ -1,46 +0,0 @@
# Review Record: MIL-004 (scripts as files)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-034 |
| CrossReference | [MIL-004], [QC-MIL-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [616c5d2] |
---
## Artifact Under Review
- Instance reviewed: [MIL-004]
- Checklist used: [QC-MIL-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | A concrete deliverable is defined for every gate | Pass | The deliverable now also names scripts as files fetched at a pinnable reference. |
| 2 | Explicit Go/No-Go criteria are stated for each gate | Pass | New criterion 5 is checkable: the count of embedded scripts is 0 and a run in another organization passes. |
| 3 | Dependencies on other milestones are explicitly mapped | Pass | Unchanged (MIL-003); task 6 needs no other milestone, because the checkout of a script repository was verified on 2026-10-10. |
| 4 | Each milestone is traceable to a Business Case objective or KPI | Pass | Finding fixed during this review: task 6 serves O2 (one canonical copy and a defined way to reach consuming repositories) and the Traceability table listed only O4. It now lists O2 and O4. |
| 5 | Milestone owner and approving reviewer are identified | Pass | Unchanged: owner S05, approving reviewer S01. |
| 6 | Milestone has a defined target date consistent with project constraints | Pass | 2026-11-28, confirmed (RC-029). |
## Overall Verdict
Go - all six criteria pass; the one finding (criterion 4) was fixed during the review. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader. Accepting the amendment unlocks task 6 under the plan-first gate; the issue is still to be created with `sync-project.sh --apply`.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Decide whether consumers pin a tag or follow `main` for the shared scripts (task 1 of this milestone) | S01 | 2026-11-16 |
---
[MIL-004]: ../../milestones/mil-004-versioned-release.md
[QC-MIL-001]: ../../../framework/qc/qc-milestones-gateways.md
[616c5d2]: https://git.tirsystem.com/TirSystem/github-action/commit/616c5d2e48f0d76399a6f78923891fc7f50c8e22
-48
View File
@@ -1,48 +0,0 @@
# Review Record: UCD-001 (quality checks)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-035 |
| CrossReference | [UCD-001], [QC-UCD-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [385d2fb] |
---
## Artifact Under Review
- Instance reviewed: [UCD-001]
- Checklist used: [QC-UCD-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Actors are defined with correct UML stereotypes (e.g. `<<System>>`, `<<Actor>>`) | Pass | Software Engineer is `<<Actor>>`, like the others. |
| 2 | System boundary is clearly drawn and labeled | Pass | Unchanged. |
| 3 | Include/extend relationships are used correctly per UML 2.5.1, not as generic "uses" arrows | Pass | Unchanged; the new use case has none. |
| 4 | Every actor participates in at least one use case (no orphan actors) | Pass | Software Engineer reaches Run Project Quality Checks. |
| 5 | Diagram is traceable to a documented stakeholder need | Pass | S02 in the Actor Table. |
| 6 | Use case names are verb phrases describing actor goals, not internal system operations | Pass | "Run Project Quality Checks". |
| 7 | Diagram is free of implementation detail (e.g. UI widgets, database tables) | Pass | No tool or file named. |
| 8 | Actor and use case naming is consistent with corresponding Use Case and User Story documents | Pass | Checked mechanically: UC-005's title and the story role match. |
## Overall Verdict
Go - all eight criteria pass for the amendment (the actor and use case of UC-005). S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | - | - |
---
[UCD-001]: ../../use-case-diagram.md
[QC-UCD-001]: ../../../framework/qc/qc-use-case-diagram.md
[385d2fb]: https://git.tirsystem.com/TirSystem/github-action/commit/385d2fb7cb9be1fdc8fd3503d0af624fa38eafc7
-47
View File
@@ -1,47 +0,0 @@
# Review Record: US-001 (quality checks)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-036 |
| CrossReference | [US-001], [QC-US-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [385d2fb] |
---
## Artifact Under Review
- Instance reviewed: [US-001]
- Checklist used: [QC-US-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Follows INVEST criteria (Independent, Negotiable, Valuable, Estimable, Small, Testable) | Pass | INVEST check updated to ten stories; the two new ones are independent of the others. |
| 2 | Written in "As a / I want / So that" form | Pass | US-001.09 and US-001.10. |
| 3 | Clear, testable acceptance criteria are included | Pass | Two Given/When/Then criteria each, matching the ADR-0005 contract. |
| 4 | Traceable to a use case or epic | Pass | UC-005 and MIL-003. |
| 5 | Story is sized to fit within a single iteration | Pass | One goal each. |
| 6 | Story statement avoids technical implementation detail | Pass | No tool named in the statements. |
| 7 | Role named in the story matches an actor defined in the Use Case Diagram | Pass | Software Engineer is in UCD-001. |
## Overall Verdict
Go - all seven criteria pass for the two added stories. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | - | - |
---
[US-001]: ../../user-stories.md
[QC-US-001]: ../../../framework/qc/qc-user-story.md
[385d2fb]: https://git.tirsystem.com/TirSystem/github-action/commit/385d2fb7cb9be1fdc8fd3503d0af624fa38eafc7
-52
View File
@@ -1,52 +0,0 @@
# Review Record: UC-005 (quality checks)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-037 |
| CrossReference | [UC-005], [QC-UC-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [385d2fb] |
---
## Artifact Under Review
- Instance reviewed: [UC-005]
- Checklist used: [QC-UC-001] (Brief format)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Consists of a single, concise paragraph summarizing only the primary success scenario | Pass | Finding fixed during this review: the paragraph also described the failure output; it now summarizes only the main success scenario (the failure is US-001.10). |
| 2 | Written as an informal multi-paragraph narrative; may mention some alternate flows without formal structure | N-A | Format is Brief. |
| 3 | All standard sections are present: actors, preconditions, postconditions, main success scenario, alternative/exception flows | N-A | Format is Brief; actor, stakeholders, pre- and postconditions and the paragraph are present. |
| 4 | Preconditions and postconditions are explicitly defined | Pass | Both stated. |
| 5 | Primary actor is explicitly stated | Pass | Software Engineer. |
| 6 | Stakeholders and their interests are stated | Pass | S02 and S05. |
| 7 | Main success scenario is written as clear, numbered steps | N-A | Format is Brief. |
| 8 | Alternative/exception flows correctly reference `<<include>>`/`<<extend>>` use cases where relevant, per UML 2.5.1 | N-A | No alternative flows in a Brief use case. |
| 9 | Explicit business rules are captured per step where applicable, rather than embedded loosely in narrative text | N-A | No steps in a Brief use case. |
| 10 | Naming of actors and use case title is consistent with the corresponding Use Case Diagram and User Stories | Pass | Title and actor match UCD-001 and US-001. |
| 11 | Scope/level (e.g. summary, user-goal, subfunction) is explicitly stated | Pass | Scope and user-goal level. |
| 12 | Use case is written from the actor's goal perspective, free of UI or implementation detail | Pass | Goal wording; no tool named. |
## Overall Verdict
Go - all applicable criteria pass; the one finding (criterion 1) was fixed during the review. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | - | - |
---
[UC-005]: ../../uc-005/uc.md
[QC-UC-001]: ../../../framework/qc/qc-use-case.md
[385d2fb]: https://git.tirsystem.com/TirSystem/github-action/commit/385d2fb7cb9be1fdc8fd3503d0af624fa38eafc7
-51
View File
@@ -1,51 +0,0 @@
# Review Record: ADR-0005 (quality checks)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-038 |
| CrossReference | [ADR-0005], [QC-ADR-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [385d2fb] |
---
## Artifact Under Review
- Instance reviewed: [ADR-0005]
- Checklist used: [QC-ADR-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The ID (`ADR-NNNN`, 4-digit) matches the filename number and is unique and sequential | Pass | ADR-0005 in `adr-0005-quality-check-contract.md`. |
| 2 | Context states the problem, the forces (cost, risk, constraints) and the options evaluated | Pass | Facts measured on the runner on 2026-10-10 and four options. |
| 3 | At least two options were considered, or the absence of alternatives is justified | Pass | Four options. |
| 4 | Decision is stated in one or two unhedged sentences and matches one of the evaluated options | Pass | Two sentences; option 1. |
| 5 | Consequences list both Positive and Negative outcomes | Pass | Three positive and five negative after the fix. |
| 6 | Quality-attribute impacts (performance, security, portability, etc.) are named where the decision affects them | Pass | Finding fixed during this review: the security impact (tools downloaded from PyPI on every run, versions pinned but not hash-pinned, runner runs as root) was not named. It is now a negative consequence; performance and reliability were already named. |
| 7 | Affected Artifacts are listed as links, and each is also in CrossReference | Pass | MIL-003, UC-005, US-001 and ADR-0004 are linked and cited. |
| 8 | Status changes are recorded as new Version History rows with a Change summary and Commit link; retained rows are never rewritten | Pass | The earlier row is kept and only its status changed. |
| 9 | A superseded or deprecated ADR names its successor, and the successor links back | N-A | Nothing is superseded. |
| 10 | Written in business or technical language of the domain, with no unexplained abbreviations | Pass | PyPI, venv and the tools are named where used. |
| 11 | Status is one of `Proposed`, `Accepted`, `Rejected`, `Deprecated` or `Superseded by ADR-NNNN`, and every Version History row uses only these | Pass | Deprecated and Accepted only. |
## Overall Verdict
Go - all applicable criteria pass; the one finding (criterion 6) was fixed during the review. The contract unlocks tasks 3 to 5 of MIL-003 under the plan-first gate. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Decide whether to hash-pin the tool packages before consumers outside this organization rely on the workflow (MIL-004) | S05 | 2026-11-28 |
---
[ADR-0005]: ../../adr/adr-0005-quality-check-contract.md
[QC-ADR-001]: ../../../framework/qc/qc-adr.md
[385d2fb]: https://git.tirsystem.com/TirSystem/github-action/commit/385d2fb7cb9be1fdc8fd3503d0af624fa38eafc7
@@ -1,47 +0,0 @@
# Review Record: MIL-003 (adoption in RepoFoundry)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-039 |
| CrossReference | [MIL-003], [QC-MIL-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [3b8681d] |
---
## Artifact Under Review
- Instance reviewed: [MIL-003]
- Checklist used: [QC-MIL-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | A concrete deliverable is defined for every gate | Pass | Unchanged. |
| 2 | Explicit Go/No-Go criteria are stated for each gate | Pass | Unchanged; criterion 2 (another repository runs the workflow and its status check appears on pull requests) is evidenced by the pull-request run in RepoFoundry. |
| 3 | Dependencies on other milestones are explicitly mapped | Pass | Unchanged. |
| 4 | Each milestone is traceable to a Business Case objective or KPI | Pass | Unchanged. |
| 5 | Milestone owner and approving reviewer are identified | Pass | Unchanged. |
| 6 | Milestone has a defined target date consistent with project constraints | Pass | Unchanged. |
## Overall Verdict
Go - all six criteria pass; the reviewed change records the adoption trial and its findings. The adoption is not complete until RepoFoundry PR 76 is merged, and the record says so. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Merge RepoFoundry PR 76 (its maintainers), then close issue #18 | S01 | 2026-11-14 |
| Put the three findings (shfmt style in `.editorconfig`, relative paths, reference `main` or a tag) in the results guide (issue #19) | S01 | 2026-11-14 |
---
[MIL-003]: ../../milestones/mil-003-quality-checks.md
[QC-MIL-001]: ../../../framework/qc/qc-milestones-gateways.md
[3b8681d]: https://git.tirsystem.com/TirSystem/github-action/commit/3b8681d0236c669b794ffbba725433fff600a2d2
@@ -1,48 +0,0 @@
# Review Record: UCD-001 (release process)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-040 |
| CrossReference | [UCD-001], [QC-UCD-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [044d8ba] |
---
## Artifact Under Review
- Instance reviewed: [UCD-001]
- Checklist used: [QC-UCD-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Actors are defined with correct UML stereotypes (e.g. `<<System>>`, `<<Actor>>`) | Pass | Unchanged actors. |
| 2 | System boundary is clearly drawn and labeled | Pass | Unchanged. |
| 3 | Include/extend relationships are used correctly per UML 2.5.1, not as generic "uses" arrows | Pass | The new use case has none. |
| 4 | Every actor participates in at least one use case (no orphan actors) | Pass | DevOps Professional reaches Release a Reusable Workflow. |
| 5 | Diagram is traceable to a documented stakeholder need | Pass | S05 in the Actor Table. |
| 6 | Use case names are verb phrases describing actor goals, not internal system operations | Pass | "Release a Reusable Workflow". |
| 7 | Diagram is free of implementation detail (e.g. UI widgets, database tables) | Pass | No tool or file named. |
| 8 | Actor and use case naming is consistent with corresponding Use Case and User Story documents | Pass | UC-006's title and the story roles match. |
## Overall Verdict
Go - all eight criteria pass for the amendment (the use case of UC-006). S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | - | - |
---
[UCD-001]: ../../use-case-diagram.md
[QC-UCD-001]: ../../../framework/qc/qc-use-case-diagram.md
[044d8ba]: https://git.tirsystem.com/TirSystem/github-action/commit/044d8ba21f96f4aceb807d62addc35cdcbb56051
-47
View File
@@ -1,47 +0,0 @@
# Review Record: US-001 (release process)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-041 |
| CrossReference | [US-001], [QC-US-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [044d8ba] |
---
## Artifact Under Review
- Instance reviewed: [US-001]
- Checklist used: [QC-US-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Follows INVEST criteria (Independent, Negotiable, Valuable, Estimable, Small, Testable) | Pass | INVEST check updated to thirteen stories. |
| 2 | Written in "As a / I want / So that" form | Pass | US-001.11 to US-001.13. |
| 3 | Clear, testable acceptance criteria are included | Pass | Two Given/When/Then criteria each, matching ADR-0006. |
| 4 | Traceable to a use case or epic | Pass | Finding fixed during this review: US-001.13 is a consumer's goal (pin a version) but traced to UC-006, whose actor is the DevOps Professional. It now traces to the epic MIL-004 and names its use case, Consume a Workflow Update, as not yet written; UC-006 lists only US-001.11 and US-001.12. |
| 5 | Story is sized to fit within a single iteration | Pass | One goal each. |
| 6 | Story statement avoids technical implementation detail | Pass | Tags are named only in the criteria, as the observable result. |
| 7 | Role named in the story matches an actor defined in the Use Case Diagram | Pass | DevOps Professional and Software Engineer are in UCD-001. |
## Overall Verdict
Go - all seven criteria pass; the one finding (criterion 4) was fixed during the review. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | - | - |
---
[US-001]: ../../user-stories.md
[QC-US-001]: ../../../framework/qc/qc-user-story.md
[044d8ba]: https://git.tirsystem.com/TirSystem/github-action/commit/044d8ba21f96f4aceb807d62addc35cdcbb56051
-52
View File
@@ -1,52 +0,0 @@
# Review Record: UC-006
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-042 |
| CrossReference | [UC-006], [QC-UC-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [044d8ba] |
---
## Artifact Under Review
- Instance reviewed: [UC-006]
- Checklist used: [QC-UC-001] (Brief format)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Consists of a single, concise paragraph summarizing only the primary success scenario | Pass | The paragraph describes the main flow: validation, changelog, tags, release page. The failure and undo paths are in the process guide and the stories. |
| 2 | Written as an informal multi-paragraph narrative; may mention some alternate flows without formal structure | N-A | Format is Brief. |
| 3 | All standard sections are present: actors, preconditions, postconditions, main success scenario, alternative/exception flows | N-A | Format is Brief; actor, stakeholders, pre- and postconditions and the paragraph are present. |
| 4 | Preconditions and postconditions are explicitly defined | Pass | Both stated. |
| 5 | Primary actor is explicitly stated | Pass | DevOps Professional. |
| 6 | Stakeholders and their interests are stated | Pass | S05, S02 and S03. |
| 7 | Main success scenario is written as clear, numbered steps | N-A | Format is Brief. |
| 8 | Alternative/exception flows correctly reference `<<include>>`/`<<extend>>` use cases where relevant, per UML 2.5.1 | N-A | No alternative flows in a Brief use case. |
| 9 | Explicit business rules are captured per step where applicable, rather than embedded loosely in narrative text | N-A | No steps in a Brief use case. |
| 10 | Naming of actors and use case title is consistent with the corresponding Use Case Diagram and User Stories | Pass | Title and actor match UCD-001; its stories are US-001.11 and US-001.12. |
| 11 | Scope/level (e.g. summary, user-goal, subfunction) is explicitly stated | Pass | Scope and user-goal level. |
| 12 | Use case is written from the actor's goal perspective, free of UI or implementation detail | Pass | Goal wording; tags and the changelog are domain terms. |
## Overall Verdict
Go - all applicable criteria pass. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | - | - |
---
[UC-006]: ../../uc-006/uc.md
[QC-UC-001]: ../../../framework/qc/qc-use-case.md
[044d8ba]: https://git.tirsystem.com/TirSystem/github-action/commit/044d8ba21f96f4aceb807d62addc35cdcbb56051
-52
View File
@@ -1,52 +0,0 @@
# Review Record: ADR-0006
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-043 |
| CrossReference | [ADR-0006], [QC-ADR-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [044d8ba] |
---
## Artifact Under Review
- Instance reviewed: [ADR-0006]
- Checklist used: [QC-ADR-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The ID (`ADR-NNNN`, 4-digit) matches the filename number and is unique and sequential | Pass | ADR-0006 in `adr-0006-release-process-and-version-pinning.md`. |
| 2 | Context states the problem, the forces (cost, risk, constraints) and the options evaluated | Pass | Names that every consumer runs `main`, what can and cannot be pinned, and the options. |
| 3 | At least two options were considered, or the absence of alternatives is justified | Pass | Four options for the version unit and three for the pin. |
| 4 | Decision is stated in one or two unhedged sentences and matches one of the evaluated options | Pass | Two sentences; options 1 and b. |
| 5 | Consequences list both Positive and Negative outcomes | Pass | Three positive and four negative. |
| 6 | Quality-attribute impacts (performance, security, portability, etc.) are named where the decision affects them | Pass | Reliability for consumers and the security of tag permissions and of a bad merge of a scoped file are named. |
| 7 | Affected Artifacts are listed as links, and each is also in CrossReference | Pass | MIL-004, UC-006, US-001, ADR-0005 and ADR-0004 are linked and cited. |
| 8 | Status changes are recorded as new Version History rows with a Change summary and Commit link; retained rows are never rewritten | Pass | The earlier row is kept and only its status changed. |
| 9 | A superseded or deprecated ADR names its successor, and the successor links back | N-A | Nothing is superseded. |
| 10 | Written in business or technical language of the domain, with no unexplained abbreviations | Pass | Finding fixed during this review: SemVer was used without being expanded; it is now introduced as semantic version (SemVer). |
| 11 | Status is one of `Proposed`, `Accepted`, `Rejected`, `Deprecated` or `Superseded by ADR-NNNN`, and every Version History row uses only these | Pass | Deprecated and Accepted only. |
## Overall Verdict
Go - all applicable criteria pass; the one finding (criterion 10) was fixed during the review. It unlocks tasks 2 to 5 of MIL-004 (#21 to #24) under the plan-first gate. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Pin the scripts fetched by the two scoped workflows to `v1` once it exists (the workflows still say `ref: main`) | S05 | 2026-11-28 |
| Review who may merge to `main` and who may move tags, since a scoped workflow file cannot be pinned by consumers | S01 | 2026-11-14 |
---
[ADR-0006]: ../../adr/adr-0006-release-process-and-version-pinning.md
[QC-ADR-001]: ../../../framework/qc/qc-adr.md
[044d8ba]: https://git.tirsystem.com/TirSystem/github-action/commit/044d8ba21f96f4aceb807d62addc35cdcbb56051
-52
View File
@@ -1,52 +0,0 @@
# Review Record: UC-007
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-044 |
| CrossReference | [UC-007], [QC-UC-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [4cf52af] |
---
## Artifact Under Review
- Instance reviewed: [UC-007]
- Checklist used: [QC-UC-001] (Brief format)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Consists of a single, concise paragraph summarizing only the primary success scenario | Pass | The paragraph describes read, try in one repository, read the run, roll out; the rollback and the failures are in the stories and the guide. |
| 2 | Written as an informal multi-paragraph narrative; may mention some alternate flows without formal structure | N-A | Format is Brief. |
| 3 | All standard sections are present: actors, preconditions, postconditions, main success scenario, alternative/exception flows | N-A | Format is Brief; actor, stakeholders, pre- and postconditions and the paragraph are present. |
| 4 | Preconditions and postconditions are explicitly defined | Pass | Both stated; the precondition names the release process of UC-006. |
| 5 | Primary actor is explicitly stated | Pass | Software Engineer. |
| 6 | Stakeholders and their interests are stated | Pass | S02 and S05. |
| 7 | Main success scenario is written as clear, numbered steps | N-A | Format is Brief. |
| 8 | Alternative/exception flows correctly reference `<<include>>`/`<<extend>>` use cases where relevant, per UML 2.5.1 | N-A | No alternative flows in a Brief use case. |
| 9 | Explicit business rules are captured per step where applicable, rather than embedded loosely in narrative text | N-A | No steps in a Brief use case. |
| 10 | Naming of actors and use case title is consistent with the corresponding Use Case Diagram and User Stories | Pass | Title and actor match UCD-001 (checked mechanically); stories are US-001.13 to US-001.15. |
| 11 | Scope/level (e.g. summary, user-goal, subfunction) is explicitly stated | Pass | Scope and user-goal level. |
| 12 | Use case is written from the actor's goal perspective, free of UI or implementation detail | Pass | Goal wording; no tool named. |
## Overall Verdict
Go - all applicable criteria pass. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | - | - |
---
[UC-007]: ../../uc-007/uc.md
[QC-UC-001]: ../../../framework/qc/qc-use-case.md
[4cf52af]: https://git.tirsystem.com/TirSystem/github-action/commit/4cf52afe00f546c6b20424fb8dfc12796ffd9296
@@ -1,48 +0,0 @@
# Review Record: UCD-001 (consume an update)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-045 |
| CrossReference | [UCD-001], [QC-UCD-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [4cf52af] |
---
## Artifact Under Review
- Instance reviewed: [UCD-001]
- Checklist used: [QC-UCD-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Actors are defined with correct UML stereotypes (e.g. `<<System>>`, `<<Actor>>`) | Pass | Unchanged actors. |
| 2 | System boundary is clearly drawn and labeled | Pass | Unchanged. |
| 3 | Include/extend relationships are used correctly per UML 2.5.1, not as generic "uses" arrows | Pass | The new use case has none; its dependency on UC-006 is a precondition. |
| 4 | Every actor participates in at least one use case (no orphan actors) | Pass | Software Engineer now reaches two use cases. |
| 5 | Diagram is traceable to a documented stakeholder need | Pass | S02 in the Actor Table. |
| 6 | Use case names are verb phrases describing actor goals, not internal system operations | Pass | "Consume a Workflow Update". |
| 7 | Diagram is free of implementation detail (e.g. UI widgets, database tables) | Pass | No tool or file named. |
| 8 | Actor and use case naming is consistent with corresponding Use Case and User Story documents | Pass | UC-007's title and the story roles match. |
## Overall Verdict
Go - all eight criteria pass for the amendment (the use case of UC-007). S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | - | - |
---
[UCD-001]: ../../use-case-diagram.md
[QC-UCD-001]: ../../../framework/qc/qc-use-case-diagram.md
[4cf52af]: https://git.tirsystem.com/TirSystem/github-action/commit/4cf52afe00f546c6b20424fb8dfc12796ffd9296
-47
View File
@@ -1,47 +0,0 @@
# Review Record: US-001 (consume an update)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-046 |
| CrossReference | [US-001], [QC-US-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [4cf52af] |
---
## Artifact Under Review
- Instance reviewed: [US-001]
- Checklist used: [QC-US-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Follows INVEST criteria (Independent, Negotiable, Valuable, Estimable, Small, Testable) | Pass | INVEST check updated to fifteen stories. |
| 2 | Written in "As a / I want / So that" form | Pass | US-001.14 and US-001.15. |
| 3 | Clear, testable acceptance criteria are included | Pass | Two Given/When/Then criteria each; both are checked by reading the changelog or a run. |
| 4 | Traceable to a use case or epic | Pass | UC-007 and MIL-004; US-001.13 is now traced to UC-007 as well, closing the gap noted in RC-041. |
| 5 | Story is sized to fit within a single iteration | Pass | One goal each. |
| 6 | Story statement avoids technical implementation detail | Pass | No tool named in the statements. |
| 7 | Role named in the story matches an actor defined in the Use Case Diagram | Pass | Software Engineer is in UCD-001. |
## Overall Verdict
Go - all seven criteria pass. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | - | - |
---
[US-001]: ../../user-stories.md
[QC-US-001]: ../../../framework/qc/qc-user-story.md
[4cf52af]: https://git.tirsystem.com/TirSystem/github-action/commit/4cf52afe00f546c6b20424fb8dfc12796ffd9296
-51
View File
@@ -1,51 +0,0 @@
# Review Record: ADR-0007
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-047 |
| CrossReference | [ADR-0007], [QC-ADR-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [d9cd3c6] |
---
## Artifact Under Review
- Instance reviewed: [ADR-0007]
- Checklist used: [QC-ADR-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The ID (`ADR-NNNN`, 4-digit) matches the filename number and is unique and sequential | Pass | ADR-0007 in `adr-0007-release-publish-destination.md`, after ADR-0006. |
| 2 | Context states the problem, the forces (cost, risk, constraints) and the options evaluated | Pass | States what the repository contains, what the API offers and the two sensitive writes. |
| 3 | At least two options were considered, or the absence of alternatives is justified | Pass | Four options for the destination and three for the permission. |
| 4 | Decision is stated in one or two unhedged sentences and matches one of the evaluated options | Pass | Options 1 and a, with a named fallback b; the fallback is conditional on a fact the ADR says is unverified. |
| 5 | Consequences list both Positive and Negative outcomes | Pass | Three positive and three negative. |
| 6 | Quality-attribute impacts (performance, security, portability, etc.) are named where the decision affects them | Pass | Security (permission scope and secret) and portability (no release page on GitHub) are named. |
| 7 | Affected Artifacts are listed as links, and each is also in CrossReference | Pass | MIL-004, UC-006 and ADR-0006 are linked and cited. |
| 8 | Status changes are recorded as new Version History rows with a Change summary and Commit link; retained rows are never rewritten | Pass | Initial row only. |
| 9 | A superseded or deprecated ADR names its successor, and the successor links back | N-A | Nothing is superseded. |
| 10 | Written in business or technical language of the domain, with no unexplained abbreviations | Pass | No abbreviation without expansion. |
| 11 | Status is one of `Proposed`, `Accepted`, `Rejected`, `Deprecated` or `Superseded by ADR-NNNN`, and every Version History row uses only these | Pass | Accepted. |
## Overall Verdict
Go - all applicable criteria pass. The behaviour of the job token is an assumption that the first run of the release workflow (task 5) verifies, with the fallback already named. S01 gave the Go in chat on 2026-10-10, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Verify in the first run of the release workflow that the job token creates the tag and moves the major tag; if not, create `TOKEN_FOR_GITEA_RELEASE` | S05 | 2026-11-28 |
---
[ADR-0007]: ../../adr/adr-0007-release-publish-destination.md
[QC-ADR-001]: ../../../framework/qc/qc-adr.md
[d9cd3c6]: https://git.tirsystem.com/TirSystem/github-action/commit/d9cd3c67d4017984af8958f32240d3d66217e153
@@ -1,48 +0,0 @@
# Review Record: MIL-004 (verification results)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-048 |
| CrossReference | [MIL-004], [QC-MIL-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-11 | Deprecated | Jens Tirsvad Nielsen | S01 | Initial version | [6933e91] |
| 2026-10-11 | Accepted | Jens Tirsvad Nielsen | S01 | Criterion 3 verified; the action item is closed | [05b635c] |
---
## Artifact Under Review
- Instance reviewed: [MIL-004] after the first release, with its new Verification results section
- Checklist used: [QC-MIL-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | A concrete deliverable is defined for every gate | Pass | The release process, the upgrade guide, the release workflow and the scripts at a pinned reference now exist; the release page of `v1.0.0` is the proof. |
| 2 | Explicit Go/No-Go criteria are stated for each gate | Pass | All five criteria have a result in the Verification results table, each naming its evidence. |
| 3 | Dependencies on other milestones are explicitly mapped | Pass | Unchanged (MIL-003). |
| 4 | Each milestone is traceable to a Business Case objective or KPI | Pass | O2 and O4, unchanged. |
| 5 | Milestone owner and approving reviewer are identified | Pass | Owner S05, approving reviewer S01, unchanged. |
| 6 | Milestone has a defined target date consistent with project constraints | Pass | 2026-11-28; the criteria are met on 2026-10-11. |
## Overall Verdict
Go - all six criteria pass, and the five Go/No-Go criteria of MIL-004 are met. Criterion 3 (a consumer pinned to the previous version keeps working) was met by construction at the first release and verified on 2026-10-11 with pinned consumers after `v1.0.1` and `v1.1.0` (see the Verification results of MIL-004). S01 gave the Go in chat on 2026-10-11, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Done 2026-10-11: criterion 3 verified with pinned consumers after `v1.0.1` (run 660) and `v1.1.0` (run 672) | S05 | done |
---
[MIL-004]: ../../milestones/mil-004-versioned-release.md
[QC-MIL-001]: ../../../framework/qc/qc-milestones-gateways.md
[6933e91]: https://git.tirsystem.com/TirSystem/github-action/commit/6933e91c83075fb39b2dfbe41683cb2a0a0bce28
[05b635c]: https://git.tirsystem.com/TirSystem/github-action/commit/05b635c1b3d79390c794e62e781595fbe5f1a4ea
@@ -1,46 +0,0 @@
# Review Record: MIL-006 (pilot results)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-049 |
| CrossReference | [MIL-006], [QC-MIL-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-11 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [d575f27] |
---
## Artifact Under Review
- Instance reviewed: [MIL-006] with its amended criterion 1 and its new Verification results section
- Checklist used: [QC-MIL-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | A concrete deliverable is defined for every gate | Pass | The scoped workflow, the opt-in rule, tests, guides and a pilot exist; run 629 is the proof. |
| 2 | Explicit Go/No-Go criteria are stated for each gate | Pass | Finding fixed during this review: criterion 1 demanded a live run in a repository without the marker, which the instance cannot produce (a scoped workflow is not dispatchable and runs only on a push that changes `wiki/**`). The criterion now names the offline tests and the trigger rule as its evidence. This is weaker than a live run, which the results state. |
| 3 | Dependencies on other milestones are explicitly mapped | Pass | Unchanged (MIL-005, MIL-002). |
| 4 | Each milestone is traceable to a Business Case objective or KPI | Pass | O2 and O3, unchanged. |
| 5 | Milestone owner and approving reviewer are identified | Pass | Owner S05, approving reviewer S01, unchanged. |
| 6 | Milestone has a defined target date consistent with project constraints | Pass | 2026-12-26; the criteria are met on 2026-10-11. |
## Overall Verdict
Go - all six criteria pass; the one finding (criterion 2) was fixed during the review, and the milestone's six Go/No-Go criteria are met, criterion 1 on the weaker evidence stated. S01 gave the Go in chat on 2026-10-11, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Observe the first push that changes `wiki/**` in a repository without the marker, if one occurs, and record that the run only logs that publishing is not enabled | S05 | when it occurs |
---
[MIL-006]: ../../milestones/mil-006-shared-wiki-publishing.md
[QC-MIL-001]: ../../../framework/qc/qc-milestones-gateways.md
[d575f27]: https://git.tirsystem.com/TirSystem/github-action/commit/d575f272fcb044e3165951013464177a6e659ea6
@@ -1,46 +0,0 @@
# Review Record: MIL-005 (translations accepted)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-050 |
| CrossReference | [MIL-005], [QC-MIL-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-11 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [ead3d98] |
---
## Artifact Under Review
- Instance reviewed: [MIL-005] with its amended criterion 4 and its new Verification results section
- Checklist used: [QC-MIL-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | A concrete deliverable is defined for every gate | Pass | The wiki in three languages, generated and published from `wiki/`; 21 pages are published. |
| 2 | Explicit Go/No-Go criteria are stated for each gate | Pass | Finding fixed during this review: criterion 4 demanded a native reader, which the project does not have. It now allows acceptance by S01 as the stand-in of ADR-0002 and says that the lack of a native reader is stated. This is weaker than a native review, and the results say so. |
| 3 | Dependencies on other milestones are explicitly mapped | Pass | Unchanged (MIL-002). |
| 4 | Each milestone is traceable to a Business Case objective or KPI | Pass | Unchanged. |
| 5 | Milestone owner and approving reviewer are identified | Pass | Owner S05, approving reviewer S01, unchanged. |
| 6 | Milestone has a defined target date consistent with project constraints | Pass | 2026-12-12; the criteria are met on 2026-10-11. |
## Overall Verdict
Go - all six criteria pass; the one finding (criterion 2) was fixed during the review. The Danish and Bahasa Malaysia pages are accepted by S01 on 2026-10-11 without a native reader, standing in for the other reviewers as ADR-0002 records; there is no independent reader. Bahasa Malaysia is the weaker draft (`docs/wiki-translation-review.md`).
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Have a native reader of each language use `docs/wiki-translation-review.md` when one is available; fix the findings through a pull request | S05 | when a reader is available |
---
[MIL-005]: ../../milestones/mil-005-wiki-and-translations.md
[QC-MIL-001]: ../../../framework/qc/qc-milestones-gateways.md
[ead3d98]: https://git.tirsystem.com/TirSystem/github-action/commit/ead3d98d73fcab95fd57b0eb005a02aff9983256
@@ -1,51 +0,0 @@
# Review Record: ADR-0005 (tools-ref)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-051 |
| CrossReference | [ADR-0005], [QC-ADR-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-11 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [670f0ac] |
---
## Artifact Under Review
- Instance reviewed: [ADR-0005] after the addition of the input `tools-ref`
- Checklist used: [QC-ADR-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The ID (`ADR-NNNN`, 4-digit) matches the filename number and is unique and sequential | Pass | Unchanged. |
| 2 | Context states the problem, the forces (cost, risk, constraints) and the options evaluated | Pass | Unchanged; the move of the shell steps to a script file is an implementation of the decided contract, not a new option. |
| 3 | At least two options were considered, or the absence of alternatives is justified | Pass | Unchanged. |
| 4 | Decision is stated in one or two unhedged sentences and matches one of the evaluated options | Pass | The decision sentence names the new optional input. |
| 5 | Consequences list both Positive and Negative outcomes | Pass | Finding noted for the next revision, not a blocker: a reusable workflow cannot learn the ref it was called at (the context fields `workflow_ref`, `workflow_sha`, `job_workflow_sha` and `action_ref` are empty on this instance, verified on 2026-10-11), so the script ref is an input and a call at an exact tag is pinned completely only with `tools-ref` set to the same tag. |
| 6 | Quality-attribute impacts (performance, security, portability, etc.) are named where the decision affects them | Pass | Maintainability gains (a script of this repository, linted and tested as a file); the pin limitation above is the reliability cost. |
| 7 | Affected Artifacts are listed as links, and each is also in CrossReference | Pass | Unchanged. |
| 8 | Status changes are recorded as new Version History rows with a Change summary and Commit link; retained rows are never rewritten | Pass | The earlier row is kept with status Deprecated and a new row added. |
| 9 | A superseded or deprecated ADR names its successor, and the successor links back | N-A | Nothing is superseded. |
| 10 | Written in business or technical language of the domain, with no unexplained abbreviations | Pass | Unchanged. |
| 11 | Status is one of `Proposed`, `Accepted`, `Rejected`, `Deprecated` or `Superseded by ADR-NNNN`, and every Version History row uses only these | Pass | Deprecated and Accepted. |
## Overall Verdict
Go - all applicable criteria pass. Adding an optional input is a minor change under ADR-0006. S01 gave the Go in chat on 2026-10-11, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Run a pinned consumer (`@v1.0.1` with `tools-ref: v1.0.1`) after the next release to confirm the complete pin | S05 | next release |
---
[ADR-0005]: ../../adr/adr-0005-quality-check-contract.md
[QC-ADR-001]: ../../../framework/qc/qc-adr.md
[670f0ac]: https://git.tirsystem.com/TirSystem/github-action/commit/670f0ac469043bb166c84290c0dbf62b4908e3cc
-47
View File
@@ -1,47 +0,0 @@
# Review Record: MIL-007
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-052 |
| CrossReference | [MIL-007], [QC-MIL-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-11 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [e3ad1fa] |
---
## Artifact Under Review
- Instance reviewed: [MIL-007]
- Checklist used: [QC-MIL-001]
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | A concrete deliverable is defined for every gate | Pass | Two reusable workflows with pinned tools, guides and wiki pages in three languages, a use in another repository and a release. |
| 2 | Explicit Go/No-Go criteria are stated for each gate | Pass | Six criteria, each with a Go and a No-Go: runner verified, ADR accepted, seeded failure visible, a run in another repository, no embedded script, released. |
| 3 | Dependencies on other milestones are explicitly mapped | Pass | MIL-003 for the contract and mechanism, MIL-004 for the release; both are closed. |
| 4 | Each milestone is traceable to a Business Case objective or KPI | Pass | O4, and US-001.09 and US-001.10 which the milestone extends. |
| 5 | Milestone owner and approving reviewer are identified | Pass | Owner S05, approving reviewer S01. |
| 6 | Milestone has a defined target date consistent with project constraints | Pass | 2027-01-16, after the last decision of the plan; the Business Case sets no deadline. |
## Overall Verdict
Go - all six criteria pass; no findings. The plan-first order holds inside the milestone: the use case and stories (task 1), the runner check (task 2) and the contract ADR (task 3) come before any workflow (tasks 4 and 5). The decision between one workflow and one per language is left to the ADR and is not made here. S01 gave the Go in chat on 2026-10-11, standing in for the other reviewers as ADR-0002 records; there is no independent reader.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Run `sync-project.sh --apply` so that the milestone and its issues exist | S05 | 2026-10-11 |
| Decide in the ADR (task 3) one workflow or one per language, and whether C is included | S01 | before tasks 4 and 5 |
---
[MIL-007]: ../../milestones/mil-007-cpp-csharp-quality-checks.md
[QC-MIL-001]: ../../../framework/qc/qc-milestones-gateways.md
[e3ad1fa]: https://git.tirsystem.com/TirSystem/github-action/commit/e3ad1fa7e7eef57a6793a479edb41ac6fd2db688

Some files were not shown because too many files have changed in this diff Show More