Add OpenAI specific configuration
- add AGENTS.md and PLANS.md based on MPV - add subagents configuration
This commit is contained in:
@@ -0,0 +1,300 @@
|
||||
# AGENTS.md
|
||||
|
||||
## Scope
|
||||
|
||||
- These rules apply to the entire repository.
|
||||
- Build a local WireGuard management tool for Linux servers.
|
||||
- Keep `wg-manager.sh` as the primary entry point.
|
||||
- The project is copied as a directory and is not installed into `PATH`.
|
||||
- Do not add installer or uninstaller scripts unless explicitly requested.
|
||||
- Treat `MVP.md` as the product scope and acceptance reference.
|
||||
- Treat `PLANS.md` as the required milestone sequence for MVP implementation.
|
||||
- Complete and verify one milestone before starting the next one.
|
||||
- Update the `PLANS.md` progress and execution log as milestones are completed.
|
||||
- Run milestones under the Sol coordinator and Luna worker/reviewer loop defined in `PLANS.md` and `.codex/`.
|
||||
- The coordinator must independently review Luna's changes and delegate explicit Luna repairs until verification passes or a genuine blocker remains.
|
||||
- Use the existing `add-user.sh` only as a behavioral reference.
|
||||
- New code must improve its safety rather than copy its weaknesses.
|
||||
|
||||
## General priorities
|
||||
|
||||
- Preserve a working WireGuard configuration above all else.
|
||||
- Prefer correctness and recoverability over cleverness.
|
||||
- Keep CLI behavior independent from the TUI.
|
||||
- Make every mutating operation explicit and auditable.
|
||||
- Keep secrets out of output, logs, tests, and error messages.
|
||||
- Minimize required dependencies.
|
||||
- Support operation over SSH and ordinary terminal emulators.
|
||||
- Write user-facing text in Russian unless the surrounding interface uses another language.
|
||||
- Keep identifiers, functions, CLI command names, and code comments in English.
|
||||
- Avoid unrelated refactors while implementing a focused change.
|
||||
|
||||
## Bash baseline
|
||||
|
||||
- Use Bash, not POSIX `sh`.
|
||||
- Start executable scripts with `#!/usr/bin/env bash`.
|
||||
- Enable `set -Eeuo pipefail` in production entry points.
|
||||
- Understand strict-mode exceptions before suppressing them.
|
||||
- Use `if command; then` when a nonzero status is expected.
|
||||
- Do not append `|| true` unless the ignored failure is intentional and documented.
|
||||
- Set `umask 077` before creating configs, keys, metadata, logs, or backups.
|
||||
- Require a supported Bash version at startup when using version-specific features.
|
||||
- Prefer Bash builtins over unnecessary subprocesses.
|
||||
- Use `printf` rather than `echo -e`.
|
||||
- Use `[[ ... ]]` for Bash conditionals.
|
||||
- Use `(( ... ))` for arithmetic conditions.
|
||||
- Use `case` for command dispatch and finite state handling.
|
||||
- Use `local` for function-local variables.
|
||||
- Declare variables close to first use.
|
||||
- Use `readonly` for constants after configuration is loaded.
|
||||
- Use uppercase names only for exported variables and true constants.
|
||||
- Use lowercase snake_case for local variables and functions.
|
||||
- Give functions verb-based names such as `load_config` or `add_client`.
|
||||
- Keep functions focused and normally below about 60 lines.
|
||||
- Return statuses from functions; print data only when output is the contract.
|
||||
- Do not mix machine-readable results with progress messages.
|
||||
- Send errors and diagnostics to stderr.
|
||||
- Use explicit exit codes for expected CLI failure categories.
|
||||
|
||||
## Quoting and data handling
|
||||
|
||||
- Double-quote parameter expansions unless splitting is deliberately required.
|
||||
- Use `"${array[@]}"` when forwarding array elements.
|
||||
- Use arrays to build commands; never construct commands as strings.
|
||||
- Never use `eval`.
|
||||
- Never pass user-controlled text to `bash -c`.
|
||||
- Avoid command substitution for multiline or NUL-sensitive data.
|
||||
- Use `mapfile -t` for line-oriented command output when appropriate.
|
||||
- Use `IFS= read -r` to read literal lines.
|
||||
- Use `read -r -d ''` or NUL delimiters for arbitrary file names.
|
||||
- Use `--` before user-derived positional arguments where supported.
|
||||
- Do not rely on locale-sensitive parsing.
|
||||
- Set `LC_ALL=C` locally for command output that must be parsed predictably.
|
||||
- Do not parse human-formatted output when a stable dump format exists.
|
||||
- Prefer `wg show <interface> dump` for WireGuard state parsing.
|
||||
- Treat names, endpoints, addresses, paths, and config values as untrusted input.
|
||||
- Validate input with allowlists and semantic checks.
|
||||
- Reject control characters and embedded newlines in user input.
|
||||
- Never derive a filesystem path from an unchecked client name.
|
||||
- Canonicalize or constrain paths before reading or writing them.
|
||||
|
||||
## Configuration
|
||||
|
||||
- Keep server-specific values in `wg-manager.conf`.
|
||||
- Resolve the project directory from `${BASH_SOURCE[0]}`.
|
||||
- Do not depend on the caller's current working directory.
|
||||
- Do not silently overwrite administrator configuration.
|
||||
- Validate every required setting at startup.
|
||||
- Reject unknown enum values such as unsupported tunnel modes.
|
||||
- Validate numeric ranges before arithmetic use.
|
||||
- Validate IPv4, IPv6, CIDR, port, and hostname values before use.
|
||||
- Do not `source` a configuration file that may be writable by untrusted users.
|
||||
- If sourcing is retained, require root ownership and non-group/world-writable permissions.
|
||||
- Prefer a restricted `KEY=VALUE` parser for long-term safety.
|
||||
- Environment overrides must be documented and narrowly scoped.
|
||||
- Never accept key material through command-line arguments.
|
||||
- Avoid exporting secrets into the process environment.
|
||||
|
||||
## Temporary files and cleanup
|
||||
|
||||
- Create temporary files with `mktemp`.
|
||||
- Create mutation staging files on the same filesystem as the target.
|
||||
- Never use predictable temporary filenames.
|
||||
- Register cleanup immediately after creating temporary resources.
|
||||
- Use a cleanup function with `trap` for `EXIT`, `INT`, and `TERM`.
|
||||
- Quote trap bodies safely; avoid premature expansion.
|
||||
- Preserve the original exit status during cleanup.
|
||||
- Do not remove a path unless this process created it or validated it exactly.
|
||||
- Apply restrictive permissions before writing secret content.
|
||||
- Do not leave key material in world-readable temporary directories.
|
||||
|
||||
## WireGuard safety
|
||||
|
||||
- Require root only for commands that need privileged access or mutation.
|
||||
- Allow safe read-only commands without root when system permissions permit it.
|
||||
- Check that the configured interface and config file agree.
|
||||
- Identify peers by public key, not only by display name.
|
||||
- Treat comments such as `### Client NAME` as metadata, not identity.
|
||||
- Detect duplicate public keys and overlapping `AllowedIPs`.
|
||||
- Detect address collisions before generating any persistent file.
|
||||
- Distinguish managed peers from unmanaged peers.
|
||||
- Never modify an unmanaged peer implicitly.
|
||||
- Do not regenerate server keys automatically.
|
||||
- Do not rotate or replace client keys without explicit confirmation.
|
||||
- Never print private or preshared keys in routine output.
|
||||
- Never include key values in traces or debug logs.
|
||||
- Disable shell tracing around all secret-handling code.
|
||||
- Store client files with mode `0600`.
|
||||
- Keep directories containing client material at mode `0700`.
|
||||
|
||||
## Mutating operations
|
||||
|
||||
- Serialize mutations with `flock`.
|
||||
- Acquire the lock before re-reading mutable state.
|
||||
- Revalidate assumptions after the lock is acquired.
|
||||
- Create a backup before every persistent change.
|
||||
- Write the complete proposed config to a staging file.
|
||||
- Validate the staged config before replacing the live config.
|
||||
- Preserve the target owner, group, and restrictive mode.
|
||||
- Replace files atomically with a same-filesystem rename.
|
||||
- Apply the new configuration only after durable storage succeeds.
|
||||
- Verify active state after applying the change.
|
||||
- Roll back both disk and runtime state on failure.
|
||||
- Report rollback failure as a critical error.
|
||||
- Never append directly to the live WireGuard config.
|
||||
- Never use broad text deletion to remove a peer block.
|
||||
- Match an exact managed block and its public key.
|
||||
- Default to archiving client files instead of permanent deletion.
|
||||
- Require explicit confirmation before destructive or restorative actions.
|
||||
- Make repeated operations fail safely or behave idempotently.
|
||||
|
||||
## Backups and audit log
|
||||
|
||||
- Timestamp backups in an unambiguous UTC format.
|
||||
- Include the interface name in backup metadata or filenames.
|
||||
- Keep a bounded number of automatic backups.
|
||||
- Never prune the only known-good backup.
|
||||
- Validate a backup before offering restoration.
|
||||
- Back up the current state before restoring an older state.
|
||||
- Record who initiated a mutation when that information is available.
|
||||
- Log the operation, target, timestamp, outcome, and concise error.
|
||||
- Do not log private keys, preshared keys, or full client configs.
|
||||
- Avoid logging full environment dumps or command lines with secrets.
|
||||
- Make logs readable only by root by default.
|
||||
- Log failed mutations and rollback outcomes.
|
||||
|
||||
## CLI design
|
||||
|
||||
- TUI actions must call the same backend functions as CLI commands.
|
||||
- Keep CLI commands usable when `gum` is unavailable.
|
||||
- Provide `help` and useful usage errors.
|
||||
- Reject unknown commands and extra positional arguments.
|
||||
- Keep command names stable once documented.
|
||||
- Use stdout for requested data and stderr for warnings or progress.
|
||||
- Do not add decorative ANSI output when stdout is not a terminal.
|
||||
- Honor `NO_COLOR` for CLI colors where colors are used.
|
||||
- Return zero only when the requested operation succeeded.
|
||||
- Use distinct nonzero statuses for usage, validation, dependency, and runtime errors.
|
||||
- Avoid interactive prompts when a CLI command is explicitly noninteractive.
|
||||
- Require a confirmation flag for destructive noninteractive commands.
|
||||
- Never let localization change machine-parsed values or exit codes.
|
||||
|
||||
## TUI with gum
|
||||
|
||||
- Use `gum` as the only planned TUI framework.
|
||||
- Do not add `dialog`, `whiptail`, or a second TUI framework.
|
||||
- Do not download or install `gum` from the application.
|
||||
- Resolve `gum` in this order: `WG_MANAGER_GUM`, local `bin/gum`, then `PATH`.
|
||||
- Validate that the resolved path is executable.
|
||||
- Check required `gum` subcommands or minimum version at startup.
|
||||
- Fail with a clear message when TUI is requested without usable `gum`.
|
||||
- Keep all `gum` invocation details in small UI wrapper functions.
|
||||
- Backend functions must never call `gum` directly.
|
||||
- Use `gum choose` for short finite menus.
|
||||
- Use `gum filter` for searchable client selection.
|
||||
- Use `gum input` for short validated text fields.
|
||||
- Use `gum confirm` before deletion, restoration, or key rotation.
|
||||
- Use `gum table` only for display or selection, not as a data store.
|
||||
- Use `gum pager` for logs, diagnostics, and long text.
|
||||
- Use `gum spin` only when the wrapped operation can safely hide routine output.
|
||||
- Preserve stderr from failed commands behind a spinner.
|
||||
- Never show secret content inside a spinner command line.
|
||||
- Keep stable internal values separate from translated display labels.
|
||||
- Treat cancellation and Escape as normal control flow, not an error.
|
||||
- Return to the previous screen after cancellation.
|
||||
- Do not trap users in an endless menu loop after repeated failures.
|
||||
- Keep the main menu shallow and task-oriented.
|
||||
- Show interface name and current status on the main screen.
|
||||
- Use consistent verbs: view, add, remove, diagnose, restore, exit.
|
||||
- Show the exact target before asking for destructive confirmation.
|
||||
- Require stronger confirmation for restoring backups or deleting client material.
|
||||
- Keep colors readable on light and dark terminals.
|
||||
- Do not communicate status by color alone.
|
||||
- Keep layouts usable at 80 columns.
|
||||
- Avoid assumptions about mouse support.
|
||||
- Do not clear valuable terminal output after an error.
|
||||
- Detect noninteractive stdin or stdout before starting TUI.
|
||||
- Never emit TUI control output into pipelines or redirected files.
|
||||
|
||||
## Error handling
|
||||
|
||||
- Provide one concise user-facing error plus actionable context.
|
||||
- Preserve the failing command's status where meaningful.
|
||||
- Do not expose secret variable values in error messages.
|
||||
- Distinguish validation errors from system failures.
|
||||
- Distinguish skipped diagnostic checks from successful checks.
|
||||
- Diagnostic results use `OK`, `WARN`, `FAIL`, or `SKIP`.
|
||||
- A critical diagnostic failure must produce a nonzero status.
|
||||
- Include remediation guidance when it is reliable and specific.
|
||||
- Avoid guessing firewall fixes across distributions.
|
||||
- Continue independent diagnostic checks after a nonfatal failure.
|
||||
|
||||
## Dependencies and portability
|
||||
|
||||
- Assume a Linux server with Bash and WireGuard tools.
|
||||
- Keep required dependencies listed in `MVP.md` and README.
|
||||
- Treat `qrencode`, systemd, `nft`, and `iptables` as optional capabilities.
|
||||
- Detect optional commands before using them.
|
||||
- Do not fail the entire diagnostic run because one optional tool is absent.
|
||||
- Prefer feature detection over distribution detection.
|
||||
- Do not assume systemd is PID 1 on every supported server.
|
||||
- Support at least Linux `x86_64`; document additional tested architectures.
|
||||
- Do not assume the bundled `gum` binary matches the current architecture.
|
||||
- Report architecture mismatch clearly.
|
||||
|
||||
## Tests
|
||||
|
||||
- Add regression tests for every fixed bug.
|
||||
- Tests must not modify the host's real `/etc/wireguard`.
|
||||
- Use fixtures for server configs, peer blocks, and metadata.
|
||||
- Mock external commands through a controlled test `PATH`.
|
||||
- Cover `wg`, `wg-quick`, `ip`, `systemctl`, `journalctl`, `nft`, and `iptables` as needed.
|
||||
- Test success, expected failure, rollback, and interruption paths.
|
||||
- Test client names containing spaces, newlines, glob characters, and option prefixes.
|
||||
- Test duplicate keys, duplicate IPs, and overlapping networks.
|
||||
- Test empty peer lists and unmanaged peers.
|
||||
- Test CLI behavior without `gum`.
|
||||
- Test local binary, environment override, and `PATH` resolution for `gum`.
|
||||
- Test that logs do not contain generated secrets.
|
||||
- Test concurrent mutation attempts.
|
||||
- Test restoration failure and failed rollback reporting.
|
||||
- Keep tests deterministic; do not depend on external network access.
|
||||
- Use temporary test directories and remove them safely.
|
||||
|
||||
## Quality gates
|
||||
|
||||
- Run `bash -n` on every changed shell script.
|
||||
- Run ShellCheck on every changed shell script when available.
|
||||
- Run the relevant automated tests.
|
||||
- Format consistently; use `shfmt` when the project adopts a fixed style.
|
||||
- Do not silence ShellCheck globally to hide local problems.
|
||||
- Add a narrow inline suppression only with an explanatory comment.
|
||||
- Review diffs for accidental key material before finishing.
|
||||
- Review file permissions in tests that create secrets.
|
||||
- Verify that failure paths preserve the original config.
|
||||
- Verify CLI output with stdout redirected.
|
||||
- Verify TUI entry and cancellation in an interactive terminal.
|
||||
|
||||
## Documentation
|
||||
|
||||
- Update `MVP.md` only when product scope or architecture changes.
|
||||
- Keep operational usage in README once implementation begins.
|
||||
- Document every CLI command and its exit behavior.
|
||||
- Document required and optional dependencies separately.
|
||||
- Include examples that use placeholder keys and addresses only.
|
||||
- Never commit real endpoints, private keys, preshared keys, or client configs.
|
||||
- Explain backup and restore behavior before users rely on it.
|
||||
- Document limitations of handshake history and traffic visibility.
|
||||
|
||||
## Definition of done
|
||||
|
||||
- The requested behavior is implemented through shared backend functions.
|
||||
- Mutations are locked, validated, backed up, atomic, and reversible.
|
||||
- CLI operation remains available independently of the TUI.
|
||||
- TUI uses the configured `gum` resolution order.
|
||||
- Errors are actionable and do not reveal secrets.
|
||||
- Relevant tests pass.
|
||||
- `bash -n` passes.
|
||||
- ShellCheck has no unexplained findings.
|
||||
- Documentation matches observable behavior.
|
||||
- No unrelated files or user changes are overwritten.
|
||||
Reference in New Issue
Block a user