-
Notifications
You must be signed in to change notification settings - Fork 4
Improve the documentation of (required) for maps and repeated fields
#929
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
8d872e7
Document empty-key entries as missing for `(required) map<string, V>`
alexander-yevsyukov 4519e54
Improve description of `(required)` for maps
alexander-yevsyukov 455cb70
Bump version -> `2.0.0-SNAPSHOT.390`
alexander-yevsyukov 15a0ecd
Update dependency reports
alexander-yevsyukov aa0ba75
Improve documenation of `(required)` option for `repeated` and `map` …
alexander-yevsyukov 0e274f0
Update `config`
alexander-yevsyukov e199d1c
Update build time
alexander-yevsyukov 94e59af
Document that `bytes` elements/values are treated similarly to `string`s
alexander-yevsyukov 94f8819
Update build time
alexander-yevsyukov File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| # Team memory index | ||
|
|
||
| One line per memory. Scan at the start of every session. | ||
| See [README.md](README.md) for the format and routing rules. | ||
|
|
||
| ## Feedback (validated patterns & corrections) | ||
|
|
||
| *(no entries yet)* | ||
|
|
||
| ## Project (durable context & rationale) | ||
|
|
||
| *(no entries yet)* | ||
|
|
||
| ## Reference (external systems) | ||
|
|
||
| *(no entries yet)* |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| # Team memory — `.agents/memory/` | ||
|
|
||
| Validated patterns, durable project context, and pointers to external | ||
| systems. Checked into git so the whole team — and any agent working in | ||
| this repo — benefits from accumulated knowledge. | ||
|
|
||
| This complements Claude Code's built-in per-developer auto-memory: | ||
| team-shareable knowledge lives here; personal preferences and ephemeral | ||
| state live in the auto-memory. | ||
|
|
||
| ## Layout | ||
|
|
||
| .agents/memory/ | ||
| ├── MEMORY.md # Index — scan at start of every session | ||
| ├── README.md # This file — read when adding/updating memories | ||
| ├── feedback/ # Validated patterns & corrections | ||
| ├── project/ # Durable project context & rationale | ||
| └── reference/ # External systems & resources | ||
|
|
||
| One file per memory. Filename = the memory's kebab-case slug. | ||
|
|
||
| ## File format | ||
|
|
||
| --- | ||
| name: tests-no-db-mocks | ||
| description: One-line summary — used to surface relevance, so be specific. | ||
| metadata: | ||
| type: feedback # feedback | project | reference | ||
| since: 2026-05-19 # date added (ISO) | ||
| --- | ||
|
|
||
| <one-paragraph rule or fact> | ||
|
|
||
| **Why:** <reason — incident, constraint, team convention> | ||
|
|
||
| **How to apply:** <when this kicks in; what to do or avoid> | ||
|
|
||
| Related: [[other-memory-slug]] | ||
|
|
||
| `Why:` and `How to apply:` are required for `feedback` and `project` | ||
| memories — they let future readers judge edge cases. `reference` | ||
| memories may be shorter (link + one-line purpose). | ||
|
|
||
| Link related memories with `[[slug]]` (the target file's `name:`). | ||
|
|
||
| ## Routing — repo vs. auto-memory | ||
|
|
||
| | Kind of fact | Goes to | | ||
| |---|---| | ||
| | Personal preference, role, style | auto-memory (`user`) | | ||
| | Personal habit feedback | auto-memory (`feedback`) | | ||
| | Team coding/test/PR rule | **`feedback/`** | | ||
| | Durable project rationale | **`project/`** | | ||
| | Ephemeral project state (freezes, OOO, deadlines) | auto-memory (`project`) — would rot in git | | ||
| | Team-shared external resource | **`reference/`** | | ||
| | Personal external resource | auto-memory (`reference`) | | ||
|
|
||
| **Litmus test:** *would a teammate joining the project next month benefit | ||
| from knowing this?* If no, it belongs in auto-memory. | ||
|
|
||
| ## Write protocol | ||
|
|
||
| 1. Write the file **uncommitted** in the working tree. | ||
| 2. **Surface the change** in the same turn so the human can review. | ||
| 3. **Do not auto-commit** memory edits as part of an unrelated PR — memory | ||
| changes should be reviewable on their own. | ||
| 4. **Correct in place** when an existing memory turns out wrong; `git blame` | ||
| carries the history. | ||
| 5. **Propose deletion explicitly** when a memory has gone stale, rather | ||
| than silently editing it out. | ||
|
|
||
| ## Updating the index | ||
|
|
||
| After adding or removing a memory file, update `MEMORY.md`. One line under | ||
| the matching section: | ||
|
|
||
| - [slug](category/slug.md) — description from frontmatter | ||
|
|
||
| Keep the index short — long descriptions belong in the file body. | ||
|
|
||
| ## Anti-patterns — do not store | ||
|
|
||
| - Anything derivable from the code (module structure, paths, conventions | ||
| visible in source). Use `grep` / `Read`. | ||
| - Recent-activity summaries or PR lists — `git log` is authoritative. | ||
| - Fix recipes for specific bugs — the commit message belongs in the commit. | ||
| - Anything already documented in `.agents/` reference docs — keep one | ||
| source of truth. | ||
| - Personal preferences (see routing). |
Empty file.
Empty file.
Empty file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| #!/usr/bin/env bash | ||
| # | ||
| # PreToolUse hook: block `gh pr create` unless /pre-pr has successfully run | ||
| # for the current HEAD. The hook is intentionally unaware of the repository's | ||
| # versioning or build system; the /pre-pr skill decides which checks apply. | ||
| # | ||
| # Input: hook JSON on stdin (tool_name, tool_input.command). | ||
| # Exit: 0 to allow, 2 to block (stderr is surfaced to Claude). | ||
| # | ||
| set -eu | ||
|
|
||
| input=$(cat) | ||
| tool=$(printf '%s' "$input" | jq -r '.tool_name // empty') | ||
| [ "$tool" != "Bash" ] && exit 0 | ||
|
|
||
| cmd=$(printf '%s' "$input" | jq -r '.tool_input.command // empty') | ||
|
|
||
| # Split the command on shell separators (`;`, `&`, `|` — `&&`/`||` collapse | ||
| # to repeated newlines, which is fine) and check each segment. Only block | ||
| # when a segment STARTS (after optional whitespace) with `gh pr create`. | ||
| # This avoids false positives like `echo "gh pr create"` or test fixtures | ||
| # that mention the string, while still catching `cd dir && gh pr create` | ||
| # and `cat body | gh pr create`. `tr` is used (not `sed s///`) because | ||
| # BSD `sed` on macOS does not interpret `\n` in the replacement string. | ||
| if ! printf '%s' "$cmd" \ | ||
| | tr ';&|' '\n\n\n' \ | ||
| | grep -qE '^[[:space:]]*gh[[:space:]]+pr[[:space:]]+create([[:space:]]|$)'; then | ||
| exit 0 | ||
| fi | ||
|
|
||
| repo_root=$(git rev-parse --show-toplevel 2>/dev/null) || exit 0 | ||
| sentinel="$repo_root/.git/pre-pr.ok" | ||
|
|
||
| block() { | ||
| cat >&2 | ||
| exit 2 | ||
| } | ||
|
|
||
| if [ ! -f "$sentinel" ]; then | ||
| block <<EOF | ||
| 'gh pr create' blocked: pre-PR checks have not run on this clone. | ||
|
|
||
| Run /pre-pr first. It runs the applicable build/check command, applies the | ||
| version gate only when this repository has a root version.gradle.kts, dispatches | ||
| the configured reviewers, then writes $sentinel on success. | ||
| EOF | ||
| fi | ||
|
|
||
| sentinel_status=$(awk -F= '/^status=/{print $2}' "$sentinel") | ||
| sentinel_sha=$(awk -F= '/^head=/{print $2}' "$sentinel") | ||
| head_sha=$(git -C "$repo_root" rev-parse HEAD) | ||
|
|
||
| if [ "$sentinel_status" != "PASS" ]; then | ||
| block <<EOF | ||
| 'gh pr create' blocked: the last /pre-pr run reported status='$sentinel_status'. | ||
|
|
||
| Fix the issues and re-run /pre-pr before creating the PR. | ||
| Sentinel: $sentinel | ||
| EOF | ||
| fi | ||
|
|
||
| if [ "$sentinel_sha" != "$head_sha" ]; then | ||
| block <<EOF | ||
| 'gh pr create' blocked: /pre-pr was last run at commit | ||
| $sentinel_sha | ||
| but HEAD is now | ||
| $head_sha | ||
|
|
||
| Re-run /pre-pr to revalidate the current tree. | ||
| EOF | ||
| fi | ||
|
|
||
| exit 0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| #!/usr/bin/env bash | ||
| # | ||
| # PreToolUse hook: block direct Edit/Write/MultiEdit on `version.gradle.kts`. | ||
| # In repositories that have this file, the bump-version skill owns the | ||
| # version-bump policy (snapshot numbering, rebuilds, dependency-report updates, | ||
| # conflict resolution). Repositories without it must not add it just to satisfy | ||
| # hooks or reviewers. | ||
| # | ||
| # Input: hook JSON on stdin. Claude edit tools pass `tool_input.file_path`; | ||
| # Codex `apply_patch` passes the patch text in `tool_input.command`. | ||
| # Exit: 0 to allow, 2 to block with stderr message surfaced to the agent. | ||
| # | ||
| set -eu | ||
|
|
||
| input=$(cat) | ||
| file=$(printf '%s' "$input" | jq -r '.tool_input.file_path // empty') | ||
| command=$(printf '%s' "$input" | jq -r '.tool_input.command // empty') | ||
|
|
||
| touches_version_file() { | ||
| if [ "$file" = "version.gradle.kts" ] || [ "${file%/version.gradle.kts}" != "$file" ]; then | ||
| return 0 | ||
| fi | ||
|
|
||
| printf '%s\n' "$command" \ | ||
| | grep -qE '^\*\*\* (Add|Update|Delete) File: (.+/)?version\.gradle\.kts$' | ||
| } | ||
|
|
||
| if touches_version_file; then | ||
| cat >&2 <<'EOF' | ||
| Direct edits to version.gradle.kts are blocked by a project hook. | ||
|
|
||
| If this repository already has a root version.gradle.kts, use the bump-version | ||
| skill instead: | ||
| /bump-version [snapshot|minor|major] | ||
|
|
||
| If this repository does not have a root version.gradle.kts, do not add one just | ||
| to satisfy /pre-pr; the version check is not applicable. | ||
|
|
||
| See: | ||
| - .agents/version-policy.md | ||
| - .agents/skills/bump-version/SKILL.md | ||
| EOF | ||
| exit 2 | ||
| fi | ||
|
|
||
| exit 0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| #!/usr/bin/env bash | ||
| # | ||
| # PreToolUse hook: block any `./gradlew` invocation that could publish to | ||
| # Maven Local without a version bump on the current branch. Wraps the | ||
| # Layer-1 deterministic check at `version-bumped.sh`. | ||
| # | ||
| # This is intentionally broad: it fires on `build`, `publish`, | ||
| # `publishToMavenLocal`, and any `:publish*` task. Many repos in this | ||
| # constellation chain `publishToMavenLocal` into `build` because | ||
| # integration tests consume those local artifacts, so `build` itself is | ||
| # publish-risky. False positives (blocking a pure compile) are preferable | ||
| # to overwriting a previously published snapshot that consuming repos | ||
| # rely on. | ||
| # | ||
| # Input: hook JSON on stdin (tool_name, tool_input.command). | ||
| # Exit: 0 to allow, 2 to block (stderr is surfaced to Claude). | ||
| # | ||
| set -eu | ||
|
|
||
| input=$(cat) | ||
| tool=$(printf '%s' "$input" | jq -r '.tool_name // empty') | ||
| [ "$tool" != "Bash" ] && exit 0 | ||
|
|
||
| cmd=$(printf '%s' "$input" | jq -r '.tool_input.command // empty') | ||
|
|
||
| # Split the command on shell separators (`;`, `&`, `|`) and inspect each | ||
| # segment. Only block when a segment, after optional whitespace, invokes | ||
| # `./gradlew` (or `./config/gradlew`) with a publish-risky task. Avoids | ||
| # false positives on `echo "./gradlew build"` or fixtures. | ||
| risky_segment() { | ||
| local seg="$1" | ||
| # Must start with a gradlew invocation. | ||
| printf '%s' "$seg" | grep -qE '^[[:space:]]*\.?/?(config/)?gradlew([[:space:]]|$)' || return 1 | ||
| # Must mention a publish-risky task. `build` is risky because it can | ||
| # finalize publishToMavenLocal in this config. The leading | ||
| # `(:[A-Za-z0-9_.-]+)*:?` covers qualified task paths | ||
| # (e.g. `:module:build`, `:a:b:publishToMavenLocal`) and a single | ||
| # leading-colon form (`:publishMavenJavaPublicationToMavenLocal`). | ||
| # `publish[^[:space:]]*` then catches every publish-task variant. | ||
| printf '%s' "$seg" | grep -qE '(^|[[:space:]])(:[A-Za-z0-9_.-]+)*:?(build|publish[^[:space:]]*|publishToMavenLocal|publishAllPublicationsToMavenLocal)([[:space:]]|$)' | ||
| } | ||
|
|
||
| block_needed=0 | ||
| # `|| [ -n "$segment" ]` makes the loop process the final segment when the | ||
| # input has no trailing newline (which is the case for `printf '%s'`). | ||
| while IFS= read -r segment || [ -n "$segment" ]; do | ||
| if risky_segment "$segment"; then | ||
| block_needed=1 | ||
| break | ||
| fi | ||
| done < <(printf '%s' "$cmd" | tr ';&|' '\n\n\n') | ||
|
|
||
| [ "$block_needed" -eq 0 ] && exit 0 | ||
|
|
||
| repo_root=$(git rev-parse --show-toplevel 2>/dev/null) || exit 0 | ||
| script="$repo_root/.agents/skills/version-bumped/scripts/version-bumped.sh" | ||
|
|
||
| # If the helper is missing (e.g. partial clone), don't pretend we gated. | ||
| if [ ! -x "$script" ]; then | ||
| exit 0 | ||
| fi | ||
|
|
||
| # `&& rc=0 || rc=$?` captures the exit code regardless of success/failure. | ||
| # After `if cmd; then ... fi`, $? reflects the if-fi structural exit (0), | ||
| # not the failed test's exit code — so we cannot use the if-fi form here. | ||
| err_file="/tmp/version-bumped.$$.err" | ||
| VERSION_BUMPED_QUIET=1 "$script" 2>"$err_file" && rc=0 || rc=$? | ||
| if [ "$rc" -eq 0 ]; then | ||
| rm -f "$err_file" | ||
| exit 0 | ||
| fi | ||
| err_payload=$(cat "$err_file" 2>/dev/null || true) | ||
| rm -f "$err_file" | ||
|
|
||
| # Layer-1 returned a configuration error — do not block, surface the note. | ||
| if [ "$rc" -ne 1 ]; then | ||
| printf '%s\n' "$err_payload" >&2 | ||
| exit 0 | ||
| fi | ||
|
|
||
| cat >&2 <<EOF | ||
| './gradlew' blocked: branch differs from the base ref but | ||
| version.gradle.kts is not bumped. Publishing would overwrite the Maven | ||
| Local artifact at the base version, which integration tests in consumer | ||
| repos may rely on. | ||
|
|
||
| Run /version-bumped to auto-recover (it invokes /bump-version and re-runs | ||
| the check), or /bump-version directly. | ||
|
|
||
| Underlying check (.agents/skills/version-bumped/scripts/version-bumped.sh) reported: | ||
| $err_payload | ||
| EOF | ||
| exit 2 | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| #!/usr/bin/env bash | ||
| # | ||
| # PostToolUse hook: enforce the source-code formatting rules from | ||
| # .agents/coding-guidelines.md after Edit/Write/MultiEdit: | ||
| # - strip trailing whitespace | ||
| # - replace 2+ consecutive blank lines with a single blank line | ||
| # | ||
| # Input: hook JSON on stdin. Claude Code passes `tool_input.file_path`; | ||
| # Codex `apply_patch` passes the patch text in `tool_input.command`. | ||
| # Exit: 0 always (post-tool-use; never block). | ||
| # | ||
| set -eu | ||
|
|
||
| input=$(cat) | ||
| file=$(printf '%s' "$input" | jq -r '.tool_input.file_path // empty') | ||
| command=$(printf '%s' "$input" | jq -r '.tool_input.command // empty') | ||
|
alexander-yevsyukov marked this conversation as resolved.
|
||
|
|
||
| sanitize_file() { | ||
| local path="$1" | ||
|
|
||
| [ -z "$path" ] && return 0 | ||
| [ ! -f "$path" ] && return 0 | ||
|
|
||
| case "$path" in | ||
| *.java|*.kt|*.kts) ;; | ||
| *) return 0 ;; | ||
| esac | ||
|
|
||
| tmp=$(mktemp) | ||
| awk ' | ||
| { sub(/[ \t]+$/, "") } | ||
| /^$/ { blank++; if (blank > 1) next; print; next } | ||
| { blank = 0; print } | ||
|
alexander-yevsyukov marked this conversation as resolved.
|
||
| ' "$path" > "$tmp" && mv "$tmp" "$path" | ||
| } | ||
|
|
||
| if [ -n "$file" ]; then | ||
| sanitize_file "$file" | ||
| exit 0 | ||
| fi | ||
|
|
||
| printf '%s\n' "$command" \ | ||
| | sed -nE 's/^\*\*\* (Add|Update) File: (.*)$/\2/p' \ | ||
| | sort -u \ | ||
| | while IFS= read -r path; do | ||
| sanitize_file "$path" | ||
| done | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.