Verified with the coordinated workspace changes by devkit full run 2026-09-08T225814-186389-0000-3e3ed7cd (all seven phases passed). This shared UI pass does not mark the individual module reviews complete.
8.9 KiB
Executable File
Devkit review bundles and issue evidence
Gitea remains the canonical backlog and review state log. These commands assemble guidance and append evidence; they do not create a second progress tracker, close issues, rewrite issue bodies, tick checkboxes, or certify a module review.
Prepare a module review
./devkit review campaign
./devkit review campaigns --json --output /tmp/campaign-review.json
./devkit review campaign --evidence RUN_ID
Repository names, repository aliases and scope IDs from the
issue discovery inventory are accepted.
review bundle campaign is an equivalent spelling. A bundle contains the current
source inventory and fingerprint, canonical module/central issue links, the
Core principle revision and content hash, applicable planned check stages,
and a manual checklist. No checks or application servers are started. The
optional output file is a local snapshot, not an authoritative state record.
The filename inventory is a starting point, not proof that all runtime surfaces were found. It does not import application manifests or optional modules. Review routes, panes, dialogs, settings, widgets, public forms, contributed/headless interfaces, missing-module behavior, permissions, English/German and narrow/wide layouts manually. Missing source, no UI files or no planned checks is never an automatic pass or N/A. Record exceptions and remaining work in the module issue.
Apply UI-01 and UI-02, and the other Core principles: books belong beside meaningful visible text; normal screens display compact data, with intentional scoped dialog editing. A bulk editing mode needs a documented reason. Record new principles and their back-propagation to previously reviewed modules through the central review program.
An explicit portable --project project.json does not inherit GovOPlaN issue
links or principles. Its optional configuration is:
{
"review": {
"issue_inventory": "meta/docs/review-issues.json",
"principles": "core/docs/UI_DESIGN_PRINCIPLES.md"
}
}
Paths are relative to --workspace-root and cannot escape it or traverse
symlinks. The inventory uses schema version 1, issues[] with scope_id,
repository, number, url, and optional name/kind; an optional epic
contains repository, number, url. Snapshot issue-state fields are not
reported as current state. Custom checks come from the project's selected
profile (--profile ui by default).
Preview and append evidence
./devkit issues note --root govoplan-campaign --issue 103 \
--evidence RUN_ID --summary 'Targeted checks passed.' \
--next 'Manual module review and remaining fixes are still required.' --json
./devkit issues note --root govoplan-campaign --issue 103 \
--evidence RUN_ID --summary 'Targeted checks passed.' \
--next 'Manual module review and remaining fixes are still required.' \
--env-file /private/gitea.env --apply
--root is resolved relative to the selected workspace root, not the shell's
current directory. In the normal siblings workspace, use --root govoplan-campaign
or an absolute checkout path; do not use a path escaping the workspace.
The default is a completely offline dry run; it does not load credentials or
contact Gitea. --apply explicitly authorizes comment creation. Tokens are read
from GITEA_TOKEN or the explicit --env-file (environment wins); there is no
implicit .env search. The credential file is parsed, never sourced, and is not
printed or uploaded. Git's selected remote (default origin) determines the
exact target: ambient GITEA_OWNER, GITEA_REPO and GITEA_URL cannot retarget
the request. Credential-bearing HTTP Git remote URLs are rejected.
Use repeatable --summary/--next, --body-file for Markdown, or --note-file
with structured JSON { "summary": ["..."], "next": ["..."], "body": "..." }.
Do not put secrets in notes, paths, check arguments or logs. Display redaction is
best-effort protection, not permission to include confidential data.
For a bounded multi-issue operation, replace --root/--issue with
--target-plan targets.json:
{
"schema_version": 1,
"targets": [
{
"root": "govoplan-campaign",
"issue": 103,
"url": "https://git.add-ideas.de/GovOPlaN/govoplan-campaign/issues/103"
}
]
}
Targets must be unique, inside the workspace and bound exactly to their Git
remote/issue URLs, all on one exact Gitea base URL. Optional issue_id binds
Gitea's immutable numeric ID as well. Every target, complete comment history,
marker collision and local journal binding is checked before the first POST.
Comments are then posted serially and read back against the exact issue. A
closed issue stays closed; existing bodies, comments and checklists are untouched.
Each note has a stable hidden marker binding its issue, --key purpose
(verification by default), and evidence run ID. Identical already-published
notes are read back instead of reposted; changed content with the same marker
is a collision, not an update. Use a distinct intentional --key for a separate
follow-up. Without a receipt, the note's structured content determines identity.
A lost POST response is not retried automatically. The publisher scans all
comment pages and reads back any matching comment. If it cannot confirm the
result, it records uncertain, stops later posts, and exits nonzero. The next
invocation reconciles again without replaying the POST. Only after inspecting
the issue and local result, use --apply --retry-uncertain to permit one new
attempt when the marker is still absent. Local journals and OS-released locks
live in the workspace-scoped devkit state directory; do not delete them to bypass
uncertainty. These are retry receipts, not issue state. Independent machines or
different state directories cannot share a lock: coordinate publishers, because
Gitea comment creation does not provide an atomic idempotency key.
What a receipt does and does not prove
--evidence RUN_ID reads the workspace-scoped runner receipt and checks local
integrity. --evidence /path/to/receipt.json accepts bounded validated external
receipt metadata, explicitly labeled external-unverified. A self-consistent
digest is not a signature or independent verification. Foreign-workspace,
malformed and inconsistent successful receipts are rejected. Receipt-provided
commands are never run; log files are not opened or uploaded, only referenced.
Successful receipts must explicitly record a verified source snapshot; an
external file's flag is still a reported claim, not an independent attestation.
An aggregate containing a skipped stage cannot claim success. New versioned
receipts additionally require independent verified checkpoints for passed phases.
Failed/interrupted/stale aggregates remain labeled as such even when they contain
reusable successful phases; reuse creates a new run and preserves the original.
Stage coverage limitations are validated and retained in the note, including
checks omitted by scoped profiles. Compact review output shows the first eight
limitations and points to the complete list in its JSON bundle. A passing stage
never implies that omitted compiler, browser, permutation or manual checks ran.
Documentation audit limitations are saved with their stage receipts, so later
review bundles and issue notes retain the same scope as the original command.
Managed inventory collectors use the explicit selected workspace throughout;
an incomplete checkout never borrows sources or missing module imports from a
fuller default workspace. Missing required Core/parser dependencies fail the
audit. Legacy direct inventory commands without --workspace-root retain their
discovery behavior; use the explicit option for reproducible evidence.
The note distinguishes matches-current, historical-source-differs,
different-project-not-compared and unavailable comparisons. Matching source
is a comparison at bundle/note preparation time, not a live test run or proof
that a person completed review. If the source or environment has changed, run
the appropriate checks again and keep historical evidence labeled honestly.
Versioned repository-input receipts compare the recorded repository scope, not a legacy whole-workspace hash. Partial scopes remain explicitly labeled in evidence notes. This comparison reads source only; receipt commands are never executed. Legacy receipts retain their original comparison format. A matching source scope does not prove that ignored build outputs, the environment or live services match.
Fixtures cover dry-run isolation, exact target bindings, capped/repeated pagination, collisions, append-only idempotency, uncertain POST reconciliation, secret-safe errors, receipt validation, portable projects and optional-module review boundaries:
python3 -m pytest -q tests/test_devkit_issues.py tests/test_devkit_review.py