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.
301 lines
18 KiB
Markdown
Executable File
301 lines
18 KiB
Markdown
Executable File
# Developer command suite
|
|
|
|
`./devkit` is the maintained entry point for repeated development work. It uses
|
|
ordinary local programs, not an AI service. People, CI and coding agents use the
|
|
same commands and results. It composes existing GovOPlaN checks and release
|
|
services rather than defining parallel product rules.
|
|
|
|
## Start here
|
|
|
|
From the Meta checkout:
|
|
|
|
```sh
|
|
./devkit commands
|
|
./devkit doctor --repo core
|
|
./devkit context --changed
|
|
./devkit check --profile quick --repo campaign --dry-run
|
|
./devkit coverage --profile ui --repo campaign
|
|
./devkit check --profile quick --repo campaign
|
|
./devkit latest
|
|
./devkit review campaign
|
|
```
|
|
|
|
Use `--help` on each command. `--json` (or `--format json`) returns structured
|
|
results; the default summary intentionally omits full logs and source contents.
|
|
Global options work before or after the command. `--workspace-root` is the parent
|
|
directory of the registered repositories, not the Core checkout. Unknown
|
|
repository filters fail rather than silently widening/narrowing scope.
|
|
|
|
The launcher prefers Meta's `.venv/bin/python`, or the explicit `PYTHON`
|
|
executable, with `python3` as the no-venv fallback. Checks resolve `NODE` and
|
|
`NPM` from explicit environment settings or `PATH`; no username-specific Node
|
|
installation path is required. Doctor reports repairs but never installs
|
|
packages, changes configuration, kills an occupied port or starts a server.
|
|
|
|
## Command contracts
|
|
|
|
| Command | Purpose | Effects |
|
|
| --- | --- | --- |
|
|
| `context [--changed] [--repo NAME]` | Offline Git state, instruction/documentation paths and review links | Reads only; upstream counts are not freshly fetched |
|
|
| `doctor [--repo NAME] [--profile PROFILE]` | Interpreter, dependency, browser and test-resource preflight | Reads only; repair suggestions are not executed |
|
|
| `check --profile PROFILE` | Registered checks with explanations, bounded logs and a receipt | Runs trusted tests/builds; `--dry-run` only plans |
|
|
| `coverage --profile PROFILE [--repo NAME]` | Declared suite dispositions and explicit coverage limits | Reads only; not execution evidence |
|
|
| `runs [--limit 10] [--before RUN]`, `latest` | Discover recent runs without looking up state-directory paths | Reads only; malformed latest evidence is not replaced with an older pass |
|
|
| `status RUN`, `summary RUN` | Stage counts and failure log locations | Reads only |
|
|
| `logs RUN --stage STAGE --tail 40 [--final-only]` | Provisional live output or a hash-verified final stage log | Reads only; provisional output never proves a pass |
|
|
| `resume RUN` | Replan the previous check selection and reuse eligible successful stages | Runs remaining checks, creating a new receipt |
|
|
| `recover RUN [--apply]` | Recover an abandoned check-run record after acquiring its OS lock | No test replay; apply changes only the local record |
|
|
| `review MODULE` | Source inventory, principle revision, issue links, check plan and walkthrough checklist | Does not perform or complete a module review |
|
|
| `docs audit [--repo NAME] [--changed]` | Owning manifest/help/translation checks and visible-label gaps | Local checks only; never translates or edits content |
|
|
| `issues note …` | Preview and explicitly append deduplicated evidence | Remote comment creation only with `--apply` |
|
|
| `release …` | Existing durable release planning/execution/recovery | Explicit `--apply`, request IDs and existing step confirmations |
|
|
| `git …` | Frozen, explicit-path maintenance commit and exact branch push | Preview first; mutations require `--apply`; no stage-all, force or tags |
|
|
|
|
Git maintenance is a separate, selected-path workflow; see
|
|
[Git maintenance](DEVKIT_MAINTENANCE.md). Issue notes and module bundles are
|
|
documented in [Evidence and review commands](DEVKIT_EVIDENCE.md). The complete
|
|
release command syntax, limitations and examples are in
|
|
[Headless release operations](DEVKIT_RELEASE.md).
|
|
|
|
## Check profiles and their limits
|
|
|
|
- `quick`: existing manifest/interface invariants, import/help guards and selected
|
|
module source/structure tests. It does not compile component suites or run the
|
|
full browser matrix.
|
|
- `ui`: quick/source contracts plus the shared Core component batch, compiled
|
|
once in an isolated directory. This is not a full visual/usability review.
|
|
- `backend`: existing manifest/interface checks and selected repository backend
|
|
test suites. Shared backend-test state is serialized.
|
|
- `full`: the canonical `tools/checks/check-focused.sh`, including optional-module
|
|
build permutations and integrated browser conformance. Repository filters do
|
|
not reduce this required cross-module completion gate.
|
|
|
|
`--changed` includes uncommitted work, commits ahead of the locally cached
|
|
upstream and repositories with commits but no configured upstream.
|
|
Missing/unreadable repositories remain visible as errors. For the
|
|
GovOPlaN profiles, Core or Meta changes conservatively select every registered
|
|
consumer; other changes expand through declared interface consumers. This is
|
|
not complete semantic dependency analysis. Use the full gate for cross-module
|
|
completion as required by `AGENTS.md`.
|
|
|
|
The module catalog reuses declared direct-Node tests and established structural
|
|
script names. Arbitrary shell chains are not guessed or rewritten. Unsupported
|
|
declared scripts remain visible with a reason; only exact known Core component
|
|
aliases are covered by the shared component runner. Invalid package metadata is
|
|
an error, not an empty test inventory.
|
|
|
|
`coverage` inventories declared suites as `planned`, `covered_elsewhere`,
|
|
`excluded` or `unsupported`, naming their covering stage where applicable. The
|
|
same inventory accompanies check dry runs and saved receipts. **Full means the
|
|
canonical focused gate, not every test in every package.** Its inventory follows
|
|
explicit canonical commands conservatively; it does not infer arbitrary nested
|
|
shell commands or npm hooks. Add new deterministic checks to the owning
|
|
package/canonical gate and the catalog's tests as appropriate. Coverage planning
|
|
does not execute the scripts it inventories or assert that they passed. See
|
|
[Coverage and validation details](DEVKIT_COVERAGE.md) for examples and boundaries.
|
|
|
|
Independent checks can run with `--jobs 1..8` (default 2). Shared resources use
|
|
OS locks for the current user, including across runs with different evidence
|
|
directories. Browser/port locks are shared across that user's workspaces. Full runs
|
|
reserve the shared WebUI/backend/browser resources. Standalone Core component
|
|
commands use isolated temporary build directories; `npm run test:components --
|
|
page-layout documentation-help` compiles once for that batch. Managed temporary
|
|
output is cleaned; no user worktree is reset or restored.
|
|
|
|
## Evidence, interruption and safe reuse
|
|
|
|
A check announces its run ID and saves a `preparing` receipt before source and
|
|
environment fingerprinting. Progress on stderr shows elapsed time, stage counts
|
|
and active stages; it also distinguishes `checking` from final snapshot
|
|
verification (`finalizing`). `--json` keeps stdout as one final JSON result and
|
|
emits structured progress events on stderr; `--quiet` suppresses these events.
|
|
Use `latest`, `status RUN` and `logs RUN --stage STAGE` from another terminal
|
|
while a check runs. Counts are stages, not a guessed percentage of test effort.
|
|
|
|
Live snapshots are private, bounded, explicitly provisional and not accepted for
|
|
reuse or issue evidence. A completed stage log can be hash-verified before the
|
|
whole run finishes, but only the final run snapshot verifies the overall result.
|
|
`--final-only` rejects unfinished logs. Run history supports cursor pagination
|
|
(up to 100 rows per page), bounds directory scanning, and never deletes evidence.
|
|
An explicitly selected `--project` also filters run discovery by project file.
|
|
|
|
Default records are private below
|
|
`$XDG_STATE_HOME/govoplan/devkit/workspace-<identity>/runs/<run>/` (fallback
|
|
`~/.local/state`). `--state-dir` selects another base; workspace scoping still
|
|
applies. Status changes are atomically persisted with restrictive file modes;
|
|
symlinked evidence paths are rejected. A record contains source/environment/plan
|
|
fingerprints, stage reasons, status, exit code, timing and log identities.
|
|
|
|
Stages distinguish pending, running, passed, failed, timed out, blocked, skipped,
|
|
stale and interrupted. A skipped or unexecuted stage is never a pass. A source or
|
|
environment change during verification marks the overall result **stale**, even
|
|
when individual subprocesses returned zero. Such a result is not passing evidence.
|
|
|
|
`resume RUN` replans the current selection and compares each phase independently.
|
|
Matching **verified checkpoints** are reused; changed/new phases and phases
|
|
without a checkpoint run again. A checkpoint binds the exact command and working
|
|
directory, declared repository inputs, transitive data-dependency identities,
|
|
devkit implementation/schema, tool/dependency metadata and environment. Logs must
|
|
retain their recorded hashes; a missing or changed cached log fails closed.
|
|
The summary reports how many checkpoints were reused; JSON records `input_scope`,
|
|
`cache_key`, `checkpoint_verified`, `reused_from` and the reuse/rerun reason.
|
|
|
|
Each checkpoint is saved while its resource locks remain held, only after exit
|
|
zero, a verified final log, and matching before/after inputs and environment.
|
|
A phase that changes its own inputs is stale, even if another phase later restores
|
|
those bytes. Final verification rechecks all passed/reused phases against current
|
|
inputs before the new aggregate can pass. An interrupted, failed or stale run may
|
|
donate an independently verified matching checkpoint, but never becomes passing
|
|
evidence itself. Old receipts remain readable: legacy monolithic logs and receipts
|
|
without these checkpoints cannot be retroactively split or reused as verified phases.
|
|
|
|
After a hard crash, `recover RUN` shows the abandoned owner and guidance. Inspect the
|
|
recorded commands and manually stop any surviving test/build processes before
|
|
using `recover RUN --apply --confirm-processes-stopped`. The command verifies the
|
|
run lock is free before marking the record interrupted. A free parent lock alone
|
|
does **not** prove children stopped after a hard kill. Recovery does not replay
|
|
processes or infer that a partially completed operation succeeded.
|
|
|
|
### Canonical phases and narrower inputs
|
|
|
|
The full gate has seven explicit phases: `preflight`, `tooling`, `backend`,
|
|
`core-ui`, `module-builds`, `browser`, and `module-ui`. Devkit stage IDs are
|
|
`focused.<phase>`. The authoritative Bash bodies remain in
|
|
`tools/checks/check-focused.sh`; the bounded metadata in
|
|
`tools/checks/focused-phases.json` names their order and resources. The direct
|
|
shell command still runs every phase in the original fail-fast order. For inspection:
|
|
|
|
```sh
|
|
tools/checks/check-focused.sh --list-phases
|
|
./devkit check --profile full --jobs 1
|
|
./devkit resume RUN_ID --jobs 1
|
|
```
|
|
|
|
For example, a browser failure no longer forces successful backend/build phases
|
|
to run again if their inputs still match. Standalone `--phase browser` is available
|
|
for diagnostics, but is not a substitute for the complete gate or its receipt.
|
|
|
|
Scopes are whole repositories, not inferred file globs. A trusted check may declare
|
|
`"inputs": {"repos": ["canonical-repository-name"]}`; no declaration means the whole
|
|
registered workspace. Dry runs show that boundary. Native source-discovery checks
|
|
retain broad scopes where cross-module dependencies cannot safely be narrowed.
|
|
Changes outside an explicit scope do not invalidate it, but tool/environment
|
|
changes remain conservatively global. Scope declarations are a correctness
|
|
contract: include every source repository that the check reads, not only its cwd.
|
|
Native discovery ownership/presence is rechecked at phase boundaries, so a newly
|
|
appearing module or WebUI directory invalidates the in-flight environment identity.
|
|
Unregistered native sibling sources disable reuse with an explicit coverage note;
|
|
register them before relying on cached results. Ordinary generated files inside
|
|
existing source directories do not change this directory-shape identity.
|
|
|
|
Every snapshot rereads repository presence, HEAD, index/flags and tracked plus
|
|
non-ignored untracked membership, including assume-unchanged files. File hashes
|
|
use a bounded **in-process-only** memo with file identity/ctime/mtime/size checks
|
|
before and after an open file descriptor; no persistent mtime cache is trusted.
|
|
In-repository regular-file symlink targets are included; escaping or directory
|
|
symlinks fail closed. Ignored files, undeclared external data and service state
|
|
are not source evidence and need explicit verification.
|
|
|
|
Environment probes stream bounded regular-file contents and reject concurrent
|
|
replacement, growth and symlink retargeting. Stable venv executable and dependency
|
|
directory symlinks remain supported without changing the executable path; absent
|
|
optional metadata remains optional. Environment identities are not persistently
|
|
cached and remain deliberately global.
|
|
|
|
These checkpoints cache **verification results, not output artifacts**. The full
|
|
gate's phases were audited so later phases do not require an earlier phase's
|
|
retained build output. A custom setup/build that produces files consumed later
|
|
must declare `"reuse": "never"`; its consumers must use `deps`. Until output
|
|
manifests/restoration exist, do not assume a cached successful build recreates
|
|
deleted ignored artifacts.
|
|
|
|
Check output is drained without unbounded memory growth. Stored output retains
|
|
the beginning and actual final tail within an 8 MiB bound per stage, with a small
|
|
truncation marker and an omitted-byte count; output truncation does not change
|
|
the subprocess exit result. `logs` exposes at most 200 lines and 16 KiB. Live
|
|
snapshots retain at most 64 KiB after redaction. Incomplete live lines and cut
|
|
retention-boundary lines are withheld to avoid exposing fragments of secrets;
|
|
very long single-line output may therefore be absent from live views.
|
|
Known environment credentials and common authorization patterns are
|
|
redacted as display hygiene. **Never pass credentials as check arguments or print
|
|
them from tests.** Redaction is not a general secret-classification guarantee.
|
|
JSON command output is a redacted presentation; the receipt file at the reported
|
|
path is the canonical local record. Cancellation and deadlines terminate the
|
|
owned process group; a parent leaving running descendants does not pass.
|
|
During source/environment fingerprinting, cancellation is observed between
|
|
probes; the current bounded probe may finish first. Cancellation during final
|
|
verification is recorded as interrupted, never as a passing run.
|
|
Deliberately detached processes are outside that group: this is not a sandbox.
|
|
|
|
These local hash-bound records detect accidental changes; they are not signed
|
|
attestations, a security certification, proof of complete test coverage, or
|
|
permission to publish. External service state and undeclared dependencies still
|
|
need explicit verification. No automated result closes a Gitea issue or marks a
|
|
module reviewed. Detailed logs remain local unless deliberately shared. Old run
|
|
directories are not automatically deleted; review retention before removing any
|
|
evidence referenced by an issue.
|
|
|
|
## Reuse in another project
|
|
|
|
The runner, repository context, doctor and evidence primitives are usable with an
|
|
explicit local JSON project manifest. The example at
|
|
`tools/devkit/examples/project.json` registers ordinary Python tests and a Git
|
|
whitespace check; the format is described by
|
|
`tools/devkit/project.schema.json`.
|
|
|
|
```sh
|
|
/path/to/govoplan/devkit --workspace-root /path/to/project \
|
|
--project /path/to/project/devkit-project.json check --profile quick --dry-run
|
|
```
|
|
|
|
Repository paths and check working directories must remain inside the selected
|
|
workspace. Check arguments are arrays, not shell-evaluated strings. The supported
|
|
tool placeholders are `{python}`, `{node}`, `{npm}` and `{workspace}`. Check
|
|
dependencies form an acyclic graph; resources serialize incompatible tasks.
|
|
`deps` declares actual data dependencies: consumers rerun whenever a dependency
|
|
runs again. `after` declares only fail-fast execution ordering: a failed predecessor
|
|
skips the follower, but a successfully rerun independent predecessor does not
|
|
invalidate the follower's inputs. Both edge types are validated together for
|
|
cycles, missing IDs and overlap. `reuse` is `verified` by default or `never` for
|
|
setup/output-producing checks. Repository `inputs` names are canonical, unique,
|
|
nonempty and validated even for unselected checks.
|
|
The complete custom manifest is validated, including unselected checks/profiles:
|
|
unknown fields, misspellings, invalid bounds/types and unresolved dependencies
|
|
fail early. This prevents silently ignored resource or timeout declarations.
|
|
|
|
Portable `doctor` always requires its Python runtime, plus tools needed by the
|
|
selected checks and their dependencies and tools explicitly configured in the
|
|
manifest. Without `--profile`, all declared profiles are considered. Unused
|
|
Node/npm are marked `not_required` and do not block Python-only projects. Declare
|
|
indirect tool dependencies explicitly: arbitrary script contents are not
|
|
analyzed. Native GovOPlaN retains its Python/Node/npm requirements.
|
|
Only use project manifests and scripts you trust: running a registered test is
|
|
ordinary code execution, not a sandbox. Platform-specific release and Docs
|
|
commands reject generic project manifests; put another project's checks in its
|
|
own profiles rather than pretending its release policy is GovOPlaN's.
|
|
|
|
The initial runtime targets POSIX environments with Python 3.11+ and OS advisory
|
|
locks; it does not claim Windows support. No globally installed service or Codex
|
|
plugin is needed. Keep this implementation versioned and reuse it; avoid copying
|
|
diverging helper implementations into each project.
|
|
|
|
Devkit is not a complete build system: it does not infer semantic dependencies,
|
|
restore output artifacts, sandbox checks, or share signed remote caches. Repository
|
|
scopes intentionally stop short of file/glob narrowing; environment identities
|
|
remain global. These are explicit boundaries, not claims of exhaustive coverage.
|
|
|
|
## Development and conformance
|
|
|
|
```sh
|
|
./.venv/bin/python -m pytest -q tests/test_devkit_*.py
|
|
./.venv/bin/python -m pytest -q tests/test_focused_phases.py
|
|
node --test tests/test-devkit-display-labels.mjs
|
|
./.venv/bin/python -m unittest tests.test_documentation_structure
|
|
```
|
|
|
|
The focused gate includes the Python command-suite regression tests. Fixture
|
|
tests use temporary repositories/processes and mocked issue/release transports;
|
|
they do not commit user work, send mail, publish artifacts or change live issues.
|
|
Documentation is part of each command change: update `--help`, this guide and the
|
|
corresponding targeted contract tests together.
|