Commit Graph
14 Commits
Author SHA1 Message Date
kevinveenbirkenbachandClaude Opus 5 a018e88468 style(lint): state the zip invariant the comment lint relies on
ruff B905 flagged zip(comments, spans) without strict=. spans is built by a comprehension over comments, so the two can only ever be the same length; strict=True can never fire and records that, while a future edit that breaks the pairing now fails loudly instead of silently truncating the shorter side.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 03:22:04 +02:00
kevinveenbirkenbachandClaude Opus 5 b36ef6bfc4 fix(lint): stop reporting a comment nested inside another comment
Two collectors run over a .j2 template, so the closing '#}' of a Jinja
block was also a standalone '#' comment to the line-based one. The
header rule protects the opening '{#' but not a closer 22 lines down,
so the fragment got reported, deleted, and the template ended up inside
an unterminated comment: it rendered to nothing while every parser
stayed happy.

_drop_nested drops any comment whose line span is a proper subset of
another's, so the enclosing comment always wins.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 03:22:01 +02:00
kevinveenbirkenbachandClaude Opus 5 23ef231f7e test(lint): check comments in every file, not only changed ones
The linter only saw the working-tree diff, so 3529 invalid comments in
528 files never broke a build. It now enumerates git ls-files, and the
policy holds for the whole repository.

Two changes ride along, both required to make that scope survivable:

_css_comments never closed a /* */ block on the line that opened it, so
every single-line CSS comment swallowed the following code as its body.
The reported spans were unusable for anything but counting.

