intermediate commit
Some checks failed
Dependency Audit / dependency-audit (push) Failing after 16s
Security Audit / security-audit (push) Failing after 11s

This commit is contained in:
2026-07-14 13:32:09 +02:00
parent dd796b4d3c
commit 05ae81d641
58 changed files with 7526 additions and 66 deletions

View File

@@ -0,0 +1,57 @@
# GovOPlaN Frontend Layout Principles
GovOPlaN modules should choose their page layout by the kind of work the user is
doing, not by the repository that owns the feature.
## Structured Data Directories
Use a full-available-space workspace for structured data directories: files,
addresses, calendars, records, mailboxes, document stores, and similar domains
where the primary task is browsing, selecting, filtering, inspecting, and acting
on related objects.
Principles:
- The module route should use the full available content area.
- Do not add a separate page heading row above the main workspace.
- Prefer persistent navigation panes, such as tree panels, source panels, folder
panels, calendar list panels, or mailbox folder panels.
- Keep collection navigation and collection-level actions close to the relevant
pane header.
- Use bounded widths for navigation/list panes and let the main detail/content
pane take the remaining space.
- Keep filtering controls inside the pane they affect.
- Use overlays, toasts, or floating alerts for transient messages so the
workspace height does not change.
This pattern is appropriate when the user is working inside one coherent data
domain and needs spatial continuity.
## Workflow And Configuration Surfaces
Use the standard heading/menu/card visual language for workflow structures,
settings, administration, dashboards, and pages that collect essentially
unrelated areas.
Principles:
- A page heading and subnavigation are appropriate when the page explains a
task, workflow stage, or administrative area.
- Cards are appropriate for repeated independent panels, settings groups,
summaries, and dashboard widgets.
- Collapsible panels and segmented controls are appropriate when a dense
configuration area needs controlled disclosure.
- Avoid forcing workflow/configuration pages into a file-explorer style unless
the primary interaction is genuinely directory browsing.
This pattern is appropriate when the user is comparing or configuring separate
concerns rather than navigating one structured object space.
## Shared Components
Reusable layout components belong in `govoplan-core` WebUI. Modules may consume
shared components from core, but must not import another module's private UI
components directly.
When a module-specific component becomes generally useful, promote it to core
with a parameterized API before reusing it elsewhere.

83
docs/META_REPO_SCAN.md Normal file
View File

@@ -0,0 +1,83 @@
# Meta Repository Scan
Scan date: 2026-07-13.
This scan checked local repositories under `/mnt/DATA/git` listed in
`repositories.json`.
## Repository Inventory
`repositories.json` already lists every checked-out GovOPlaN repository.
Checked-out repositories not listed in `repositories.json`: none.
Repositories listed in `repositories.json` but not checked out locally: none.
The human-readable link index is `docs/REPOSITORY_INDEX.md`; the JSON file
remains the machine-readable source of truth.
## Meta-Owned Content
These items are correctly owned by the meta repository:
- `.gitea/workflows`: cross-repository CI and audit workflows.
- `.gitleaks.toml`: whole-workspace secret scan policy.
- `audit-reports`: whole-workspace audit output.
- `dev/postgres`: shared development PostgreSQL service.
- `dev/production-like`: production-like product validation composition.
- `tools/checks`: whole-product checks and audit launchers.
- `tools/gitea`: issue/wiki/label/backlog tooling.
- `tools/launch`: product launch entry points.
- `tools/release`: release catalog, lock, push, and release console tooling.
- `tools/repo`: repository bootstrap, status, and metadata tooling.
## Module-Local Content That Should Stay Local
These paths look operational, but they are tied to one module's protocol or
transport behavior and should stay in the owning repository for now:
- `govoplan-campaign/dev/mail-testbed`: mail transport testbed for campaign.
- `govoplan-files/dev/connectors`: WebDAV, Nextcloud, and SMB connector smoke
environment for files.
The meta repo can later wrap these with aggregate commands, but the test-bed
definitions should remain close to the module code unless they become a shared
product deployment profile.
## Generated Or Local-Only Content
These should not move to the meta repo; they should be ignored or cleaned:
- `__pycache__` directories under `tools/gitea` and module test beds.
- `.venv` and `.ruff_cache` directories.
- Populated `.env` files such as `govoplan-campaign/dev/mail-testbed/.env`.
## Repo-Local Workflow Files
Most module repositories have `.gitea/ISSUE_TEMPLATE` installed. These are
repo-local generated copies of the shared workflow templates and are fine to
keep in each repository.
Repositories currently missing a `.gitea` directory in the local checkout:
- `govoplan-dashboard`
- `govoplan-evaluation`
- `govoplan-poll`
- `govoplan-rest`
- `govoplan-soap`
If those repositories should use the shared issue templates, run the meta repo
installer from `govoplan/tools/gitea/gitea-install-workflow.py`.
## Do Not Move
The following stay in each module repository:
- `pyproject.toml` and package dependency metadata.
- Backend manifests and migrations.
- Module-owned tests.
- Module READMEs and module-specific docs.
- WebUI package manifests and module frontend source.
Those files describe or implement the module itself. The meta repo should
catalog and orchestrate them, not become the owner of module code.

