All checks were successful
check / check (pull_request) Successful in 2m46s
Entry writes the banner to stdout before cobra parses anything, and the scan that decides whether to write it knew --quiet, -q and --cron but not --json. Every --json document therefore arrived behind two lines of prose and a blank line, and `vaultik snapshot list --json | jq` failed. Passing opts.JSON as extraQuiet could not help: that reaches UI.SetQuiet through an fx OnStart hook, long after the banner is already written. With the logger moved to stderr in #82, this was the last writer that could put something on stdout the caller did not ask for. The design question the issue raised is answered in favour of extending the raw-argv scan rather than moving the banner after parsing. The banner is printed first deliberately, so that it still appears when cobra rejects the arguments and on --help; after parsing there is no single place that covers those paths, so "after parsing" means either reimplementing the banner in several handlers or losing it exactly where a human most wants to know which build just ran. The objection to the scan is that --json is a subcommand flag matched anywhere in the vector, but --cron is already in the list and is also a subcommand flag: it exists only on `snapshot create`. So this adds another instance of an imprecision the code already accepts, not a new kind of one. The two error directions are not symmetric either — a false positive loses a decorative banner, a false negative corrupts a document — so the scan errs toward suppression, and --json=false suppresses it exactly as --quiet=false already does. Three tests at the CLI layer, where internal/vaultik's existing guard cannot reach. TestEntryJSONStdoutIsExactlyOneDocument runs Entry itself over the process's real stdout descriptor, through cobra and the fx graph to the document, and asserts the capture decodes as one JSON value with nothing after it; it is hermetic because file:// storage needs no credentials and `snapshot list` treats a destination store with no metadata/ as an empty list rather than a failure. A second covers the argument vectors of all five --json commands plus the pre-subcommand and --json=true forms. A third asserts the banner is still printed without a suppressing flag, so the first cannot be satisfied by deleting it. AGENTS.md policy 9 still keyed the structured-log format on stdout's TTY-ness after #82 moved that decision to stderr; it now names the log stream. A rules file that misdescribes the code misleads exactly the readers who trust it most. Two smaller findings from the same review. bytesAttrKey's human-readable byte formatting stopped applying under an open group, because the key reaching the comparison is group-qualified: "bytes" logged under a group arrives as "transfer.bytes" and fell back to a bare number. The match is now made on the final dot-separated segment, tested both grouped and ungrouped. And listEnv.stderr in snapshot_list_test.go, assigned but never read since those tests began capturing the process's stderr, is removed. Vaultik.Stderr is kept — nothing writes to it today, which its comment now says outright rather than leaving the next reader to hunt for a writer that does not exist. `prune --json` still does not survive jq, for an unrelated reason found while verifying this: pruneLocalSnapshots writes three lines of prose to stdout with no --json awareness, on main and after this change alike, and -q never suppressed them either. Filed as #108 rather than fixed here, being a different writer on a different code path.
111 lines
5.2 KiB
Markdown
111 lines
5.2 KiB
Markdown
# 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.md` file 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
|
|
|
|
1. 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 use `go fmt` and `go test -v ./...` and
|
|
`golangci-lint run`. Each Makefile target does exactly one thing — to
|
|
run lint + fmt-check + test together (the standard pre-commit gate),
|
|
use `make check`.
|
|
|
|
2. Always write a `Makefile` with the default target being `test`, and with
|
|
a `fmt` target that formats the code. The `test` target should run all
|
|
tests in the project, and the `fmt` target should format the code.
|
|
`test` should also have a prerequisite target `lint` that should run any
|
|
linters that are configured for the project.
|
|
|
|
3. 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.
|
|
|
|
4. 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.
|
|
|
|
5. 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.
|
|
|
|
6. 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.
|
|
|
|
7. 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.
|
|
|
|
8. 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.
|
|
|
|
9. 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.
|
|
|
|
10. 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.
|
|
|
|
11. 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.
|
|
|
|
12. 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.
|
|
|
|
13. 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.
|
|
|