The banner is printed to stdout before cobra parses, and bannerSuppressedInArgs recognised only --quiet, -q and --cron. So every --json document was preceded by two banner lines and a blank one, and `vaultik snapshot list --json | jq` failed. Passing opts.JSON as extraQuiet did not help: that calls UI.SetQuiet in an fx OnStart hook, long after Entry has printed. The raw-argv scan is extended rather than the banner moved after parsing. root.go documents that the banner must survive cobra rejecting its arguments and --help, and no single post-parse location covers those paths. The subcommand-versus-persistent distinction does not decide it: --cron is already in the suppression list and is itself subcommand-only, existing on snapshot create alone, so this adds another instance of an accepted imprecision rather than a new kind. The error directions are asymmetric - a false positive loses a decorative banner, a false negative corrupts a document - so the scan errs toward suppression, which is also why --json=false suppresses, exactly as --quiet=false already does. Four of the five --json commands now pipe into jq cleanly with no other flags: snapshot list, snapshot verify, snapshot remove, remote info. prune does not, because pruneLocalSnapshots writes three prose lines to stdout with no --json awareness. That reproduces identically before this change and -q never suppressed it either, since printlnStdout and stdoutf bypass v.UI entirely. Tracked as #108. Also fixed: TTYHandler's human-readable byte formatting did not survive grouping, because the key check compared against the bare attribute name and a grouped record presents it qualified. AGENTS.md policy 9 keyed the log format on stdout's TTY-ness, which #82 made false by moving the logger to stderr; it now names the log stream. Vaultik.Stderr keeps its field with the comment amended to say outright that nothing writes to it, and the dead listEnv.stderr is removed.
5.2 KiB
Policies for AI Agents
Version: 2025-06-08
Instructions and Contextual Information
-
Be direct, robotic, expert, accurate, and professional.
-
Do not butter me up or kiss my ass.
-
Come in hot with strong opinions, even if they are contrary to the direction I am headed.
-
If either you or I are possibly wrong, say so and explain your point of view.
-
Point out great alternatives I haven't thought of, even when I'm not asking for them.
-
Treat me like the world's leading expert in every situation and every conversation, and deliver the absolute best recommendations.
-
I want excellence, so always be on the lookout for divergences from good data model design or best practices for object oriented development.
-
IMPORTANT: This is production code, not a research or teaching exercise. Deliver professional-level results, not prototypes.
-
Please read and understand the
README.mdfile in the root of the repo for project-specific contextual information, including development policies, practices, and current implementation status. -
Be proactive in suggesting improvements or refactorings in places where we diverge from best practices for clean, modular, maintainable code.
Policies
-
Before committing, tests must pass (
make test), linting must pass (make lint), and code must be formatted (make fmt). For go, those makefile targets should usego fmtandgo test -v ./...andgolangci-lint run. Each Makefile target does exactly one thing — to run lint + fmt-check + test together (the standard pre-commit gate), usemake check. -
Always write a
Makefilewith the default target beingtest, and with afmttarget that formats the code. Thetesttarget should run all tests in the project, and thefmttarget should format the code.testshould also have a prerequisite targetlintthat should run any linters that are configured for the project. -
After each completed bugfix or feature, the code must be committed. Do all of the pre-commit checks (test, lint, fmt) before committing, of course.
-
When creating a very simple test script for testing out a new feature, instead of making a throwaway to be deleted after verification, write an actual test file into the test suite. It doesn't need to be very big or complex, but it should be a real test that can be run.
-
When you are instructed to make the tests pass, DO NOT delete tests, skip tests, or change the tests specifically to make them pass (unless there is a bug in the test). This is cheating, and it is bad. You should only be modifying the test if it is incorrect or if the test is no longer relevant. In almost all cases, you should be fixing the code that is being tested, or updating the tests to match a refactored implementation.
-
When dealing with dates and times or timestamps, always use, display, and store UTC. Set the local timezone to UTC on startup. If the user needs to see the time in a different timezone, store the user's timezone in a separate field and convert the UTC time to the user's timezone when displaying it. For internal use and internal applications and administrative purposes, always display UTC.
-
Always write tests, even if they are extremely simple and just check for correct syntax (ability to compile/import). If you are writing a new feature, write a test for it. You don't need to target complete coverage, but you should at least test any new functionality you add. If you are fixing a bug, write a test first that reproduces the bug, and then fix the bug in the code.
-
When implementing new features, be aware of potential side-effects (such as state files on disk, data in the database, etc.) and ensure that it is possible to mock or stub these side-effects in tests.
-
Always use structured logging. Log any relevant state/context with the messages (but do not log secrets). If the log stream is not a terminal, output the structured logs in jsonl format.
-
Avoid using bare strings or numbers in code, especially if they appear anywhere more than once. Always define a constant (usually at the top of the file) and give it a descriptive name, then use that constant in the code instead of the bare string or number.
-
You do not need to summarize your changes in the chat after making them. Making the changes and committing them is sufficient. If anything out of the ordinary happened, please explain it, but in the normal case where you found and fixed the bug, or implemented the feature, there is no need for the end-of-change summary.
-
Do not create additional files in the root directory of the project without asking permission first. Configuration files, documentation, and build files are acceptable in the root, but source code and other files should be organized in appropriate subdirectories.
-
Pre-1.0: NEVER write database migrations. There are no live databases anywhere — every user's local index can be rebuilt from a fresh full backup. When the schema changes, just change
schema.sql(and any code that touches the affected tables). The local index is disposable until 1.0 ships and is tagged.