View File

@@ -0,0 +1,120 @@
# Module Contracts and Install Boundaries
## Why Some Changes Require `pip install`
GovOPlaN discovers runtime modules through Python package entry points in the
`govoplan.modules` group. Core reads those entry points with
`importlib.metadata.entry_points()`, imports the configured manifest factory, and
then builds the module registry from the returned `ModuleManifest`.
That means the Python environment must know that a package exists before core can
discover it.
In development, `requirements-dev.txt` installs modules with `-e
../govoplan-module`. With editable installs:
- normal Python source changes are picked up after the process reloads;
- manifest code changes are picked up after the process reloads;
- new imports inside an already installed package are picked up after reload.
`pip install` is still needed when package metadata changes:
- a repository was not installed in the environment before;
- a `pyproject.toml` entry point is added, renamed, or removed;
- package dependencies change;
- optional extras change;
- package names or import roots change;
- console scripts or other installed metadata change;
- release installs need a different tag, wheel, or source ref.
The same principle applies to WebUI packages: source changes are local during
development, but `package.json` dependency or export changes require an install
step so the consuming app sees the correct package metadata.
## Current Contract Mechanism
Modules already announce contracts through `ModuleManifest`:
- `dependencies`
- `optional_dependencies`
- `required_capabilities`
- `optional_capabilities`
- `provides_interfaces`
- `requires_interfaces`
- `capability_factories`
- permissions and role templates
- route factories, migrations, docs, lifecycle hooks, and frontend metadata
Core validates the active manifest graph when it builds the registry. Release
tooling can inspect those manifests to calculate compatibility and migration
impact.
## What Core Can and Cannot Pick Up Automatically
Core can pick up contract changes automatically after reload when the changed
module package is already installed and importable.
Core cannot discover a new module or new entry point that has not been installed
into the environment, because there is no distribution metadata to enumerate.
Core also cannot notify every module about a contract change at edit time by
itself. The runtime registry is built from installed/importable packages. The
right place for cross-module announcement is the meta repo tooling and CI:
- scan manifests across all repositories;
- build an impact graph from provided/required interfaces and capabilities;
- run affected module tests;
- post Gitea issue/release notes for affected modules;
- block releases when a required interface is missing or incompatible.
## Mitigation Strategy
Use three layers:
1. Editable development environment.
Keep `requirements-dev.txt` in the meta repo as the one workspace installer.
Source edits then need process reloads, not repeated full installs.
2. Versioned runtime contracts.
Keep adding and tightening `provides_interfaces`, `requires_interfaces`, and
capability protocols. Treat interface names and versions as public module
contracts.
3. Meta-level contract audit.
The meta repo statically reads `src/**/backend/manifest.py` files across all
repositories and validates provided/required interface ranges without
importing the packages. CI blocks missing or incompatible required
interfaces before release installs are attempted.
Run the static graph check with:
```sh
./tools/checks/check-contracts.sh
```
Use `--json` when the release console or another automation needs structured
provider/consumer impact data.
## Practical Rule
Do not run `pip install` for every code edit. Run it when package metadata or the
set of installed packages changes.
For normal development:
```sh
./.venv/bin/python tools/repo/sync-python-environment.py --requirements requirements-dev.txt --python ./.venv/bin/python
```
Then restart the server when Python code or manifests change. The development
launcher runs this helper automatically by default; set
`GOVOPLAN_AUTO_SYNC_PYTHON=0` to disable that preflight.
For release validation:
```sh
./.venv/bin/python tools/repo/sync-python-environment.py --requirements requirements-release.txt --python ./.venv/bin/python
```
That install is necessary because the release environment intentionally resolves
tagged package refs, not local editable source trees.

