Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
a0b06a0
ci: restore the OpenSpec Sync caller on development (#284)
rubenvdlinde Aug 21, 2026
51b7837
chore(deps): clear the critical and high audit findings (#310)
rubenvdlinde Aug 21, 2026
83482c7
chore(deps): refresh the shared Conduction locks (#312)
rubenvdlinde Aug 21, 2026
2a29f47
fix(ci): give dispatched runs their own concurrency lane (#315)
rubenvdlinde Aug 21, 2026
139c8f6
chore(quality): migrate to PHPStan 2 (and hydra-gates 1.8.2) (#313)
rubenvdlinde Aug 21, 2026
e14ad0d
chore(deps): refresh the shared Conduction locks (#327)
rubenvdlinde Aug 22, 2026
887aa37
test(l10n): ratchet the untranslated schema strings (#329)
rubenvdlinde Aug 23, 2026
605b6e8
chore(deps): refresh the shared Conduction locks (#331)
rubenvdlinde Aug 24, 2026
ea693e4
chore(release): 1.0.13-unstable.20260824072359 [skip ci] (#332)
github-actions[bot] Aug 24, 2026
e5e6227
fix: repoint stale Codeberg links to GitHub (#333)
rubenvdlinde Aug 24, 2026
03c0698
feat: port issue templates to GitHub Issue Forms (#335)
rubenvdlinde Aug 24, 2026
66e19bf
chore(ci): remove dead Forgejo/Codeberg CI configuration (#337)
rubenvdlinde Aug 24, 2026
5ccf6b3
chore(release): 1.0.13-unstable.20260824210826 [skip ci] (#338)
github-actions[bot] Aug 25, 2026
d66ec1e
ci(quality): give every event its own concurrency lane, not just main…
rubenvdlinde Aug 25, 2026
5c7509d
chore(release): 1.0.13-unstable.20260825094451 [skip ci] (#340)
github-actions[bot] Aug 25, 2026
991f502
chore: ignore agent/test scratch and untrack generated files (#341)
rubenvdlinde Aug 26, 2026
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
25 changes: 0 additions & 25 deletions .forgejo/workflows/documentation.yml

This file was deleted.

25 changes: 0 additions & 25 deletions .forgejo/workflows/l10n-parity.yml

This file was deleted.

70 changes: 0 additions & 70 deletions .forgejo/workflows/pre-merge-check-strict.yaml

This file was deleted.

13 changes: 0 additions & 13 deletions .forgejo/workflows/release-beta.yml

This file was deleted.

17 changes: 0 additions & 17 deletions .forgejo/workflows/release-stable.yml

This file was deleted.

49 changes: 47 additions & 2 deletions .github/workflows/code-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,47 @@ on:
# Proven in openconnector#1158: its first-ever completed `development` push run
# (31048998594) executed Coverage Baseline Check, SBOM and Features Extract.
concurrency:
group: quality-${{ github.head_ref || github.ref_name }}${{ (github.event_name == 'push' && (github.ref_name == 'main' || github.ref_name == 'development')) && '-push' || '' }}
# SUFFIXED BY EVENT NAME, not just by `-push`.
#
# The previous expression gave a push on `development` its own lane
# (`-push`) but left EVERYTHING ELSE sharing `quality-development` — and
# that is not a quiet lane: `Sync to Beta` keeps a PR open whose head_ref
# IS `development`, so its run computes the same group and is re-triggered
# on every merge.
#
# A `workflow_dispatch` therefore shared a group with that PR and was
# cancelled by it. Measured on shillinq 2026-08-21: dispatch 32487948678
# cancelled by pull_request run 32490160836 (head_branch `development`).
# A run someone deliberately asked for could essentially never complete.
#
# That reaches past ad-hoc verification: the fleet gate-drift sweep
# (.github#523) dispatches per app with `--ref development`, because
# `schedule:` cannot choose a branch. Under the old group those runs are
# cancelled and report neither pass nor fail — and a routine that produces
# no verdict is indistinguishable from one that never ran.
#
# This is hermiq's form, already live there. Pull requests keep the bare
# group (so a PR still supersedes its own earlier run); push, dispatch and
# schedule each get their own lane.
#
# THE BRANCH RESTRICTION IS GONE, because it contradicted the sentence above.
#
# The suffix used to apply only when `ref_name` was `main` or `development`,
# so on every OTHER branch push and pull_request computed the SAME group —
# and `cancel-in-progress` made them kill each other. That became reachable
# when the push allow-list widened on 2026-08-14 to include `feat/**`,
# `fix/**`, `perf/**`, `refactor/**` and `chore/**`: those branches now get
# both a push run and a pull_request run for one commit.
#
# `quality / Quality Report` is a `needs:`-gated aggregator and reports
# FAILURE when its dependencies are CANCELLED, so the collision shows up as a
# red gate on a PR that was never actually evaluated — and re-running collides
# the same way. Measured on openregister#2821: a push run left queued and a
# pull_request run cancelled, 18 seconds apart, on one commit.
#
# A branch name is not a unique lane when two event types can each produce a
# run for it, so the event is now always part of the key.
group: quality-${{ github.head_ref || github.ref_name }}${{ github.event_name != 'pull_request' && format('-{0}', github.event_name) || '' }}
cancel-in-progress: true

# Permission CEILING for the called quality pipeline. GitHub statically
Expand Down Expand Up @@ -216,7 +256,12 @@ jobs:
# Measured on this tree before enabling: PASSES, 237 of 279 tracked
# frontend files in scope (l10n/ and docs/ excluded via .prettierignore /
# .gitignore, which prettier 3 also reads).
frontend-checks: '["check:manifest", "format"]'
# `check:schema-l10n` is a RATCHET, not a gate. Every string inside a form
# comes from the schema and is a key in THIS app's catalogue; an absent key
# renders the English source inside an otherwise translated form, silently.
# The fleet had 30,459 such strings, so this records the current count and
# fails only when it GROWS — burning it down stays an ordinary PR.
frontend-checks: '["check:manifest", "format", "check:schema-l10n"]'

# ── Coverage ratchet ─────────────────────────────────────────────────
# `enable-coverage-guard` defaults to FALSE, which is why both
Expand Down
51 changes: 51 additions & 0 deletions .github/workflows/openspec-sync.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: OpenSpec Sync

# RESTORED, on evidence that the condition which justified dropping it is gone.
#
# This caller was removed from `development` in #42 on 2026-08-04 for a good
# reason: every run in its history was a startup failure reporting `jobs=0`.
# That is the signature of a reusable workflow that never resolved — no log, no
# step, no verdict, just a permanently red branch. As #42 put it, a
# permanently-red workflow is worse than an absent one, because the next
# genuine failure lands on an already-red branch and cannot be told apart from
# the standing noise. That argument was correct.
#
# What has changed since:
#
# 1. The unresolvable ref was FIXED — on `main`, by 9a695ae on 2026-08-03
# ("fix all 8 shared-workflow callers on main (wrong org)"), one day
# BEFORE #42 dropped this file from development. The fix and the removal
# crossed: `main` got the repair, `development` got the deletion, and
# because main is 345 commits behind development the two never met.
#
# 2. It has now been observed working. Dispatched against main on
# 2026-08-21, this exact caller ran to success and created 12 OpenSpec
# issues — the first non-zero result this workflow has ever produced.
#
# On the PROJECT_TOKEN: #42 and openregister#2111 both attributed the failure
# to an expired project-board PAT. That is not what blocks it here — launchpad
# has no PROJECT_TOKEN secret at all, and the 2026-08-21 run succeeded anyway.
# The token is for the project BOARD; the issues themselves are written with
# the workflow's own github.token. The line below is kept so the board sync
# starts working by itself if a token is ever added, and is harmless while the
# secret is absent.
#
# Why it belongs on `development` and not only on `main`: the push trigger
# below watches `development`, and GitHub reads the workflow file from the
# branch being pushed. With the file only on main, that trigger could never
# fire — which is why the sync had to be kicked by hand and why only main's 16
# changes were covered while development's 28 went unsynced.

on:
push:
branches: [development]
paths: ['openspec/**']
workflow_dispatch:

jobs:
sync:
uses: ConductionNL/.github/.github/workflows/openspec-sync.yml@main
with:
app-name: launchpad
secrets:
PROJECT_TOKEN: ${{ secrets.PROJECT_TOKEN }}
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,9 @@ bom-npm.cdx.json
# Local MCP server configuration — carries API keys, must never be committed.
# A live n8n API key reached the tip tree of 37 local branches before this was added.
.mcp.json

# Agent/test scratch and tool caches — generated, never source.
# Added by the 2026-08-25 fleet hygiene sweep (ADR-100 Decision 2).
.stale/
/.e2e-state/
.phpunit.cache
20 changes: 10 additions & 10 deletions appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,25 +52,25 @@ Ideaal voor organisaties die consistente, samengestelde dashboards willen voor h

Vrij en open source onder de EUPL-1.2-licentie.
]]></description>
<version>1.0.13-unstable.20260820060123</version>
<version>1.0.13-unstable.20260825094451</version>
<licence>EUPL-1.2</licence>
<author mail="info@conduction.nl" homepage="https://www.conduction.nl/">Conduction</author>
<namespace>LaunchPad</namespace>
<documentation>
<user>https://codeberg.org/Conduction/launchpad</user>
<admin>https://codeberg.org/Conduction/launchpad</admin>
<developer>https://codeberg.org/Conduction/launchpad</developer>
<user>https://github.com/ConductionNL/launchpad</user>
<admin>https://github.com/ConductionNL/launchpad</admin>
<developer>https://github.com/ConductionNL/launchpad</developer>
</documentation>
<category>customization</category>
<category>organization</category>
<category>dashboard</category>
<website>https://codeberg.org/Conduction/launchpad</website>
<bugs>https://codeberg.org/Conduction/launchpad/issues</bugs>
<repository>https://codeberg.org/Conduction/launchpad</repository>
<website>https://github.com/ConductionNL/launchpad</website>
<bugs>https://github.com/ConductionNL/launchpad/issues</bugs>
<repository>https://github.com/ConductionNL/launchpad</repository>

<screenshot>https://codeberg.org/Conduction/launchpad/raw/branch/main/img/screenshot-dashboard.png</screenshot>
<screenshot>https://codeberg.org/Conduction/launchpad/raw/branch/main/img/screenshot-widgets.png</screenshot>
<screenshot>https://codeberg.org/Conduction/launchpad/raw/branch/main/img/screenshot-admin.png</screenshot>
<screenshot>https://raw.githubusercontent.com/ConductionNL/launchpad/main/img/screenshot-dashboard.png</screenshot>
<screenshot>https://raw.githubusercontent.com/ConductionNL/launchpad/main/img/screenshot-widgets.png</screenshot>
<screenshot>https://raw.githubusercontent.com/ConductionNL/launchpad/main/img/screenshot-admin.png</screenshot>

<!-- ADR: LaunchPad is an OR-free app (docs/architecture.md "Runtime-only
OR consumption policy"). It MUST boot and function fully on a
Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@
},
"require-dev": {
"conduction/coding-standard": "^1.0",
"conduction/hydra-gates": "^1.0",
"conduction/hydra-gates": "^1.8.2",
"cyclonedx/cyclonedx-php-composer": "^6.2",
"edgedesign/phpqa": "^1.27",
"nextcloud/ocp": "^34.0",
"phpcsstandards/phpcsextra": "^1.4",
"phpmd/phpmd": "^2.15",
"phpmetrics/phpmetrics": "^2.8",
"phpstan/phpstan": "^1.10",
"phpstan/phpstan": "^2.0",
"phpunit/phpunit": "^10",
"roave/security-advisories": "dev-latest",
"squizlabs/php_codesniffer": "^3.9",
Expand Down
Loading
Loading