Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/badges/conformance.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 23 additions & 9 deletions .github/conformance.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
standard_version: "1.6.0"
assessed_on: "2026-08-31"
state: "Healthy"
standard_version: "1.21.0"
assessed_on: "2026-09-22"
state: "Needs work"
evidence: "docs/self-assessment.md"

criteria:
Expand All @@ -17,6 +17,9 @@ criteria:
B11: pass
B12: pass
B13: pass
B14: pass
B15: na
B16: pass
P01: pass
P02: pass
P03: pass
Expand All @@ -26,6 +29,10 @@ criteria:
P07: pass
P08: pass
P09: pass
P10: pass
P11: pass
P12: pass
P13: pass
S01: pass
S02: pass
S03: pass
Expand All @@ -36,22 +43,28 @@ criteria:
S08: pass
S09: pass
S10: pass
S11: pass
S12: pass
S13: na
D01: na
D02: na
D03: na
D04: na
D05: na
D06: na
R01: pass
R01: partial
R02: pass
R03: pass
R04: pass
R05: pass
R06: pass
R07: pass
R08: pass
R09: pass
I01: pass
I02: pass
I03: pass
I04: pass
I02: fail
I03: fail
I04: partial
I05: pass
I06: pass
T01: na
Expand All @@ -63,10 +76,11 @@ criteria:
W02: pass
W03: pass
W04: pass
W05: pass
W06: pass
W05: na
W06: na
W07: pass
W08: pass
W09: pass
G01: pass
G02: pass
G03: pass
Expand Down
100 changes: 79 additions & 21 deletions docs/self-assessment.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,28 @@ Per-criterion evidence for [`.github/conformance.yml`](../.github/conformance.ym

| Field | Value |
|---|---|
| Standard | [Repository Quality Standard](https://github.com/trsdn/.github/blob/v1.6.0/docs/repository-quality-standard.md) **v1.6.0** |
| Assessed on | 2026-08-31 |
| State | **Healthy** |
| Results | 74 pass · 0 partial · 0 fail · 19 n/a |
| Standard | [Repository Quality Standard](https://github.com/trsdn/.github/blob/v1.21.0/docs/repository-quality-standard.md) **v1.21.0** |
| Assessed on | 2026-09-22 |
| State | **Needs work** |
| Results | 80 pass · 2 partial · 2 fail · 23 n/a |

Remediation was tracked in [#32](https://github.com/trsdn/PtionsPlus/issues/32),
which followed the first assessment in
[#29](https://github.com/trsdn/PtionsPlus/issues/29).

Reassessed against v1.6.0 on 2026-08-31. The only change is `P08`, which moved
from `partial` to `pass` because the standard's badge rule changed, not because
anything in this repository was relaxed. See
[Badge hosting](#badge-hosting-p08) for the reasoning.
Reassessed against v1.21.0 on 2026-09-22, jumping from v1.6.0. Fourteen
criteria are new since v1.6.0 (`B14`-`B16`, `P10`-`P13`, `R07`-`R09`,
`S11`-`S13`, `W09`); this assessment reads every criterion in the current
standard, not a diff. Three of the new ones needed a change, made in the same
pull request as this record: `B14` (a credential-exposure statement was
missing from `AGENTS.md`), `R08` (README did not tell a consumer what to check
or how), and `W09` (the site carried the vendored design language's default
palette with no project-specific override). `I02` and `I03` newly fail, not
because anything regressed, but because the latest published release,
`v1.2.0`, predates the commit that added the product-identity metadata these
criteria ask for; see [Product Identity](#product-identity). `P08` stays at
`pass` for the reason the v1.6.0 reassessment recorded; see
[Badge hosting](#badge-hosting-p08).

## Profiles

Expand Down Expand Up @@ -49,6 +58,9 @@ Not applicable, with rationale:
| B11 | pass | This record and [`.github/conformance.yml`](../.github/conformance.yml), validated in CI by [`.github/workflows/conformance.yml`](../.github/workflows/conformance.yml). |
| B12 | pass | `trsdn-standard` topic. |
| B13 | pass | `AGENTS.md` carries a documentation-boundaries table naming one home per fact. Commands and architecture moved out of the README into `AGENTS.md`; `CLAUDE.md` and `.github/copilot-instructions.md` are pointers, enforced by `scripts/check-documentation.sh`. |
| B14 | pass | `AGENTS.md` **Secrets and signing** names each of the five release secrets (`MACOS_CERTIFICATE`, `MACOS_CERTIFICATE_PWD`, `APPLE_ID`, `APPLE_TEAM_ID`, `APPLE_APP_PASSWORD`) and states what replaces each one and where, added in this reassessment. |
| B15 | na | README **Requirements** and `AGENTS.md` state Ptions+ has no third-party dependencies; nothing is redistributed. |
| B16 | pass | `gh api repos/trsdn/PtionsPlus/branches/main/protection` shows both force pushes and deletion blocked. |

## Public

Expand All @@ -63,6 +75,10 @@ Not applicable, with rationale:
| P07 | pass | Description, 14 topics, and a maintained homepage. |
| P08 | pass | Required order — licence, platform, CI, release, conformance — with every badge linking to what it reports. CI uses GitHub's own workflow badge endpoint, the first-party live image the standard names. Conformance is a committed image, regenerated from the record by a repository event. Licence, platform, and release have no first-party image source and are served live by `img.shields.io`, which v1.6.0 records as a `Pass`. The hardcoded `Swift 5.9` badge this criterion exists to prevent was removed in the previous assessment. Reasoning in [Badge hosting](#badge-hosting-p08). |
| P09 | pass | [`.github/stats/repo-card.svg`](../.github/stats/repo-card.svg) and `repo-card-dark.svg`, generated by [`repo-stats.yml`](../.github/workflows/repo-stats.yml) on a weekly schedule, committed, selected with a `<picture>` element, and self-contained — the only `url()` in either file is an internal filter reference. |
| P10 | pass | [`bug.yml`](../.github/ISSUE_TEMPLATE/bug.yml) collects expected behaviour, actual behaviour, numbered reproduction steps, the Ptions+ version, and the macOS version, plus mouse model and vendor-software fields specific to this product's failure modes. |
| P11 | pass | Inherited [`pull_request_template.md`](https://github.com/trsdn/.github/blob/main/.github/pull_request_template.md) covers what the change does, how it was validated, its risk and compatibility impact, and the related issue. |
| P12 | pass | `gh api repos/trsdn/PtionsPlus/vulnerability-alerts` and `automated-security-fixes` both enabled. |
| P13 | pass | CodeQL default setup, `state: active`, read from `gh api repos/trsdn/PtionsPlus/code-scanning/default-setup`. |

## Software

Expand All @@ -78,28 +94,55 @@ Not applicable, with rationale:
| S08 | pass | Dependabot covers GitHub Actions weekly; Dependabot security updates enabled; `@trsdn` owns triage through `CODEOWNERS`. |
| S09 | pass | Two required checks protect `main`; both exist and pass. |
| S10 | pass | `AGENTS.md` documents the architecture, the runtime invariant, and the product constraints; the README documents the event flow. |
| S11 | pass | Every workflow (`ci.yml`, `conformance.yml`, `release.yml`, `repo-stats.yml`) declares a `permissions` block, at the top level or on every job, no broader than the job's work. |
| S12 | pass | All 15 `uses:` references in the four workflows are pinned to a commit SHA (third-party actions) or reference a workflow within the account, satisfying the graduated table. |
| S13 | na | No workflow uses `pull_request_target` or `workflow_run`. |

## Package And Release

| ID | Result | Evidence |
|---|---|---|
| R01 | pass | `Info.plist` and the build settings agree with the repository metadata; verified by `scripts/verify-version.sh`. |
| R01 | partial | Name (`CFBundleName` `Ptions+`) and version (`CFBundleShortVersionString` `1.2.0`) are present in the latest published artifact and agree with the repository. Licence and repository URL are not: see `I02`/`I03` below, the same finding. `scripts/verify-version.sh` will enforce all of it starting with the next release. |
| R02 | pass | README **Versioning and compatibility** states semantic versioning and what each bump means for the `config.json` schema, including that downgrade is unsupported across a major. |
| R03 | pass | A `v*` tag runs [`release.yml`](../.github/workflows/release.yml), which builds, signs, notarises, staples, and uploads a ZIP, a DMG, and a SHA-256 file. |
| R04 | pass | `scripts/verify-version.sh --tag` rejects a tag that does not match `MARKETING_VERSION`. |
| R05 | pass | `scripts/verify-release-artifacts.sh` rebuilds the ZIP and DMG from the stapled app and verifies them before upload; the release workflow reruns the full CI suite against the tagged commit first. |
| R05 | pass | `scripts/verify-release-artifacts.sh` rebuilds the ZIP and DMG from the stapled app and verifies them before upload; the release workflow reruns the full CI suite against the tagged commit first. This reassessment additionally downloaded the published `v1.2.0` `Ptions+.dmg` and `Ptions+.zip`, checked the DMG against its published `.sha256`, and ran `codesign --verify --deep --strict`, `xcrun stapler validate`, and `spctl --assess --type execute` against the unpacked app: all passed (`accepted`, `source=Notarized Developer ID`). Neither artifact was launched. |
| R06 | pass | The release workflow gates on `scripts/changelog.sh release-notes` and publishes the `CHANGELOG.md` section of the tagged version as the release body, so a release cannot ship without described changes. |
| R07 | pass | [`release.yml`](../.github/workflows/release.yml) `Verify changelog and build release notes` reads `CHANGELOG.md` at the tagged commit and fails the release when the tag's section is missing or empty; the same extracted text becomes the published release body, so the two cannot disagree. |
| R08 | pass | README **Install** now states the mechanism (Developer ID signature plus Apple notarisation) and gives the two commands a consumer runs to check it, `codesign --verify` and `spctl --assess`, added in this reassessment. Verified directly against the `v1.2.0` artifact under `R05`. |
| R09 | pass | Secret scan: GitHub secret scanning is enabled and `gh api repos/trsdn/PtionsPlus/secret-scanning/alerts?state=open` returns none. Dependency check: `gh api repos/trsdn/PtionsPlus/dependabot/alerts?state=open` returns none, and Dependabot covers the only third-party surface (GitHub Actions); the app itself has no dependencies. |

## Product Identity

**Finding.** `PtionsPlus/Info.plist` gained `TRSRepositoryURL`, `TRSIssuesURL`, and
`TRSLicenseIdentifier` in commit `a5e9a25` (2026-08-31 13:22 CEST). The latest
published release, `v1.2.0`, was tagged at 11:25 CEST the same day — before that
commit — and `a5e9a25` is not an ancestor of the `v1.2.0` tag. This assessment
downloaded the `v1.2.0` `Ptions+.zip`, unpacked it without launching it, and read
`Contents/Info.plist` with `plutil -p`: it carries `CFBundleName`,
`CFBundleShortVersionString` (`1.2.0`), `CFBundleIdentifier`, and
`NSHumanReadableCopyright`, but none of the three `TRS*` keys, and
`Contents/Resources/` carries no bundled licence text. A local `Debug` build from
the current `main` (`scripts/validate.sh --fast`, `xcb -configuration Debug
build`) was checked the same way and does carry all three keys, confirming the
Info.plist template and build settings work; nothing is broken. This is a
released-version gap, not a broken pipeline: `scripts/verify-version.sh --app`
already fails a release whose archived app is missing any of these keys, so the
next tagged release will carry them or fail its own gate. Per
[Product Identity](https://github.com/trsdn/.github/blob/v1.21.0/docs/repository-quality-standard.md#product-identity),
"a value that appears only in source is not evidence that the artifact carries
it," so `I02` and `I03` are recorded against the artifact as published, not the
source. **Remediation is cutting a new release**, which is a maintainer
decision this assessment does not make.

| ID | Result | Evidence |
|---|---|---|
| I01 | pass | `CFBundleShortVersionString` `1.2.0` and `CFBundleVersion` `7` in the built bundle, from `MARKETING_VERSION` and `CURRENT_PROJECT_VERSION`. |
| I02 | pass | `TRSRepositoryURL` and `TRSIssuesURL` in `Info.plist`, confirmed present in the built bundle with `plutil -p`. |
| I03 | pass | `NSHumanReadableCopyright` set from the build settings, `TRSLicenseIdentifier` `MIT`, and the full `LICENSE` text bundled at `Contents/Resources/LICENSE`. |
| I04 | pass | About window, reachable from the menu bar dropdown, showing version and build and linking to the repository and the issue tracker. [`AboutView.swift`](../PtionsPlus/Views/AboutView.swift) reads every value from the bundle through [`ProductIdentity.swift`](../PtionsPlus/Utilities/ProductIdentity.swift) rather than hardcoding it. |
| I05 | pass | `AppIcon.icns` embedded in the bundle; the same mark is used on the published site and as the favicon. |
| I06 | pass | `scripts/bump-version.sh` owns the version in the project file and every version marker on the site. `scripts/verify-version.sh` fails when the built bundle is missing any identity key, when a value drifts from the source plist, when the licence is not bundled, or — in CI, where `GITHUB_REPOSITORY` is set — when the embedded repository and issue URLs disagree with the repository the workflow is actually running in. All four failure paths were exercised with negative tests. |
| I01 | pass | `CFBundleShortVersionString` `1.2.0` in the `v1.2.0` artifact, read directly, matching the tag. |
| I02 | fail | No `TRSRepositoryURL` or `TRSIssuesURL`, or any equivalent key, in the `v1.2.0` artifact's `Info.plist`. Present in source since `a5e9a25`, which postdates the tag. See the finding above. |
| I03 | fail | No `TRSLicenseIdentifier` or `NSHumanReadableCopyright`-equivalent licence identifier, and no bundled licence text, in the `v1.2.0` artifact. Present in source since `a5e9a25`, which postdates the tag. See the finding above. |
| I04 | partial | [`AboutView.swift`](../PtionsPlus/Views/AboutView.swift) reads every value from the bundle through [`ProductIdentity.swift`](../PtionsPlus/Utilities/ProductIdentity.swift) rather than hardcoding it, so the About window is correctly wired in source. But `ProductIdentity.swift` reads `TRSRepositoryURL`/`TRSIssuesURL` from the bundle, which the shipped `v1.2.0` binary does not carry, so the About window in the app a user actually downloads today shows no repository or issue-tracker link until the next release. Not run; read from source, per `I04`'s own rule for an interface the assessor does not operate. |
| I05 | pass | `AppIcon.icns` embedded in the `v1.2.0` bundle (confirmed present in `Contents/Resources/`); the same mark is used on the published site and as the favicon. |
| I06 | pass | `scripts/bump-version.sh` owns the version in the project file and every version marker on the site. `scripts/verify-version.sh --app` fails a release whose archived app is missing any identity key, drifts from the source plist, ships without a bundled licence, or — in CI, where `GITHUB_REPOSITORY` is set — disagrees with the repository the workflow is running in. The one value the current artifact does carry, the version, is correctly build-derived; the mechanism for the rest is in place and gates the next release, which is what `I06` asks for. |

## Published Site

Expand All @@ -111,10 +154,11 @@ Published at <https://trsdn.github.io/PtionsPlus/> from `main` at `/docs`.
| W02 | pass | Repository homepage points at the site; the site footer links to the repository, licence, security policy, support, issues, and changelog. |
| W03 | pass | The landing view opens with the name, a one-sentence statement of what Ptions+ is, the maintained status, the version, and the download action, all above the fold. |
| W04 | pass | Name and one-sentence statement; status and version; screenshot; download path; the `Y01` disclosure in its own Privacy section; links to repository, licence, security policy, and support; and a `Page last reviewed` date, which `scripts/bump-version.sh` refreshes on every release. |
| W05 | pass | Instrument Workshop, vendored into [`docs/assets/`](../docs/assets/), replacing roughly 1,050 lines of bespoke CSS. |
| W06 | pass | Version **v1.5.0** recorded in [`docs/assets/VENDORED.md`](../docs/assets/VENDORED.md) and in the header of each vendored file, with the re-vendoring procedure and a "no deviations" statement. |
| W07 | pass | The Google Fonts `preconnect` hints and stylesheet were removed and IBM Plex is self-hosted from `docs/assets/fonts/`. A network review of the rendered page recorded 11 requests, all same-origin. `scripts/check-documentation.sh` now fails the build if any resource-loading attribute or vendored stylesheet reintroduces a remote host; the guard was confirmed with a negative test. |
| W05 | na | Retired 2026-09-17 (standard 1.12.0); see [decision 0013](https://github.com/trsdn/.github/blob/v1.21.0/docs/decisions/0013-sites-are-designed-not-templated.md). |
| W06 | na | Retired 2026-09-17 (standard 1.12.0); see [decision 0013](https://github.com/trsdn/.github/blob/v1.21.0/docs/decisions/0013-sites-are-designed-not-templated.md). |
| W07 | pass | The Google Fonts `preconnect` hints and stylesheet were removed and IBM Plex is self-hosted from `docs/assets/fonts/`. A network review of the rendered page recorded 11 requests, all same-origin, plus the new `assets/site.css`, also same-origin. `scripts/check-documentation.sh` now fails the build if any resource-loading attribute or vendored stylesheet reintroduces a remote host; the guard was confirmed with a negative test. |
| W08 | pass | Build-from-source instructions and the contributor-facing material were removed from the site, which now links to the repository for depth. |
| W09 | pass | Before this reassessment, the site loaded the vendored Instrument Workshop tokens unmodified — `docs/assets/core.tokens.css`'s `--identity` accent, `#29483c`, matched the design system's own default. [`docs/assets/site.css`](../docs/assets/site.css), added in this reassessment and loaded after the vendored files, overrides `--identity`/`--identity-ink` to a project-specific slate blue for light mode and its dark-mode counterpart, both checked at over 8:1 contrast against their background (WCAG requires 4.5:1). Recorded as a deviation in [`docs/assets/VENDORED.md`](../docs/assets/VENDORED.md). |

## Agent Readiness

Expand Down Expand Up @@ -212,5 +256,19 @@ a defect.

## Open gaps

None. Every applicable criterion is at `pass`, and the 19 recorded `na` results
each carry a rationale above.
Three, all from [Product Identity](#product-identity), and all with the same
cause and the same remediation:

- `R01` (partial), `I02` (fail), `I03` (fail): the licence identifier and the
repository/issue URLs are missing from the `v1.2.0` artifact, because the
source commit that added them postdates that tag.
- `I04` (partial): the About window is correctly wired to read those same
values, so it inherits the gap in the currently shipped build.

**Remediation is cutting a new release.** `scripts/verify-version.sh --app`
already gates the next one on all four values being present and agreeing with
source, so the fix is publishing, not further code change. That is a
maintainer decision this assessment does not make.

The 23 recorded `na` results each carry a rationale above, and every other
applicable criterion is at `pass`.
Loading