194
docs/RELEASE_CONSOLE.md Normal file
View File

@@ -0,0 +1,194 @@
# GovOPlaN Release Console
The release console is a local operator tool for planning and executing
GovOPlaN releases. It belongs to the `govoplan` meta repository because it works
across all local checkouts, release scripts, module manifests, migration audits,
catalog files, Git state, and signing keys.
The current implementation has a read-only dashboard plus guarded local
candidate/publish actions:
- inspect repositories from `repositories.json`
- show dirty, ahead, behind, missing, no-HEAD, and tag state
- show local package catalog and keyring state
- optionally run release/dev migration audits
- propose next actions without executing them
- compare local catalog/keyring JSON with the published channel and public
keyring when online checks are enabled
- configure target versions per release unit in the web UI
- select the repositories that should advance through checkboxes
- generate dry-run selective release plans for independently versioned packages
- generate signed catalog candidates for the selected release units
- preview/apply/push reviewed catalog candidates behind explicit confirmations
Start it from the meta repository:
```sh
./.venv/bin/python tools/release/release-console.py
```
The server binds to `127.0.0.1` by default and prints a URL containing a local
API token. Open that URL in a browser on the same machine.
The web UI starts with a repository table. Each repository can be checked
independently and assigned its own target version. Repositories without version
metadata remain visible so they can be planned as initial releases. `Build Plan`
shows the dry-run commands for the selected rows, and `Generate Candidate`
creates a signed catalog candidate that advances only selected repositories that
already have a catalog entry.
The release-control area above the repository table is read-only and is meant
to become the central release cockpit. It shows:
- local and published channel health
- catalog/keyring drift
- signature and trusted-key status
- published module versions and refs
- local checkout version drift against the catalog
- catalog-declared interface compatibility
The target-version control can generate the next major, minor, or subversion
from the current base version. Manual target input accepts explicit versions
such as `0.2.0` or `0.2.0-alpha1`, but requires the first three version numbers
to move forward.
Plain repository pushes are separate from catalog publication. `Preview Push`
shows the selected repository push commands. `Push Selected` requires `PUSH` in
the repository push confirmation field.
The catalog workflow panel can also operate on the same selected rows:
- `Generate` creates a signed candidate below `runtime/release-candidates/`.
- `Preview` validates a candidate and shows what would be copied into the
website repository.
- `Apply + Tag` requires `APPLY` in the confirmation field.
- `Push` requires `PUSH` in the confirmation field.
The default signing key is
`$HOME/.config/govoplan/release-keys/release-key-1.pem` when no signing key is
entered in the UI.
Generate a selective release plan from the terminal:
```sh
./.venv/bin/python tools/release/release-plan.py \
--repo govoplan-files \
--target-version 0.1.9 \
--channel stable \
--online
```
`--online` compares the local catalog/keyring with the published channel and
published keyring. Use `--remote-tags` only when the plan also needs to check
Git remotes for tag existence; that can be slower across the full repository
set.
Build a signed selective catalog candidate:
```sh
KEY_DIR="$HOME/.config/govoplan/release-keys"
./.venv/bin/python tools/release/release-catalog.py selective \
--repo-version govoplan-files=0.1.9 \
--channel stable \
--catalog-signing-key "release-key-1=$KEY_DIR/release-key-1.pem"
```
This writes candidate catalog/keyring files below `runtime/release-candidates/`,
generates the browsable module directory below `modules/`, validates the signed
candidate with the module installer validator, and reports whether the candidate
catalog/keyring match the currently published channel. It does not publish to
the website repository.
Regenerate the browsable module directory from an existing catalog/keyring:
```sh
./.venv/bin/python tools/release/release-catalog.py module-directory \
--catalog ../addideas-govoplan-website/public/catalogs/v1/channels/stable.json \
--keyring ../addideas-govoplan-website/public/catalogs/v1/keyring.json \
--output-dir runtime/module-directory-preview \
--channel stable
```
Preview publication of a reviewed candidate:
```sh
./.venv/bin/python tools/release/release-catalog.py publish-candidate \
--candidate-dir runtime/release-candidates/stable-YYYYMMDD-HHMMSS \
--channel stable
```
Apply the reviewed candidate into the website repository without pushing:
```sh
./.venv/bin/python tools/release/release-catalog.py publish-candidate \
--candidate-dir runtime/release-candidates/stable-YYYYMMDD-HHMMSS \
--channel stable \
--apply \
--commit \
--tag
```
Push is a separate explicit flag:
```sh
./.venv/bin/python tools/release/release-catalog.py publish-candidate \
--candidate-dir runtime/release-candidates/stable-YYYYMMDD-HHMMSS \
--channel stable \
--apply \
--commit \
--tag \
--push
```
Published channels are expected below the public catalog base URL:
- `https://govoplan.add-ideas.de/catalogs/v1/channels/stable.json`
- `https://govoplan.add-ideas.de/catalogs/v1/keyring.json`
The console treats channels as release artifacts. A package can advance without
forcing every repository to the same tag, but channel publication must preserve
the unchanged package versions, validate interface compatibility, sign the
updated catalog, and keep the published keyring healthy.
## Published Module Directory
The target release repository is an online, browsable module directory. The
catalog remains the machine-readable channel entry point, but the published
space should also expose a tree that operators and installations can inspect:
- `/catalogs/v1/channels/<channel>.json` describes the active channel state.
- `/catalogs/v1/keyring.json` publishes trusted release signing keys.
- `/catalogs/v1/modules/<module>/<version>/manifest.json` describes one
published module version, including repository refs, package refs, contracts,
compatibility windows, signatures, and available artifacts.
- `/catalogs/v1/modules/<module>/index.json` lists available versions for
one module.
- `/catalogs/v1/modules/index.json` lists all published modules.
Gitea tags/releases remain the source release anchors. The public GovOPlaN
catalog directory becomes the installation-facing release repository that points
to those anchors and carries structured compatibility information.
Selective catalog candidates now include this directory tree. Publishing a
candidate copies the channel catalog, keyring, and `modules/` tree into the
website repository together.
Current limitation: selective catalog generation updates existing catalog
entries. Initial catalog entry synthesis for brand-new modules is still a
separate backend slice.
## Direction
The console should grow in slices:
1. Read-only dashboard and next-action suggestions.
2. Release plan builder that writes explicit JSON plans.
3. Dry-run executor that shows exact commands and expected file changes.
4. Apply executor for commit, tag, push, artifact build, signing, and catalog
publication.
5. Compatibility planner for manifest contracts and version ranges.
6. Install/test workflow that validates a release from tags or catalog entries.
All mutation must stay explicit: plan first, dry run second, apply only after a
clear confirmation.