A single comment line directly above a key in defaults/*.yml,
vars/*.yml or group_vars/ now counts as that variable's doc, the way a
docstring counts above a function. Two lines are a block again and stay
flagged, and the carve-out holds nowhere else.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 03:22:01 +02:00
kevinveenbirkenbachandClaude Opus 5 efe6bad3d5 test(lint): require a written rationale for every async
An async task is a deployment wide decision taken in one line. Whether it
holds depends on things the line does not show: in swarm a delegated
command crosses a node boundary and runs far longer than the same command
in compose, so a window that never opens on one node routinely opens
across three, and the playwright run starts the moment the play ends, so a
command still writing in the background surfaces as a flaky spec rather
than a failed task.

Require one sentence per async naming what does not consume the result.
"It is slow" is why async is tempting, never why it is safe, and the
docstring says so. There is no nocheck escape: a task that cannot be given
the sentence has not earned its async.

The comment lint learns `rationale:` as a marker so those lines are not
read as narration. It is deliberately narrower than the exception marker
next to it: a rationale is demanded by another lint that refuses the
construct without it, so it cannot be self granted, which is exactly the
failure mode of comments that explain themselves.

This lands after the change it describes, so every commit stays green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-03 04:05:38 +02:00
kevinveenbirkenbachandClaude Opus 4.8 16aa00d905 refactor(deploy-cli): split deploy.py into a per-responsibility package
One module per concern, mirroring the inventory/ subpackage layout:
run.py (single deploy pass + env forwarding SPOT), drill.py (recover
drill, host mode exempt, paths from CONTAINER_REPO_ROOT instead of a
hardcoded /opt/src/infinito), purge.py (inter-round cleanup) and
cli.py (arg parsing + round/pass loop, PASS 1/2 deduplicated).

Also extend the comment linter to flag bare string-expression
statements outside docstring position in Python: a triple-quoted
literal floating in a body is a comment in disguise and now runs
through the same validity rules; docstrings and PEP 224 attribute
docstrings stay allowed. Test narration comments moved into method
docstrings accordingly, and the design docs now link deploy/cli.py.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 05:20:54 +02:00
kevinveenbirkenbachandClaude Opus 4.8 ab53a8b847 feat(lint): recognize hadolint directives and nocheck-based raw-docker opt-outs
The comment lint learns hadolint as a directive class so 'hadolint ignore=' lines survive comment audits, and the compose raw-docker lint drops its path whitelist in favor of the same '# nocheck: raw-docker' head/inline suppression the docker variant already honors.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 23:04:41 +02:00
kevinveenbirkenbachandClaude Opus 4.8 9ecb2f8f5e test(lint): cover Dockerfiles in the comments lint
Dockerfiles have no suffix, so the comments lint never scanned them. Match the Dockerfile basename in the changed-targets collector and dispatch it to the hash-comment parser; changed-files-only semantics stay, so the legacy tree is unaffected until a Dockerfile is touched. Drop the remaining prose comment from the espocrm Dockerfile it immediately flagged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 02:37:27 +02:00
kevinveenbirkenbachandClaude Opus 4.8 e704e9a74d chore: autoformat + lint fixes; drop Invariant comment marker
autoformat reformats (settings sort, complexity/model.py, test_database_query.py, keycloak vars wrap); shorten akaunting swarm task name to <=80 chars; delete narration comments from keycloak vars; remove 'invariant' from the comment linter's valid marker set. make autoformat + make test verified green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 02:54:20 +02:00
kevinveenbirkenbachandClaude Opus 4.8 f02da33128 fix(ci): clear compose deploy-gate deprecation warnings + tighten comment markers
The test-deploy-compose "Fail on deprecation warnings" gate failed ~10 apps
while the deploys themselves succeeded. Sources cleared:

- svc-db-postgres: community.postgresql `db` -> `login_db` (the `db` param
  alias is deprecated, removed in collection 5.0.0)
- assert_no_deprecation_warnings.sh: ignore ansible-core's legacy filter/test
  PluginLoader-aliases deprecation (needs a collection migration with
  meta/runtime.yml, not fixable in role YAML)
- joomla/wordpress: drop the `{{ }}` delimiters from task conditionals
  (when/until/changed_when), per ansible-core 2.23

Also drop `upstream`/`compat`/`security`/`bug` from the comment-policy markers
and delete those comments from the joomla install tasks.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 22:48:26 +02:00
kevinveenbirkenbachandClaude Opus 4.8 8390cc4ce4 test(comments): lint .j2 templates and add file-level nocheck opt-out
Drop trap/warning from the exception markers; lint .j2 by stripping the suffix to the underlying language plus Jinja {# #} comments; add a head-level '# nocheck: comments-valid' opt-out via is_suppressed_in_head, documented in suppression.md; strip narration comments from friendica/nextcloud templates and opt the vendored discourse app.yml out with the new marker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 12:24:18 +02:00
kevinveenbirkenbachandClaude Opus 4.8 e11bf6f31b refactor(lint): drop caveat/workaround comment markers
Remove caveat and workaround from the comment-lint marker vocabulary and delete
the comments that used them across the tree. Move test_comments_valid's own
git-safe.directory note from a marked comment into the function docstring.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 21:54:10 +02:00
kevinveenbirkenbachandClaude Opus 4.8 23d1447566 refactor(ansible): add path_absolute lookup, replace playbook_dir joins
Introduce plugins/lookup/path_absolute.py as the single source for the
repo-root anchor: lookup('path_absolute', 'roles/...') returns an absolute
path under playbook_dir, joining every term. Replace all hand-built
playbook_dir path constructions across .yml/.yaml and .j2 templates with it:

  [playbook_dir, '<rel>'] | path_join   -> lookup('path_absolute', '<rel>')
  playbook_dir ~ '/<rel>'               -> lookup('path_absolute', '<rel>')
  {{ playbook_dir }}/<rel>              -> lookup('path_absolute', '<rel>')

Unrelated repo_path symbols in cli/meta/roles/applications/resolution and the
single bare discover_playwright_roles(playbook_dir) call are left untouched.

Add tests/lint/ansible/test_playbook_dir_via_lookup.py: fails the build if any
of the three construction forms reappears in .yml/.yaml/.j2, pointing callers
at the lookup. Unit test covers the plugin.

Touching these files pulled their pre-existing narration comments into
test_comments_valid scope; clean them (delete restatement/banners, keep real
trip-wires as Workaround/Upstream/Invariant markers). Drop caution, important
and pitfall from the comment-lint marker vocabulary and remove the comments
that used them.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 20:36:57 +02:00
kevinveenbirkenbachandClaude Opus 4.8 6eb1ce58e7 fix(lint): make comment-policy linter enforce in CI
test_comments_valid.py scopes to the working-tree diff via 'git diff --name-only HEAD', but the make-test container mounts the repo as a different uid, so git aborted with 'dubious ownership' and the linter silently scanned zero files. Pass '-c safe.directory=*' so it runs. Also drop 'gotcha' from the accepted exception markers.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 16:37:55 +02:00
kevinveenbirkenbachandClaude Opus 4.8 e55fb78f15 test(lint): comment-policy linter scoped to changed files
Add tests/lint/repository/test_comments_valid.py: across .py/.sh/.yml/.rb/
.php/.css, a comment is valid only as a file header, a doc comment directly
above a class/function/rule, a tool directive, or a mid-code EXCEPTION that
flags a real trip-wire (text starts with Warning/Exception/Caution/Gotcha/
Workaround/Security/Important/...). Plain narration, banners, commented-out
code and neutral notes are rejected.

Scope is the working-tree diff (staged + unstaged + untracked vs HEAD): the
legacy tree is grandfathered in and never breaks the build, while every file a
change touches must comply going forward. Python is parsed with tokenize
(string-aware); a multi-line trip-wire's marker on its first line validates the
whole block.

Also fold in autoformat normalization of 11 meta/{csp,domains,server}.yml files.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 22:45:06 +02:00