89
docs/REPOSITORY_INDEX.md Normal file
View File

@@ -0,0 +1,89 @@
# GovOPlaN Repository Index
Generated from `repositories.json`. Use that JSON file as the machine-readable source of truth; this page is the human-readable link index.
## System
| Repository | Subtype | Local path | Gitea |
| --- | --- | --- | --- |
| `govoplan` | `meta` | `../govoplan` | [govoplan](https://git.add-ideas.de/add-ideas/govoplan) |
| `govoplan-core` | `kernel` | `../govoplan-core` | [govoplan-core](https://git.add-ideas.de/add-ideas/govoplan-core) |
## Module
| Repository | Subtype | Local path | Gitea |
| --- | --- | --- | --- |
| `govoplan-access` | `platform` | `../govoplan-access` | [govoplan-access](https://git.add-ideas.de/add-ideas/govoplan-access) |
| `govoplan-addresses` | `domain` | `../govoplan-addresses` | [govoplan-addresses](https://git.add-ideas.de/add-ideas/govoplan-addresses) |
| `govoplan-admin` | `platform` | `../govoplan-admin` | [govoplan-admin](https://git.add-ideas.de/add-ideas/govoplan-admin) |
| `govoplan-appointments` | `domain` | `../govoplan-appointments` | [govoplan-appointments](https://git.add-ideas.de/add-ideas/govoplan-appointments) |
| `govoplan-approvals` | `domain` | `../govoplan-approvals` | [govoplan-approvals](https://git.add-ideas.de/add-ideas/govoplan-approvals) |
| `govoplan-assets` | `domain` | `../govoplan-assets` | [govoplan-assets](https://git.add-ideas.de/add-ideas/govoplan-assets) |
| `govoplan-audit` | `platform` | `../govoplan-audit` | [govoplan-audit](https://git.add-ideas.de/add-ideas/govoplan-audit) |
| `govoplan-booking` | `domain` | `../govoplan-booking` | [govoplan-booking](https://git.add-ideas.de/add-ideas/govoplan-booking) |
| `govoplan-calendar` | `domain` | `../govoplan-calendar` | [govoplan-calendar](https://git.add-ideas.de/add-ideas/govoplan-calendar) |
| `govoplan-campaign` | `domain` | `../govoplan-campaign` | [govoplan-campaign](https://git.add-ideas.de/add-ideas/govoplan-campaign) |
| `govoplan-cases` | `domain` | `../govoplan-cases` | [govoplan-cases](https://git.add-ideas.de/add-ideas/govoplan-cases) |
| `govoplan-certificates` | `domain` | `../govoplan-certificates` | [govoplan-certificates](https://git.add-ideas.de/add-ideas/govoplan-certificates) |
| `govoplan-committee` | `domain` | `../govoplan-committee` | [govoplan-committee](https://git.add-ideas.de/add-ideas/govoplan-committee) |
| `govoplan-consultation` | `domain` | `../govoplan-consultation` | [govoplan-consultation](https://git.add-ideas.de/add-ideas/govoplan-consultation) |
| `govoplan-contracts` | `domain` | `../govoplan-contracts` | [govoplan-contracts](https://git.add-ideas.de/add-ideas/govoplan-contracts) |
| `govoplan-dashboard` | `platform` | `../govoplan-dashboard` | [govoplan-dashboard](https://git.add-ideas.de/add-ideas/govoplan-dashboard) |
| `govoplan-dms` | `domain` | `../govoplan-dms` | [govoplan-dms](https://git.add-ideas.de/add-ideas/govoplan-dms) |
| `govoplan-dist-lists` | `domain` | `../govoplan-dist-lists` | [govoplan-dist-lists](https://git.add-ideas.de/add-ideas/govoplan-dist-lists) |
| `govoplan-docs` | `platform` | `../govoplan-docs` | [govoplan-docs](https://git.add-ideas.de/add-ideas/govoplan-docs) |
| `govoplan-erp` | `domain` | `../govoplan-erp` | [govoplan-erp](https://git.add-ideas.de/add-ideas/govoplan-erp) |
| `govoplan-evaluation` | `domain` | `../govoplan-evaluation` | [govoplan-evaluation](https://git.add-ideas.de/add-ideas/govoplan-evaluation) |
| `govoplan-facilities` | `domain` | `../govoplan-facilities` | [govoplan-facilities](https://git.add-ideas.de/add-ideas/govoplan-facilities) |
| `govoplan-files` | `domain` | `../govoplan-files` | [govoplan-files](https://git.add-ideas.de/add-ideas/govoplan-files) |
| `govoplan-forms` | `domain` | `../govoplan-forms` | [govoplan-forms](https://git.add-ideas.de/add-ideas/govoplan-forms) |
| `govoplan-forms-runtime` | `platform` | `../govoplan-forms-runtime` | [govoplan-forms-runtime](https://git.add-ideas.de/add-ideas/govoplan-forms-runtime) |
| `govoplan-grants` | `domain` | `../govoplan-grants` | [govoplan-grants](https://git.add-ideas.de/add-ideas/govoplan-grants) |
| `govoplan-helpdesk` | `domain` | `../govoplan-helpdesk` | [govoplan-helpdesk](https://git.add-ideas.de/add-ideas/govoplan-helpdesk) |
| `govoplan-identity` | `platform` | `../govoplan-identity` | [govoplan-identity](https://git.add-ideas.de/add-ideas/govoplan-identity) |
| `govoplan-identity-trust` | `platform` | `../govoplan-identity-trust` | [govoplan-identity-trust](https://git.add-ideas.de/add-ideas/govoplan-identity-trust) |
| `govoplan-idm` | `platform` | `../govoplan-idm` | [govoplan-idm](https://git.add-ideas.de/add-ideas/govoplan-idm) |
| `govoplan-inspections` | `domain` | `../govoplan-inspections` | [govoplan-inspections](https://git.add-ideas.de/add-ideas/govoplan-inspections) |
| `govoplan-issue-reporting` | `domain` | `../govoplan-issue-reporting` | [govoplan-issue-reporting](https://git.add-ideas.de/add-ideas/govoplan-issue-reporting) |
| `govoplan-learning` | `domain` | `../govoplan-learning` | [govoplan-learning](https://git.add-ideas.de/add-ideas/govoplan-learning) |
| `govoplan-ledger` | `domain` | `../govoplan-ledger` | [govoplan-ledger](https://git.add-ideas.de/add-ideas/govoplan-ledger) |
| `govoplan-mail` | `domain` | `../govoplan-mail` | [govoplan-mail](https://git.add-ideas.de/add-ideas/govoplan-mail) |
| `govoplan-notifications` | `platform` | `../govoplan-notifications` | [govoplan-notifications](https://git.add-ideas.de/add-ideas/govoplan-notifications) |
| `govoplan-ops` | `platform` | `../govoplan-ops` | [govoplan-ops](https://git.add-ideas.de/add-ideas/govoplan-ops) |
| `govoplan-organizations` | `platform` | `../govoplan-organizations` | [govoplan-organizations](https://git.add-ideas.de/add-ideas/govoplan-organizations) |
| `govoplan-payments` | `domain` | `../govoplan-payments` | [govoplan-payments](https://git.add-ideas.de/add-ideas/govoplan-payments) |
| `govoplan-permits` | `domain` | `../govoplan-permits` | [govoplan-permits](https://git.add-ideas.de/add-ideas/govoplan-permits) |
| `govoplan-policy` | `platform` | `../govoplan-policy` | [govoplan-policy](https://git.add-ideas.de/add-ideas/govoplan-policy) |
| `govoplan-poll` | `domain` | `../govoplan-poll` | [govoplan-poll](https://git.add-ideas.de/add-ideas/govoplan-poll) |
| `govoplan-portal` | `domain` | `../govoplan-portal` | [govoplan-portal](https://git.add-ideas.de/add-ideas/govoplan-portal) |
| `govoplan-postbox` | `domain` | `../govoplan-postbox` | [govoplan-postbox](https://git.add-ideas.de/add-ideas/govoplan-postbox) |
| `govoplan-procurement` | `domain` | `../govoplan-procurement` | [govoplan-procurement](https://git.add-ideas.de/add-ideas/govoplan-procurement) |
| `govoplan-records` | `domain` | `../govoplan-records` | [govoplan-records](https://git.add-ideas.de/add-ideas/govoplan-records) |
| `govoplan-reporting` | `domain` | `../govoplan-reporting` | [govoplan-reporting](https://git.add-ideas.de/add-ideas/govoplan-reporting) |
| `govoplan-resources` | `domain` | `../govoplan-resources` | [govoplan-resources](https://git.add-ideas.de/add-ideas/govoplan-resources) |
| `govoplan-risk-compliance` | `domain` | `../govoplan-risk-compliance` | [govoplan-risk-compliance](https://git.add-ideas.de/add-ideas/govoplan-risk-compliance) |
| `govoplan-scheduling` | `domain` | `../govoplan-scheduling` | [govoplan-scheduling](https://git.add-ideas.de/add-ideas/govoplan-scheduling) |
| `govoplan-search` | `platform` | `../govoplan-search` | [govoplan-search](https://git.add-ideas.de/add-ideas/govoplan-search) |
| `govoplan-tasks` | `domain` | `../govoplan-tasks` | [govoplan-tasks](https://git.add-ideas.de/add-ideas/govoplan-tasks) |
| `govoplan-templates` | `domain` | `../govoplan-templates` | [govoplan-templates](https://git.add-ideas.de/add-ideas/govoplan-templates) |
| `govoplan-tenancy` | `platform` | `../govoplan-tenancy` | [govoplan-tenancy](https://git.add-ideas.de/add-ideas/govoplan-tenancy) |
| `govoplan-transparency` | `domain` | `../govoplan-transparency` | [govoplan-transparency](https://git.add-ideas.de/add-ideas/govoplan-transparency) |
| `govoplan-workflow` | `platform` | `../govoplan-workflow` | [govoplan-workflow](https://git.add-ideas.de/add-ideas/govoplan-workflow) |
## Connector
| Repository | Subtype | Local path | Gitea |
| --- | --- | --- | --- |
| `govoplan-connectors` | `connector-hub` | `../govoplan-connectors` | [govoplan-connectors](https://git.add-ideas.de/add-ideas/govoplan-connectors) |
| `govoplan-fit-connect` | `standard` | `../govoplan-fit-connect` | [govoplan-fit-connect](https://git.add-ideas.de/add-ideas/govoplan-fit-connect) |
| `govoplan-rest` | `protocol` | `../govoplan-rest` | [govoplan-rest](https://git.add-ideas.de/add-ideas/govoplan-rest) |
| `govoplan-soap` | `protocol` | `../govoplan-soap` | [govoplan-soap](https://git.add-ideas.de/add-ideas/govoplan-soap) |
| `govoplan-xoev` | `standard` | `../govoplan-xoev` | [govoplan-xoev](https://git.add-ideas.de/add-ideas/govoplan-xoev) |
| `govoplan-xrechnung` | `standard` | `../govoplan-xrechnung` | [govoplan-xrechnung](https://git.add-ideas.de/add-ideas/govoplan-xrechnung) |
| `govoplan-xta-osci` | `standard` | `../govoplan-xta-osci` | [govoplan-xta-osci](https://git.add-ideas.de/add-ideas/govoplan-xta-osci) |
## Website
| Repository | Subtype | Local path | Gitea |
| --- | --- | --- | --- |
| `addideas-govoplan-website` | `public-site` | `../addideas-govoplan-website` | [addideas-govoplan-website](https://git.add-ideas.de/add-ideas/addideas-govoplan-website) |

View File

@@ -40,6 +40,11 @@ The wrapper tags the toolbox image by a fingerprint of the Dockerfile and
the existing local image instead of reinstalling all tools. The stable alias is
`govoplan/security-audit:local` unless `SECURITY_AUDIT_IMAGE` is set.
Semgrep is installed separately in the toolbox image because current Semgrep
packages pin Click to an affected `8.1.x` line. The image upgrades Click after
Semgrep installation and fails during build if Semgrep no longer starts with the
patched Click version.
Force a cached rebuild:
```bash
@@ -65,6 +70,13 @@ tools/checks/security-audit/run.sh --mode quick --scope current --update --build
- `ci`: quick plus Semgrep public registry rulesets, Trivy, pip-audit, npm audit.
- `full`: ci plus OSV-Scanner, jscpd, Radon, and Xenon.
Bandit and Ruff security reports are split by source kind. Production code under
`src/` is written to `bandit.json` and `ruff-security.json` and controls strict
mode. Test code under `tests/` is still scanned for visibility, but its findings
are written separately to `bandit-tests.json` and `ruff-security-tests.json` so
fixture passwords, assertions, and temporary paths do not hide the production
baseline.
## Gating
The initial Gitea workflow runs in report-only mode:
@@ -115,6 +127,13 @@ Keep active implementation status in issues instead of committing generated
audit reports. `audit-reports/` is ignored; quote the report directory and the
important scanner counts in the tracker issue.
The jscpd step is intentionally scoped to application and test source. It
excludes documentation snippets, package manifests, generated translations,
public SVG assets, workflow YAML, and declarative backend schema JSON because
those reports produce metadata or asset repetition rather than actionable source
duplication. Keep exclusions narrow and create child issues for source-code
clusters that cross module ownership or make behavior harder to change safely.
## Image Freshness
The regular `Security Audit` workflow reuses the fingerprinted toolbox image
@@ -133,6 +152,8 @@ tools first:
cd /mnt/DATA/git/govoplan
python -m venv .venv
./.venv/bin/python -m pip install -r requirements-audit.txt
./.venv/bin/python -m pip install 'semgrep>=1.140,<2'
./.venv/bin/python -m pip install --upgrade --no-deps 'click>=8.3.3'
```
Then install the non-Python tools (`gitleaks`, `trivy`, `osv-scanner`, `jscpd`)

View File

@@ -149,6 +149,12 @@
"description": "GovOPlaN Dms module behavior or integration.",
"exclusive": false
},
{
"name": "module/dist-lists",
"color": "0e8a16",
"description": "GovOPlaN Distribution Lists module behavior or integration.",
"exclusive": false
},
{
"name": "module/erp",
"color": "fef2c0",